From 89015df636aafece490c6831df385d284270b57a Mon Sep 17 00:00:00 2001 From: Hong Minhee Date: Fri, 2 Aug 2019 15:34:24 +0900 Subject: [PATCH] Revert prev workaround for LiteDB and make it flush instead It turns out that LiteDB's data corruption (https://github.com/mbdavid/LiteDB/issues/1268) seems to happen due to sudden termination of program. So the workaround made in the previous patch (https://github.com/planetarium/libplanet/pull/386) was reverted for the most part, and a new option named `flush` was added to `LiteDBStore()` constructor. --- CHANGES.md | 7 ++++-- Libplanet/Store/LiteDBStore.cs | 43 ++++++++++------------------------ 2 files changed, 18 insertions(+), 32 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index bd0c78bb5e..01eb86e760 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -12,6 +12,8 @@ To be released. - `StoreExtension.LookupStateReference()` method became to return `Tuple, long>` which is a nullable tuple of `Block.Hash` and `Block.Index`. [[#350]] + - `LiteDBStore()` constructor became to have a new option named `flush` and turned on by default. + [[#387], [LiteDB #1268]] ### Added interfaces @@ -45,7 +47,7 @@ To be released. - Fixed a bug where the `LiteDBStore.IterateStagedTransactionIds()` returns duplicated transaction ids. [[#366]] - Fixed a `LiteDBStore` bug that blocks or transactions had got corrupted - sometimes. [[#386], [LiteDB #1268]] + sometimes. [[#386], [#387], [LiteDB #1268]] [#343]: https://github.com/planetarium/libplanet/pull/343 [#350]: https://github.com/planetarium/libplanet/pull/350 @@ -54,7 +56,8 @@ To be released. [#366]: https://github.com/planetarium/libplanet/pull/366 [#384]: https://github.com/planetarium/libplanet/issues/384 [#385]: https://github.com/planetarium/libplanet/pull/385 -[#386]: https://github.com/planetarium/libplanet/pull/366 +[#386]: https://github.com/planetarium/libplanet/pull/386 +[#387]: https://github.com/planetarium/libplanet/pull/387 [LiteDB #1268]: https://github.com/mbdavid/LiteDB/issues/1268 diff --git a/Libplanet/Store/LiteDBStore.cs b/Libplanet/Store/LiteDBStore.cs index 3bdb9f0415..1cfa537c52 100644 --- a/Libplanet/Store/LiteDBStore.cs +++ b/Libplanet/Store/LiteDBStore.cs @@ -40,7 +40,14 @@ public class LiteDBStore : BaseStore, IDisposable /// Enables or disables double write check to ensure durability. /// /// Max number of pages in the cache. - public LiteDBStore(string path, bool journal = true, int cacheSize = 50000) + /// Writes data direct to disk avoiding OS cache. Turned on by default. + /// + public LiteDBStore( + string path, + bool journal = true, + int cacheSize = 50000, + bool flush = true + ) { if (path is null) { @@ -52,6 +59,7 @@ public LiteDBStore(string path, bool journal = true, int cacheSize = 50000) Filename = path, Journal = journal, CacheSize = cacheSize, + Flush = flush, }; if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) && @@ -298,7 +306,8 @@ public override void SetBlockStates( { var formatter = new BinaryFormatter(); formatter.Serialize(stream, states); - UploadFile( + stream.Seek(0, SeekOrigin.Begin); + _db.FileStorage.Upload( BlockStateFileId(blockHash), ByteUtil.Hex(blockHash.ToByteArray()), stream @@ -558,38 +567,12 @@ IEnumerable transactions .Where(tx => tx != null); } - // As LiteDB's file storage seems unstable, we need to repeat trying to save a file - // until we ensure it's actually saved. - // https://github.com/mbdavid/LiteDB/issues/1268 - private void UploadFile(string fileId, string filename, Stream stream) - { - bool IsFiledUploaded() - { - if (_db.FileStorage.FindById(fileId) is LiteFileInfo file && file.Length > 0) - { - using (LiteFileStream f = file.OpenRead()) - { - var buffer = new byte[1]; - return f.Read(buffer, 0, 1) > 0; - } - } - - return false; - } - - do - { - stream.Seek(0, SeekOrigin.Begin); - _db.FileStorage.Upload(fileId, filename, stream); - } - while (!IsFiledUploaded()); - } - private void UploadFile(string fileId, string filename, byte[] bytes) { using (var stream = new MemoryStream(bytes)) { - UploadFile(fileId, filename, stream); + stream.Seek(0, SeekOrigin.Begin); + _db.FileStorage.Upload(fileId, filename, stream); } }