Beispiel #1
0
        public void FasterLogShiftTailStressTest()
        {
            // Get an excruciatingly slow storage device to maximize chance of clogging the flush pipeline
            device = new LocalMemoryDevice(1L << 28, 1 << 28, 2, sector_size: 512, latencyMs: 50, fileName: "stress.log");
            var logSettings = new FasterLogSettings {
                LogDevice = device, LogChecksum = LogChecksumType.None, LogCommitManager = manager, SegmentSizeBits = 28
            };

            log = new FasterLog(logSettings);

            byte[] entry = new byte[entryLength];
            for (int i = 0; i < entryLength; i++)
            {
                entry[i] = (byte)i;
            }

            for (int i = 0; i < 5 * numEntries; i++)
            {
                log.Enqueue(entry);
            }

            // for comparison, insert some entries without any commit records
            var referenceTailLength = log.TailAddress;

            var enqueueDone   = new ManualResetEventSlim();
            var commitThreads = new List <Thread>();

            // Make sure to spin up many commit threads to expose lots of interleavings
            for (var i = 0; i < 2 * Math.Max(1, Environment.ProcessorCount - 1); i++)
            {
                commitThreads.Add(new Thread(() =>
                {
                    // Otherwise, absolutely clog the commit pipeline
                    while (!enqueueDone.IsSet)
                    {
                        log.Commit();
                    }
                }));
            }

            foreach (var t in commitThreads)
            {
                t.Start();
            }
            for (int i = 0; i < 5 * numEntries; i++)
            {
                log.Enqueue(entry);
            }
            enqueueDone.Set();

            foreach (var t in commitThreads)
            {
                t.Join();
            }

            // We expect the test to finish and not get stuck somewhere

            // Ensure clean shutdown
            log.Commit(true);
        }
Beispiel #2
0
        public void ScanConsumerTest([Values] TestUtils.DeviceType deviceType)
        {
            // Create log and device here (not in setup) because using DeviceType Enum which can't be used in Setup
            string filename = path + "LogScanDefault" + deviceType.ToString() + ".log";

            device = TestUtils.CreateTestDevice(deviceType, filename);
            log    = new FasterLog(new FasterLogSettings {
                LogDevice = device, SegmentSizeBits = 22, LogCommitDir = path
            });
            PopulateLog(log);

            // Basic default scan from start to end
            // Indirectly used in other tests, but good to have the basic test here for completeness

            // Read the log - Look for the flag so know each entry is unique
            var consumer = new TestConsumer();

            using (var iter = log.Scan(0, 100_000_000))
            {
                while (iter.TryConsumeNext(consumer))
                {
                }
            }

            // Make sure expected length is same as current - also makes sure that data verification was not skipped
            Assert.AreEqual(entryLength, consumer.currentEntry);
        }
Beispiel #3
0
        static async Task Main()
        {
            var path = Path.GetTempPath() + "FasterLogPubSub\\";

            var device = Devices.CreateLogDevice(path + "mylog");

            var log = new FasterLog(new FasterLogSettings {
                LogDevice = device, MemorySizeBits = 11, PageSizeBits = 9, MutableFraction = 0.5, SegmentSizeBits = 9
            });

            using var cts = new CancellationTokenSource();

            var producer = ProducerAsync(log, cts.Token);
            var commiter = CommiterAsync(log, cts.Token);
            var consumer = ConsumerAsync(log, cts.Token);

            Console.CancelKeyPress += (o, eventArgs) =>
            {
                Console.WriteLine("Cancelling program...");
                eventArgs.Cancel = true;
                cts.Cancel();
            };

            await producer;
            await consumer;
            await commiter;

            Console.WriteLine("Finished.");

            log.Dispose();
            try { new DirectoryInfo(path).Delete(true); } catch { }
        }
Beispiel #4
0
        public static void Main()
        {
            commitPath = "FasterLogStress/";

            // Clean up log files from previous test runs in case they weren't cleaned up
            // We loop to ensure clean-up as deleteOnClose does not always work for MLSD
            while (Directory.Exists(commitPath))
            {
                Directory.Delete(commitPath, true);
            }

            // Create devices \ log for test
            device = new ManagedLocalStorageDevice(commitPath + "ManagedLocalStore.log", deleteOnClose: true);
            log    = new FasterLog(new FasterLogSettings {
                LogDevice = device, PageSizeBits = 12, MemorySizeBits = 14
            });

            ManagedLocalStoreBasicTest();

            log.Dispose();
            device.Dispose();

            // Clean up log files
            if (Directory.Exists(commitPath))
            {
                Directory.Delete(commitPath, true);
            }
        }
