public void Test() { const int sleepSeconds = 1; var log = new List <string>(); var innerRenderer = new AnonymousRenderer <DumbAction>() { BlockRenderer = (Block <DumbAction> oldTip, Block <DumbAction> newTip) => { Thread.Sleep(sleepSeconds * 1000); log.Add($"Block({oldTip.Index}, {newTip.Index})"); }, ReorgRenderer = ( Block <DumbAction> oldTip, Block <DumbAction> newTip, Block <DumbAction> branchpoint ) => { Thread.Sleep(sleepSeconds * 1000); log.Add($"Reorg({oldTip.Index}, {newTip.Index}, {branchpoint.Index})"); }, ReorgEndRenderer = ( Block <DumbAction> oldTip, Block <DumbAction> newTip, Block <DumbAction> branchpoint ) => { Thread.Sleep(sleepSeconds * 1000); log.Add($"ReorgEnd({oldTip.Index}, {newTip.Index}, {branchpoint.Index})"); }, }; using (var renderer = new NonblockRenderer <DumbAction>( innerRenderer, 3, NonblockRenderer <DumbAction> .FullMode.DropNewest)) { DateTimeOffset start = DateTimeOffset.UtcNow; renderer.RenderReorg(_blockA, _blockB, _genesis); Assert.Empty(log); renderer.RenderBlock(_blockA, _blockB); Assert.Empty(log); renderer.RenderReorgEnd(_blockA, _blockB, _genesis); Assert.Empty(log); DateTimeOffset end = DateTimeOffset.UtcNow; TimeSpan elapsed = end - start; Assert.True( elapsed < TimeSpan.FromSeconds(3 * sleepSeconds), $"Elapsed more than {3 * sleepSeconds} seconds ({elapsed}); seems blocking." ); } Assert.Equal( new[] { "Reorg(1, 1, 0)", "Block(1, 1)", "ReorgEnd(1, 1, 0)", }, log ); }
public void StatingWorkerThreadOnlyOnce(int parallel) { // This is a regression test for the follwing bug: // https://github.com/planetarium/libplanet/issues/1772 var renderer = new NonblockRenderer <DumbAction>( new AnonymousRenderer <DumbAction>(), 25, NonblockRenderer <DumbAction> .FullMode.DropNewest ); Thread[] threads = new Thread[parallel]; Exception[] errors = new Exception[threads.Length]; using (renderer) { for (int i = 0; i < threads.Length; i++) { // Declare a new variable for each iteration to avoid being captured by closure: int threadNo = i; threads[threadNo] = new Thread(() => { try { renderer.RenderBlock(_blockA, _blockB); } catch (Exception e) { errors[threadNo] = e; } }); } for (int i = 0; i < threads.Length; i++) { threads[i].Start(); } for (int i = 0; i < threads.Length; i++) { threads[i].Join(); } } for (int i = 0; i < threads.Length; i++) { Assert.Null(errors[i]); } }