Beispiel #5
0
        private void FasterLogTest1(LogChecksumType logChecksum, IDevice device, ILogCommitManager logCommitManager)
        {
            log = new FasterLog(new FasterLogSettings {
                PageSizeBits = 20, SegmentSizeBits = 20, LogDevice = device, LogChecksum = logChecksum, LogCommitManager = logCommitManager
            });

            byte[] entry = new byte[entryLength];
            for (int i = 0; i < entryLength; i++)
            {
                entry[i] = (byte)i;
            }

            for (int i = 0; i < numEntries; i++)
            {
                log.Enqueue(entry);
            }
            log.Commit(true);

            using (var iter = log.Scan(0, long.MaxValue))
            {
                int count = 0;
                while (iter.GetNext(out byte[] result, out int length, out long currentAddress))
                {
                    count++;
                    Assert.IsTrue(result.SequenceEqual(entry));
                    if (count % 100 == 0)
                    {
                        log.TruncateUntil(iter.NextAddress);
                    }
                }
                Assert.IsTrue(count == numEntries);
            }

            log.Dispose();
        }
Beispiel #6
0
        static async Task Main()
        {
            var device = Devices.CreateLogDevice(path + "mylog");

            var log = new FasterLog(new FasterLogSettings {
                LogDevice = device, MemorySizeBits = 11, PageSizeBits = 9, MutableFraction = 0.5, SegmentSizeBits = 9
            });

            using var cts = new CancellationTokenSource();

            var producer = ProducerAsync(log, cts.Token);
            var commiter = CommitterAsync(log, cts.Token);

            // Consumer on SAME FasterLog instance
            var consumer = ConsumerAsync(log, true, cts.Token);

            // Uncomment below to run consumer on SEPARATE read-only FasterLog instance
            // var consumer = SeparateConsumerAsync(cts.Token);

            Console.CancelKeyPress += (o, eventArgs) =>
            {
                Console.WriteLine("Cancelling program...");
                eventArgs.Cancel = true;
                cts.Cancel();
            };

            await producer;
            await consumer;
            await commiter;

            Console.WriteLine("Finished.");

            log.Dispose();
            try { new DirectoryInfo(path).Delete(true); } catch { }
        }
Beispiel #7
0
        static async Task Main()
        {
            var device = Devices.CreateLogDevice($"c:\\logs\\mylog");

            var log = new FasterLog(new FasterLogSettings {
                LogDevice = device, MemorySizeBits = 11, PageSizeBits = 9, MutableFraction = 0.5, SegmentSizeBits = 9
            });

            using var cts = new CancellationTokenSource();

            var producer = ProducerAsync(log, cts.Token);
            var commiter = CommiterAsync(log, cts.Token);
            var consumer = ConsumerAsync(log, cts.Token);

            Console.CancelKeyPress += (o, eventArgs) =>
            {
                Console.WriteLine("Cancelling program...");
                eventArgs.Cancel = true;
                cts.Cancel();
            };

            await producer;
            await consumer;
            await commiter;

            Console.WriteLine("Finished.");
        }
        public async Task FasterLogResumePersistedReaderSpec([Values] LogChecksumType logChecksum)
        {
            var    input1     = new byte[] { 0, 1, 2, 3 };
            var    input2     = new byte[] { 4, 5, 6, 7, 8, 9, 10 };
            var    input3     = new byte[] { 11, 12 };
            string readerName = "abc";

            using (var l = new FasterLog(new FasterLogSettings {
                LogDevice = device, PageSizeBits = 16, MemorySizeBits = 16, LogChecksum = logChecksum, LogCommitFile = commitPath
            }))
            {
                await l.EnqueueAsync(input1);

                await l.EnqueueAsync(input2);

                await l.EnqueueAsync(input3);

                await l.CommitAsync();

                using var originalIterator = l.Scan(0, long.MaxValue, readerName);
                Assert.IsTrue(originalIterator.GetNext(out _, out _, out _, out long recoveryAddress));
                originalIterator.CompleteUntil(recoveryAddress);
                Assert.IsTrue(originalIterator.GetNext(out _, out _, out _, out _));  // move the reader ahead
                await l.CommitAsync();
            }

            using (var l = new FasterLog(new FasterLogSettings {
                LogDevice = device, PageSizeBits = 16, MemorySizeBits = 16, LogChecksum = logChecksum, LogCommitFile = commitPath
            }))
            {
                using var recoveredIterator = l.Scan(0, long.MaxValue, readerName);
                Assert.IsTrue(recoveredIterator.GetNext(out byte[] outBuf, out _, out _, out _));
                Assert.True(input2.SequenceEqual(outBuf));  // we should have read in input2, not input1 or input3
            }
        }
Beispiel #9
0
        public void TestDisposeReleasesFileLocksWithCompletedCommit([Values] TestUtils.DeviceType deviceType)
        {
            string path     = TestUtils.MethodTestDir + "/";
            string filename = path + "TestDisposeRelease" + deviceType.ToString() + ".log";

            DirectoryInfo di        = Directory.CreateDirectory(path);
            IDevice       device    = TestUtils.CreateTestDevice(deviceType, filename);
            FasterLog     fasterLog = new FasterLog(new FasterLogSettings {
                LogDevice = device, SegmentSizeBits = 22, LogCommitDir = path, LogChecksum = LogChecksumType.PerEntry
            });

            Assert.IsTrue(fasterLog.TryEnqueue(new byte[100], out _));

            fasterLog.Commit(spinWait: true);
            fasterLog.Dispose();
            device.Dispose();
            while (true)
            {
                try
                {
                    di.Delete(recursive: true);
                    break;
                }
                catch { }
            }
        }
Beispiel #10
0
        public void FasterLogTest1([Values] LogChecksumType logChecksum)
        {
            log = new FasterLog(new FasterLogSettings {
                LogDevice = device, LogChecksum = logChecksum
            });

            byte[] entry = new byte[entryLength];
            for (int i = 0; i < entryLength; i++)
            {
                entry[i] = (byte)i;
            }

            for (int i = 0; i < numEntries; i++)
            {
                log.Enqueue(entry);
            }
            log.Commit(true);

            using (var iter = log.Scan(0, long.MaxValue))
            {
                int count = 0;
                while (iter.GetNext(out byte[] result, out int length))
                {
                    count++;
                    Assert.IsTrue(result.SequenceEqual(entry));
                    if (count % 100 == 0)
                    {
                        log.TruncateUntil(iter.CurrentAddress);
                    }
                }
                Assert.IsTrue(count == numEntries);
            }

            log.Dispose();
        }
Beispiel #11
0
        public void PopulateLog(FasterLog log)
        {
            //****** Populate log for Basic data for tests
            // Set Default entry data
            for (int i = 0; i < entryLength; i++)
            {
                entry[i] = (byte)i;
            }

            // Enqueue but set each Entry in a way that can differentiate between entries
            for (int i = 0; i < numEntries; i++)
            {
                // Flag one part of entry data that corresponds to index
                if (i < entryLength)
                {
                    entry[i] = (byte)entryFlag;
                }

                // puts back the previous entry value
                if ((i > 0) && (i < entryLength))
                {
                    entry[i - 1] = (byte)(i - 1);
                }

                // Add to FasterLog
                log.Enqueue(entry);
            }

            // Commit to the log
            log.Commit(true);
        }
Beispiel #12
0
        public void PopulateUncommittedLog(FasterLog logUncommitted)
        {
            //****** Populate uncommitted log / device for ScanUncommittedTest
            // Set Default entry data
            for (int j = 0; j < entryLength; j++)
            {
                entry[j] = (byte)j;
            }

            // Enqueue but set each Entry in a way that can differentiate between entries
            for (int j = 0; j < numEntries; j++)
            {
                // Flag one part of entry data that corresponds to index
                if (j < entryLength)
                {
                    entry[j] = (byte)entryFlag;
                }

                // puts back the previous entry value
                if ((j > 0) && (j < entryLength))
                {
                    entry[j - 1] = (byte)(j - 1);
                }

                // Add to FasterLog
                logUncommitted.Enqueue(entry);
            }

            // refresh uncommitted so can see it when scan - do NOT commit though
            logUncommitted.RefreshUncommitted(true);
        }
Beispiel #13
0
        public void ScanWithoutRecoverTest([Values] TestUtils.DeviceType deviceType)
        {
            // You may also force an iterator to start at the specified begin address, i.e., without recovering: recover parameter = false

            // Create log and device here (not in setup) because using DeviceType Enum which can't be used in Setup
            string filename = path + "LogScanWithoutRecover" + deviceType.ToString() + ".log";

            device = TestUtils.CreateTestDevice(deviceType, filename);
            log    = new FasterLog(new FasterLogSettings {
                LogDevice = device, SegmentSizeBits = 22, LogCommitDir = path
            });
            PopulateLog(log);

            // Read the log
            int currentEntry = 9;   // since starting at specified address of 1000, need to set current entry as 9 so verification starts at proper spot

            using (var iter = log.Scan(1000, 100_000_000, recover: false))
            {
                while (iter.GetNext(out byte[] result, out _, out _))
                {
                    if (currentEntry < entryLength)
                    {
                        // Span Batch only added first entry several times so have separate verification
                        Assert.AreEqual((byte)entryFlag, result[currentEntry]);
                        currentEntry++;
                    }
                }
            }

            // Make sure expected length is same as current - also makes sure that data verification was not skipped
            Assert.AreEqual(entryLength, currentEntry);
        }
Beispiel #14
0
        public void ScanUncommittedTest([Values] TestUtils.DeviceType deviceType)
        {
            // Create log and device here (not in setup) because using DeviceType Enum which can't be used in Setup
            string filename = path + "LogScan" + deviceType.ToString() + ".log";

            device = TestUtils.CreateTestDevice(deviceType, filename);
            log    = new FasterLog(new FasterLogSettings {
                LogDevice = device, SegmentSizeBits = 22, LogCommitDir = path
            });
            PopulateUncommittedLog(log);

            // Setting scanUnCommitted to true is actual test here.
            // Read the log - Look for the flag so know each entry is unique and still reads uncommitted
            int currentEntry = 0;

            using (var iter = log.Scan(0, 100_000_000, scanUncommitted: true))
            {
                while (iter.GetNext(out byte[] result, out _, out _))
                {
                    if (currentEntry < entryLength)
                    {
                        // Span Batch only added first entry several times so have separate verification
                        Assert.AreEqual((byte)entryFlag, result[currentEntry]);
                        currentEntry++;
                    }
                }
            }

            // Make sure expected length is same as current - also makes sure that data verification was not skipped
            Assert.AreEqual(entryLength, currentEntry);
        }
Beispiel #15
0
        public void ScanByNameTest([Values] TestUtils.DeviceType deviceType)
        {
            //You can persist iterators(or more precisely, their CompletedUntilAddress) as part of a commit by simply naming them during their creation.

            // Create log and device here (not in setup) because using DeviceType Enum which can't be used in Setup
            string filename = path + "LogScanByName" + deviceType.ToString() + ".log";

            device = TestUtils.CreateTestDevice(deviceType, filename);
            log    = new FasterLog(new FasterLogSettings {
                LogDevice = device, SegmentSizeBits = 22, LogCommitDir = path
            });
            PopulateLog(log);

            // Read the log - Look for the flag so know each entry is unique
            int currentEntry = 0;

            using (var iter = log.Scan(0, 100_000_000, name: "TestScan", recover: true))
            {
                while (iter.GetNext(out byte[] result, out _, out _))
                {
                    if (currentEntry < entryLength)
                    {
                        // Span Batch only added first entry several times so have separate verification
                        Assert.AreEqual((byte)entryFlag, result[currentEntry]);
                        currentEntry++;
                    }
                }
            }

            // Make sure expected length is same as current - also makes sure that data verification was not skipped
            Assert.AreEqual(entryLength, currentEntry);
        }
Beispiel #16
0
        public void BasicHighLatencyDeviceTest()
        {
            TestUtils.DeleteDirectory(TestUtils.MethodTestDir, wait: true);

            // Create devices \ log for test for in memory device
            using LocalMemoryDevice device = new LocalMemoryDevice(1L << 28, 1L << 25, 2, latencyMs: 20);
            using FasterLog LocalMemorylog = new FasterLog(new FasterLogSettings { LogDevice = device, PageSizeBits = 80, MemorySizeBits = 20, GetMemory = null, SegmentSizeBits = 80, MutableFraction = 0.2, LogCommitManager = null });

            int entryLength = 10;

            // Set Default entry data
            for (int i = 0; i < entryLength; i++)
            {
                entry[i] = (byte)i;
                LocalMemorylog.Enqueue(entry);
            }

            // Commit to the log
            LocalMemorylog.Commit(true);

            // Read the log just to verify was actually committed
            int currentEntry = 0;

            using (var iter = LocalMemorylog.Scan(0, 100_000_000))
            {
                while (iter.GetNext(out byte[] result, out _, out _))
                {
                    Assert.IsTrue(result[currentEntry] == currentEntry, "Fail - Result[" + currentEntry.ToString() + "]: is not same as " + currentEntry.ToString());
                    currentEntry++;
                }
            }
        }
Beispiel #17
0
        public void FasterLogTest6([Values] LogChecksumType logChecksum)
        {
            log = new FasterLog(new FasterLogSettings {
                LogDevice = device, MemorySizeBits = 20, PageSizeBits = 14, LogChecksum = logChecksum, LogCommitManager = manager
            });
            byte[] data1 = new byte[1000];
            for (int i = 0; i < 100; i++)
            {
                data1[i] = (byte)i;
            }

            for (int i = 0; i < 100; i++)
            {
                log.Enqueue(data1);
            }
            log.RefreshUncommitted();
            Assert.IsTrue(log.SafeTailAddress == log.TailAddress);

            Assert.IsTrue(log.CommittedUntilAddress < log.SafeTailAddress);

            using (var iter = log.Scan(0, long.MaxValue, scanUncommitted: true))
            {
                while (iter.GetNext(out _, out _, out _))
                {
                    log.TruncateUntil(iter.NextAddress);
                }
                Assert.IsTrue(iter.NextAddress == log.SafeTailAddress);
                log.Enqueue(data1);
                Assert.IsFalse(iter.GetNext(out _, out _, out _));
                log.RefreshUncommitted();
                Assert.IsTrue(iter.GetNext(out _, out _, out _));
            }
            log.Dispose();
        }
Beispiel #18
0
 static void LogWriter(FasterLog log, byte[] entry)
 {
     // Enter in some entries then wait on this separate thread
     log.Enqueue(entry);
     log.Enqueue(entry);
     log.Enqueue(entry);
     log.WaitForCommit(log.TailAddress);
 }
Beispiel #19
0
        private FasterOps()
        {
            string devicePath = Startup.Configuration[nameof(MinMQConfiguration.FasterDevice)];

            device = Devices.CreateLogDevice(devicePath);
            logger = new FasterLog(new FasterLogSettings {
                LogDevice = device,
            });
        }
Beispiel #20
0
        //**** Helper Functions - based off of FasterLogPubSub sample ***
        static async Task CommitterAsync(FasterLog log, CancellationToken cancellationToken)
        {
            while (!cancellationToken.IsCancellationRequested)
            {
                await Task.Delay(TimeSpan.FromMilliseconds(commitPeriodMs), cancellationToken);

                await log.CommitAsync(token : cancellationToken);
            }
        }
Beispiel #21
0
        public async ValueTask FlakyLogTestCleanFailure([Values] bool isAsync)
        {
            var errorOptions = new ErrorSimulationOptions
            {
                readTransientErrorRate  = 0,
                readPermanentErrorRate  = 0,
                writeTransientErrorRate = 0,
                writePermanentErrorRate = 0.1,
            };

            device = new SimulatedFlakyDevice(Devices.CreateLogDevice(path + "fasterlog.log", deleteOnClose: true),
                                              errorOptions);
            var logSettings = new FasterLogSettings
            {
                LogDevice = device, LogChecksum = LogChecksumType.PerEntry, LogCommitManager = manager
            };

            log = new FasterLog(logSettings);

            byte[] entry = new byte[entryLength];
            for (int i = 0; i < entryLength; i++)
            {
                entry[i] = (byte)i;
            }

            try
            {
                // Ensure we execute long enough to trigger errors
                for (int j = 0; j < 100; j++)
                {
                    for (int i = 0; i < numEntries; i++)
                    {
                        log.Enqueue(entry);
                    }

                    if (isAsync)
                    {
                        await log.CommitAsync();
                    }
                    else
                    {
                        log.Commit();
                    }
                }
            }
            catch (CommitFailureException e)
            {
                var errorRangeStart = e.LinkedCommitInfo.CommitInfo.FromAddress;
                Assert.LessOrEqual(log.CommittedUntilAddress, errorRangeStart);
                Assert.LessOrEqual(log.FlushedUntilAddress, errorRangeStart);
                return;
            }

            // Should not ignore failures
            Assert.Fail();
        }
Beispiel #22
0
        static async Task BeginRecoverReadOnlyLoop(FasterLog log, CancellationToken cancellationToken)
        {
            while (!cancellationToken.IsCancellationRequested)
            {
                // Delay for a while before checking again.
                await Task.Delay(TimeSpan.FromMilliseconds(restorePeriodMs), cancellationToken);

                await log.RecoverReadOnlyAsync(cancellationToken);
            }
        }
Beispiel #23
0
        public async Task InitializeAsync()
        {
            if (!System.IO.Directory.Exists(this._BaseFolder))
            {
                System.IO.Directory.CreateDirectory(this._BaseFolder);
            }
            FasterLogSettings logSettings = new FasterLogSettings();

            this._Log = await FasterLog.CreateAsync(logSettings);
        }
Beispiel #24
0
        public void TearDown()
        {
            log?.Dispose();
            log = null;
            device?.Dispose();
            device = null;

            // Clean up log files
            TestUtils.DeleteDirectory(path, wait: true);
        }
Beispiel #25
0
        public void TearDown()
        {
            log?.Dispose();
            log = null;
            device?.Dispose();
            device = null;

            // Clean up log files
            TestUtils.DeleteDirectory(TestUtils.MethodTestDir);
        }
Beispiel #26
0
        /// <summary>
        /// Main program entry point
        /// </summary>
        static void Main()
        {
            bool sync   = true;
            var  device = Devices.CreateLogDevice("D:\\logs\\hlog.log");

            log = new FasterLog(new FasterLogSettings {
                LogDevice = device
            });

            // Populate entry being inserted
            for (int i = 0; i < entryLength; i++)
            {
                staticEntry[i] = (byte)i;
            }

            if (sync)
            {
                // Log writer thread: create as many as needed
                new Thread(new ThreadStart(LogWriterThread)).Start();

                // Threads for scan, reporting, commit
                new Thread(new ThreadStart(ScanThread)).Start();
                new Thread(new ThreadStart(ReportThread)).Start();
                new Thread(new ThreadStart(CommitThread)).Start();
            }
            else
            {
                // Async version of demo: expect lower performance
                // particularly for small payload sizes

                const int NumParallelTasks = 10_000;
                ThreadPool.SetMinThreads(2 * Environment.ProcessorCount, 2 * Environment.ProcessorCount);
                TaskScheduler.UnobservedTaskException += (object sender, UnobservedTaskExceptionEventArgs e) =>
                {
                    Console.WriteLine($"Unobserved task exception: {e.Exception}");
                    e.SetObserved();
                };

                Task[] tasks = new Task[NumParallelTasks];
                for (int i = 0; i < NumParallelTasks; i++)
                {
                    int local = i;
                    tasks[i] = Task.Run(() => AsyncLogWriter(local));
                }

                var scan = Task.Run(() => AsyncScan());

                // Threads for reporting, commit
                new Thread(new ThreadStart(ReportThread)).Start();
                new Thread(new ThreadStart(CommitThread)).Start();

                Task.WaitAll(tasks);
                Task.WaitAll(scan);
            }
        }
        public FasterEventEntitySaver()
        {
            var filename = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,
                                        "testData.mydata");
            var device = Devices.CreateLogDevice(filename);

            _log = new FasterLog(new FasterLogSettings
            {
                LogDevice = device,
            });
        }
Beispiel #28
0
        static async Task Main()
        {
            // This is two samples in one, enumerating over the same FasterLog instance that does commits, or over a separate
            // FasterLog that opens the log file read-only and continuously catches up with the first intance's commits.
            const bool sameInstance = true;

#pragma warning disable CS0162 // Unreachable code detected
            if (!sameInstance)
            {
                // Because the SAME-instance iterator illustrates truncating the log, the SEPARATE-instance may encounter EOF
                // issues if it is run after that truncation without cleaning up the directory first.
                // In all other cases, the sample should run without needing to clean up the directory.
                //if (Directory.Exists(path)) Directory.Delete(path, true);
            }

            var device = Devices.CreateLogDevice(path + "mylog");
            var log    = new FasterLog(new FasterLogSettings {
                LogDevice = device, MemorySizeBits = 11, PageSizeBits = 9, MutableFraction = 0.5, SegmentSizeBits = 9
            });
            using var cts = new CancellationTokenSource();

            var producer  = ProducerAsync(log, cts.Token);
            var committer = CommitterAsync(log, cts.Token);

            Task consumer;
            if (sameInstance)
            {
                // Consumer on SAME FasterLog instance
                consumer = ConsumerAsync(log, true, cts.Token);
            }
            else
            {
                // Consumer on SEPARATE read-only FasterLog instance
                consumer = SeparateConsumerAsync(cts.Token);
            }
#pragma warning restore CS0162 // Unreachable code detected

            Console.CancelKeyPress += (o, eventArgs) =>
            {
                Console.WriteLine("Cancelling program...");
                eventArgs.Cancel = true;
                cts.Cancel();
            };

            await producer;
            await consumer;
            await committer;

            Console.WriteLine("Finished.");

            log.Dispose();
            device.Dispose();
            try { new DirectoryInfo(path).Delete(true); } catch { }
        }
Beispiel #29
0
        static async Task CommiterAsync(FasterLog log, CancellationToken cancellationToken)
        {
            while (!cancellationToken.IsCancellationRequested)
            {
                await Task.Delay(TimeSpan.FromMilliseconds(5000), cancellationToken);

                Console.WriteLine("Committing...");

                await log.CommitAsync();
            }
        }
Beispiel #30
0
        public async Task FasterLogResumePersistedReader2([Values] LogChecksumType logChecksum, [Values] bool overwriteLogCommits, [Values] bool removeOutdated)
        {
            var    input1     = new byte[] { 0, 1, 2, 3 };
            var    input2     = new byte[] { 4, 5, 6, 7, 8, 9, 10 };
            var    input3     = new byte[] { 11, 12 };
            string readerName = "abc";

            using (var logCommitManager = new DeviceLogCommitCheckpointManager(new LocalStorageNamedDeviceFactory(), new DefaultCheckpointNamingScheme(commitPath), overwriteLogCommits, removeOutdated))
            {
                long originalCompleted;

                using (var l = new FasterLog(new FasterLogSettings {
                    LogDevice = device, PageSizeBits = 16, MemorySizeBits = 16, LogChecksum = logChecksum, LogCommitManager = logCommitManager
                }))
                {
                    await l.EnqueueAsync(input1);

                    await l.CommitAsync();

                    await l.EnqueueAsync(input2);

                    await l.CommitAsync();

                    await l.EnqueueAsync(input3);

                    await l.CommitAsync();

                    using (var originalIterator = l.Scan(0, long.MaxValue, readerName))
                    {
                        originalIterator.GetNext(out _, out _, out _, out long recoveryAddress);
                        originalIterator.CompleteUntil(recoveryAddress);
                        originalIterator.GetNext(out _, out _, out _, out _);  // move the reader ahead
                        await l.CommitAsync();

                        originalCompleted = originalIterator.CompletedUntilAddress;
                    }
                }

                using (var l = new FasterLog(new FasterLogSettings {
                    LogDevice = device, PageSizeBits = 16, MemorySizeBits = 16, LogChecksum = logChecksum, LogCommitManager = logCommitManager
                }))
                {
                    using (var recoveredIterator = l.Scan(0, long.MaxValue, readerName))
                    {
                        recoveredIterator.GetNext(out byte[] outBuf, out _, out _, out _);

                        // we should have read in input2, not input1 or input3
                        Assert.True(input2.SequenceEqual(outBuf), $"Original: {input2[0]}, Recovered: {outBuf[0]}, Original: {originalCompleted}, Recovered: {recoveredIterator.CompletedUntilAddress}");

                        // TestContext.Progress.WriteLine($"Original: {originalCompleted}, Recovered: {recoveredIterator.CompletedUntilAddress}");
                    }
                }
            }
        }