public void MaxNumberOfGroupsTest() { var scheduler = new TestScheduler(); var block = new JoinBlock <int, int> ( new GroupingDataflowBlockOptions { MaxNumberOfGroups = 1, TaskScheduler = scheduler }); Assert.IsTrue(block.Target1.Post(1)); Assert.IsFalse(block.Target1.Post(2)); Assert.IsTrue(block.Target2.Post(3)); Assert.IsFalse(block.Target2.Post(4)); Tuple <int, int> batch; Assert.IsTrue(block.TryReceive(out batch)); Assert.AreEqual(Tuple.Create(1, 3), batch); Assert.IsFalse(block.TryReceive(out batch)); scheduler.ExecuteAll(); Assert.IsTrue(block.Completion.Wait(1000)); }
/// <summary> /// Creates a dataflow builder from a join of multiple source blocks. /// </summary> /// <typeparam name="TOutput1"></typeparam> /// <typeparam name="TOutput2"></typeparam> /// <typeparam name="TOutput3"></typeparam> /// <param name="sourceBlock1"></param> /// <param name="sourceBlock2"></param> /// <param name="sourceBlock3"></param> /// <param name="joinOptions"></param> /// <returns></returns> public ISourceDataflowBuilder <Tuple <TOutput1, TOutput2, TOutput3> > Join <TOutput1, TOutput2, TOutput3>(ISourceBlock <TOutput1> sourceBlock1, ISourceBlock <TOutput2> sourceBlock2, ISourceBlock <TOutput3> sourceBlock3, DataflowJoinOptions joinOptions = default(DataflowJoinOptions)) { if (sourceBlock1 == null) { throw new ArgumentNullException("sourceBlock1"); } if (sourceBlock2 == null) { throw new ArgumentNullException("sourceBlock2"); } if (sourceBlock3 == null) { throw new ArgumentNullException("sourceBlock3"); } var joinBlock = new JoinBlock <TOutput1, TOutput2, TOutput3>(joinOptions.JoinBlockOptions); LinkHelper.Link(sourceBlock1, joinBlock.Target1, joinOptions.Target1LinkOptions); LinkHelper.Link(sourceBlock2, joinBlock.Target2, joinOptions.Target2LinkOptions); LinkHelper.Link(sourceBlock3, joinBlock.Target3, joinOptions.Target3LinkOptions); var multipleSourcesWrapper = new MultipleSourceDataflowWrapper(new IDataflowBlock[] { sourceBlock1, sourceBlock2, sourceBlock3 }); var sourceWrapper = new ReceivableSourceDataflowWrapper <Tuple <TOutput1, TOutput2, TOutput3> >(multipleSourcesWrapper, joinBlock, joinBlock); return(FromSource(sourceWrapper)); }
public void TestJoinWithFaultedTarget() { bool passed = true; var nonGreedyOptions = new GroupingDataflowBlockOptions { Greedy = false }; var goodSource = new ThrowerBlock(); var badSource = new ThrowerBlock(); var join = new JoinBlock <ThrowOn, ThrowOn>(nonGreedyOptions); var terminator = new ActionBlock <Tuple <ThrowOn, ThrowOn> >(xy => { Console.WriteLine("Terminator: We shouldn't be here - FAILED"); passed = false; }); // Pre-load the sources goodSource.Post(ThrowOn.TryReceive); // Will not throw in this test badSource.Post(ThrowOn.ConsumeMessage); // Link join.LinkTo(terminator); goodSource.LinkTo(join.Target1); badSource.LinkTo(join.Target2); Task.Delay(500).Wait(); // The Join must be faulted now passed &= TaskHasFaulted(join.Completion, "ConsumeMessage"); Assert.True(passed, string.Format("{0}", passed ? "Passed" : "FAILED")); }
public void TestNonGreedyFailToConsumeReservedMessage() { NullOnConsumeSource <int> source1 = new NullOnConsumeSource <int>(); NullOnConsumeSource <int> source2 = new NullOnConsumeSource <int>(); var options = new GroupingDataflowBlockOptions { Greedy = false }; JoinBlock <int, int> join = new JoinBlock <int, int>(options); source1.LinkTo(join.Target1); source2.LinkTo(join.Target2); try { join.Completion.Wait(); Assert.True(false, "Failed to throw an exception"); } catch (AggregateException ae) { ae.Handle(e => true); } if (source2.ConsumeMessageCalled) { Assert.True(false, "Failed to skip consuming the second message"); } }
public async Task TestPostThenReceive() { const int Iters = 3; var block2 = new JoinBlock <int, int>(); for (int i = 0; i < Iters; i++) { block2.Target1.Post(i); block2.Target2.Post(i + 1); Tuple <int, int> msg = await block2.ReceiveAsync(); Assert.Equal(expected: i, actual: msg.Item1); Assert.Equal(expected: i + 1, actual: msg.Item2); } var block3 = new JoinBlock <int, int, int>(); for (int i = 0; i < Iters; i++) { block3.Target1.Post(i); block3.Target2.Post(i + 1); block3.Target3.Post(i + 2); Tuple <int, int, int> msg = await block3.ReceiveAsync(); Assert.Equal(expected: i, actual: msg.Item1); Assert.Equal(expected: i + 1, actual: msg.Item2); Assert.Equal(expected: i + 2, actual: msg.Item3); } }
internal static bool BuffersToNonGreedyJoinToAction() { bool passed = true; const int ITERS = 2; var b1 = new BufferBlock <string>(); var b2 = new BufferBlock <int>(); var j = new JoinBlock <string, int>(new GroupingDataflowBlockOptions { Greedy = false }); b1.LinkWithCompletion(j.Target1); b2.LinkWithCompletion(j.Target2); var a = new ActionBlock <Tuple <string, int> >(t => Assert.True((t.Item1 == t.Item2.ToString()))); j.LinkWithCompletion(a); for (int i = 0; i < ITERS; i++) { b1.Post(i.ToString()); b2.Post(i); } b1.Complete(); b2.Complete(); a.Completion.Wait(); return(passed); }
public PipelineMergeLinker(ISourceBlock <IPipelineJobElement <T1> > from1, ISourceBlock <IPipelineJobElement <T2> > from2, ITargetBlock <IPipelineJobElement <Tuple <T1, T2> > > to, Predicate <IPipelineJobElement <T1> > predicate1, Predicate <IPipelineJobElement <T2> > predicate2) { if (predicate1 == null) { predicate1 = e => true; } if (predicate2 == null) { predicate2 = e => true; } Input = new JoinBlock <IPipelineJobElement <T1>, IPipelineJobElement <T2> >(); Output = new ActionBlock <Tuple <IPipelineJobElement <T1>, IPipelineJobElement <T2> > >( elements => { var job = elements.Item1.Job; var mergedElement = job.MergeToSingleElement(elements); to.Post(mergedElement); }); from1.LinkTo(Input.Target1, predicate1); from2.LinkTo(Input.Target2, predicate2); Input.LinkTo(Output); }
Then <TO, TLOutput, TROutput> ( Func <IBuilder <TOrigin, TTarget>, IBuilder <TO, TLOutput> > leftBranch, Func <IBuilder <TOrigin, TTarget>, IBuilder <TO, TROutput> > rightBranch ) { var broadcastBlock = new BroadcastBlock <TTarget>(i => i); _current.LinkTo(broadcastBlock, new DataflowLinkOptions { PropagateCompletion = true }); var broadcastBuilder = new MiddleBuilder <TOrigin, TTarget>(_start, broadcastBlock); var left = leftBranch(broadcastBuilder); var right = rightBranch(broadcastBuilder); var join = new JoinBlock <TLOutput, TROutput>(); left.End().LinkTo(join.Target1, new DataflowLinkOptions { PropagateCompletion = true }); right.End().LinkTo(join.Target2, new DataflowLinkOptions { PropagateCompletion = true }); return(new MiddleBuilder <TOrigin, Tuple <TLOutput, TROutput> >(_start, join)); }
private static void JoinAndCalculatePairs() { var bufferBlock = new BufferBlock <int>(); var bufferBlock2 = new BufferBlock <int>(); var joinBlock = new JoinBlock <int, int>(new GroupingDataflowBlockOptions { Greedy = false }); //new GroupingDataflowBlockOptions { Greedy = false } var transform = new TransformBlock <Tuple <int, int>, string>(x => $"{x.Item1} + {x.Item2} = {x.Item1 + x.Item2}"); var writer = new ActionBlock <string>(x => Console.WriteLine(x)); bufferBlock.LinkTo(joinBlock.Target1); bufferBlock2.LinkTo(joinBlock.Target2); joinBlock.LinkTo(transform); transform.LinkTo(writer); foreach (var i in Enumerable.Range(0, 10)) { bufferBlock.Post(i); } foreach (var i in Enumerable.Range(10, 20)) { bufferBlock2.Post(i); } bufferBlock.Complete(); bufferBlock2.Complete(); bufferBlock.Completion.Wait(); bufferBlock2.Completion.Wait(); Console.WriteLine("Done"); }
private static void SimpleNetwork() { var rand = new Random(DateTime.Now.Millisecond); var broadcastBlock = new BroadcastBlock <int>(x => x); var transformPositive = new TransformBlock <int, int>(x => { Thread.Sleep(1000); return(x); }); var transformNegative = new TransformBlock <int, int>(x => { Thread.Sleep(2000); return(x * -1); }); var join = new JoinBlock <int, int>(); var batchBlock = new BatchBlock <Tuple <int, int> >(5); var sumBlock = new ActionBlock <Tuple <int, int>[]>(tuples => { foreach (var tuple in tuples) { Console.WriteLine($"{tuple.Item1}+({tuple.Item2})={tuple.Item1 + tuple.Item2}"); } }); broadcastBlock.LinkTo(transformPositive, new DataflowLinkOptions { PropagateCompletion = true }); broadcastBlock.LinkTo(transformNegative, new DataflowLinkOptions { PropagateCompletion = true }); transformPositive.LinkTo(@join.Target1, new DataflowLinkOptions { PropagateCompletion = true }); transformNegative.LinkTo(@join.Target2, new DataflowLinkOptions { PropagateCompletion = true }); @join.LinkTo(batchBlock, new DataflowLinkOptions { PropagateCompletion = true }); batchBlock.LinkTo(sumBlock, new DataflowLinkOptions { PropagateCompletion = true }); for (int i = 0; i < 30; i++) { broadcastBlock.Post(rand.Next(100)); Thread.Sleep(1000); } broadcastBlock.Complete(); }
public void GreedyJoin3Test () { var scheduler = new TestScheduler (); var block = new JoinBlock<int, int, int> (new GroupingDataflowBlockOptions { TaskScheduler = scheduler }); var source1 = new BufferBlock<int> (new DataflowBlockOptions { TaskScheduler = scheduler }); var source2 = new BufferBlock<int> (new DataflowBlockOptions { TaskScheduler = scheduler }); var source3 = new BufferBlock<int> (new DataflowBlockOptions { TaskScheduler = scheduler }); Assert.IsNotNull (source1.LinkTo (block.Target1)); Assert.IsNotNull (source2.LinkTo (block.Target2)); Assert.IsNotNull (source3.LinkTo (block.Target3)); Assert.IsTrue (source1.Post (1)); scheduler.ExecuteAll (); int i; Assert.IsFalse (source1.TryReceive (out i)); Assert.IsTrue (source2.Post (11)); Assert.IsTrue (source3.Post (21)); scheduler.ExecuteAll (); Assert.IsFalse (source2.TryReceive (out i)); Assert.IsFalse (source3.TryReceive (out i)); Tuple<int, int, int> tuple; Assert.IsTrue (block.TryReceive (out tuple)); Assert.AreEqual (Tuple.Create (1, 11, 21), tuple); }
public void BasicUsageTest () { Tuple<int, int> tuple = null; var evt = new ManualResetEventSlim (false); var ablock = new ActionBlock<Tuple<int, int>> (t => { tuple = t; evt.Set (); }); var block = new JoinBlock<int, int> (); block.LinkTo (ablock); block.Target1.Post (42); evt.Wait (1000); Assert.IsNull (tuple); block.Target2.Post (24); evt.Wait (); Assert.IsNotNull (tuple); Assert.AreEqual (42, tuple.Item1); Assert.AreEqual (24, tuple.Item2); }
static void Main(string[] args) { var b1 = new BufferBlock <int>(); var b2 = new BufferBlock <string>(); var j = new JoinBlock <int, string>(); var a = new ActionBlock <Tuple <int, string> >(x => Console.WriteLine(x)); b1.LinkTo(j.Target1); b2.LinkTo(j.Target2); j.LinkTo(a); for (int i = 0; i < 10; i++) { b1.Post(i); } for (int i = 0; i < 10; i++) { Thread.Sleep(500); b2.Post(new string('*', i + 1)); } Console.ReadKey(); }
public MergeJoin() { Transformation = new RowTransformation <Tuple <TInput1, TInput2>, TOutput>(this); JoinBlock = new JoinBlock <TInput1, TInput2>(); Target1 = new MergeJoinTarget <TInput1>(this, JoinBlock.Target1); Target2 = new MergeJoinTarget <TInput2>(this, JoinBlock.Target2); }
public async Task TestPrecancellation3() { var b = new JoinBlock <int, int, int>(new GroupingDataflowBlockOptions { CancellationToken = new CancellationToken(canceled: true), MaxNumberOfGroups = 1 }); Assert.NotNull(b.LinkTo(DataflowBlock.NullTarget <Tuple <int, int, int> >())); Assert.False(b.Target1.Post(42)); Assert.False(b.Target2.Post(43)); Assert.False(b.Target2.Post(44)); Task <bool> t1 = b.Target1.SendAsync(42); Task <bool> t2 = b.Target2.SendAsync(43); Task <bool> t3 = b.Target2.SendAsync(44); Assert.True(t1.IsCompleted); Assert.False(t1.Result); Assert.True(t2.IsCompleted); Assert.False(t2.Result); Assert.True(t3.IsCompleted); Assert.False(t3.Result); Tuple <int, int, int> ignoredValue; IList <Tuple <int, int, int> > ignoredValues; Assert.False(b.TryReceive(out ignoredValue)); Assert.False(b.TryReceiveAll(out ignoredValues)); Assert.Equal(expected: 0, actual: b.OutputCount); Assert.NotNull(b.Completion); b.Complete(); await Assert.ThrowsAnyAsync <OperationCanceledException>(() => b.Completion); }
public async Task BuffersToNonGreedyJoinToAction() { var b1 = new BufferBlock <string>(); var b2 = new BufferBlock <int>(); var j = new JoinBlock <string, int>(new GroupingDataflowBlockOptions { Greedy = false }); b1.LinkTo(j.Target1, new DataflowLinkOptions { PropagateCompletion = true }); b2.LinkTo(j.Target2, new DataflowLinkOptions { PropagateCompletion = true }); var a = new ActionBlock <Tuple <string, int> >(t => Assert.True((t.Item1 == t.Item2.ToString()))); j.LinkTo(a, new DataflowLinkOptions { PropagateCompletion = true }); for (int i = 0; i < Iterations; i++) { b1.Post(i.ToString()); b2.Post(i); } b1.Complete(); b2.Complete(); await a.Completion; }
public void BasicUsageTest() { Tuple <int, int> tuple = null; var evt = new ManualResetEventSlim(false); var ablock = new ActionBlock <Tuple <int, int> > (t => { tuple = t; evt.Set(); }); var block = new JoinBlock <int, int> (); block.LinkTo(ablock); block.Target1.Post(42); evt.Wait(1000); Assert.IsNull(tuple); block.Target2.Post(24); evt.Wait(); Assert.IsNotNull(tuple); Assert.AreEqual(42, tuple.Item1); Assert.AreEqual(24, tuple.Item2); }
static void Main(string[] args) { var random = new Random(); var broadcastBlock = new BroadcastBlock <int>(null); var transformPositive = new TransformBlock <int, int>(x => { Task.Delay(random.Next(200)).Wait(); return(x); }); var transformNegative = new TransformBlock <int, int>(x => { Task.Delay(random.Next(300)).Wait(); return(x * -1); }); var joinBlock = new JoinBlock <int, int>(); var sumBlock = new ActionBlock <(int, int)>(tuple => { Console.WriteLine($"{tuple.Item1}+{tuple.Item2}={tuple.Item1+tuple.Item2}"); }); broadcastBlock.LinkToWithPropagation(transformPositive); broadcastBlock.LinkToWithPropagation(transformNegative); transformNegative.LinkToWithPropagation(joinBlock.Target1); transformPositive.LinkToWithPropagation(joinBlock.Target2); }
public JoinLossesBlock() { _joinBlock = new JoinBlock <Trial, Trial>(); _outputBuffer = new BufferBlock <Trial>(); var joinAction = new ActionBlock <Tuple <Trial, Trial> >(items => { var joined = DoWork(items); _outputBuffer.SendAsync(joined).Wait(); }); joinAction.Completion.ContinueWith(_ => { if (joinAction.Completion.IsFaulted) { ((IDataflowBlock)_outputBuffer).Fault(joinAction.Completion.Exception); } else { _outputBuffer.Complete(); } }); _joinBlock.LinkTo(joinAction, new DataflowLinkOptions { PropagateCompletion = true }); }
public async Task TestTree() { foreach (bool greedy in DataflowTestHelpers.BooleanValues) { foreach (int boundedCapacity in new[] { DataflowBlockOptions.Unbounded, 1 }) { foreach (int maxMessagesPerTask in new[] { DataflowBlockOptions.Unbounded, 1 }) { var gdbo = new GroupingDataflowBlockOptions { Greedy = greedy, BoundedCapacity = boundedCapacity, MaxMessagesPerTask = maxMessagesPerTask }; var linkOptions = new DataflowLinkOptions { PropagateCompletion = true }; var join1 = new JoinBlock <int, string>(gdbo); var join2 = new JoinBlock <double, short>(gdbo); var join5 = new JoinBlock <Tuple <int, string>, Tuple <double, short> >(gdbo); var join3 = new JoinBlock <string, object>(gdbo); var join4 = new JoinBlock <float, IntPtr>(gdbo); var join6 = new JoinBlock <Tuple <string, object>, Tuple <float, IntPtr> >(gdbo); var join7 = new JoinBlock < Tuple <Tuple <int, string>, Tuple <double, short> >, Tuple <Tuple <string, object>, Tuple <float, IntPtr> > >(gdbo); int count = 0; var sink = new ActionBlock <Tuple <Tuple <Tuple <int, string>, Tuple <double, short> >, Tuple <Tuple <string, object>, Tuple <float, IntPtr> > > >(i => count++); join1.LinkTo(new ActionBlock <Tuple <int, string> >(item => { }), t => false); // ensure don't propagate across false filtered link join1.LinkTo(join5.Target1, linkOptions, t => true); // ensure joins work through filters join2.LinkTo(join5.Target2, linkOptions); join3.LinkTo(join6.Target1, linkOptions, t => true); join4.LinkTo(join6.Target2, linkOptions); join5.LinkTo(join7.Target1, linkOptions, t => true); join6.LinkTo(join7.Target2, linkOptions); join7.LinkTo(sink, linkOptions); const int Messages = 5; CreateFillLink <int>(Messages, join1.Target1); CreateFillLink <string>(Messages, join1.Target2); CreateFillLink <double>(Messages, join2.Target1); CreateFillLink <short>(Messages, join2.Target2); CreateFillLink <string>(Messages, join3.Target1); CreateFillLink <object>(Messages, join3.Target2); CreateFillLink <float>(Messages, join4.Target1); CreateFillLink <IntPtr>(Messages, join4.Target2); await sink.Completion; Assert.Equal(expected: Messages, actual: count); } } } }
public void Run() { var broadcastBlock = new BroadcastBlock <int>(a => a); var a1 = new TransformBlock <int, int>(a => { Console.WriteLine($"Mesaj {a} a1 tarafından işlenilmekte."); Task.Delay(300).Wait(); if (a % 2 == 0) { Task.Delay(300).Wait(); } else { Task.Delay(50).Wait(); } return(-a); }, new ExecutionDataflowBlockOptions() { MaxDegreeOfParallelism = 3 }); var a2 = new TransformBlock <int, int>(a => { Console.WriteLine($"Mesaj {a} a2 tarafından işlenilmekte."); Task.Delay(150).Wait(); return(a); }, new ExecutionDataflowBlockOptions() { MaxDegreeOfParallelism = 8 }); broadcastBlock.LinkTo(a1); broadcastBlock.LinkTo(a2); var joinBlock = new JoinBlock <int, int>(); a1.LinkTo(joinBlock.Target1); a2.LinkTo(joinBlock.Target2); var printBlock = new ActionBlock <Tuple <int, int> >(a => Console.WriteLine($"{a} mesajı print block tarafından işlenildi. Değerler toplamı her zaman 0 dönecektir: {a.Item1+a.Item2}")); joinBlock.LinkTo(printBlock); for (int i = 0; i < 10; i++) { broadcastBlock.SendAsync(i).ContinueWith(a => { if (a.Result) { Console.WriteLine($"{i} mesajı kabul edildi."); } else { Console.WriteLine($"{i} mesajı reddedildi."); } }); } }
public MergeJoin() { NLogger = NLog.LogManager.GetLogger("ETL"); Transformation = new RowTransformation <Tuple <TInput1, TInput2>, TOutput>(this); JoinBlock = new JoinBlock <TInput1, TInput2>(); Target1 = new MergeJoinTarget <TInput1>(JoinBlock.Target1); Target2 = new MergeJoinTarget <TInput2>(JoinBlock.Target2); }
private static JoinBlock <int, int> ConstructJoinNewWithNMessages(int messagesCount) { var block = new JoinBlock <int, int>(); block.Target1.PostRange(0, messagesCount); block.Target2.PostRange(0, messagesCount); SpinWait.SpinUntil(() => block.OutputCount == messagesCount); // spin until messages available return(block); }
public void NonGreedyJoinWithPostTest() { var block = new JoinBlock <int, int> (new GroupingDataflowBlockOptions { Greedy = false }); Assert.IsFalse(block.Target1.Post(42)); }
// JoinBlocks allow two execution paths join together. For that, we will convert our // action blocks from the previous example into TransformBlock so that they can return values. // // Visualize This Workflow // -> Transform1 -> // ForLoop -> Buffer -> Broadcast -> -> JoinBlock -> Action (Print) // -> Transform2 -> // // Notice: One final thing to note here is that message order is preserved. private static async Task SimpleDemoAsync() { Console.WriteLine("JoinBlockDemo has started!"); var bufferExecutionOptions = new ExecutionDataflowBlockOptions { BoundedCapacity = 10 }; var transformOptions = new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 5 }; // add parallelism back var options = new DataflowLinkOptions { PropagateCompletion = true }; var bufferBlock = new BufferBlock <string>(bufferExecutionOptions); var broadCastBlock = new BroadcastBlock <string>( input => input); var transform1 = new TransformBlock <string, string>( (input) => $"TransformBlock1: {input}", transformOptions); var transform2 = new TransformBlock <string, string>( (input) => $"TransformBlock2: {input}", transformOptions); bufferBlock.LinkTo(broadCastBlock, options); broadCastBlock.LinkTo(transform1, options); broadCastBlock.LinkTo(transform2, options); var joinBlock = new JoinBlock <string, string>(); transform1.LinkTo(joinBlock.Target1, options); // You have to stitch up where the executions are going in your join block. transform2.LinkTo(joinBlock.Target2, options); var actionBlock = new ActionBlock <Tuple <string, string> >(Console.WriteLine); joinBlock.LinkTo(actionBlock, options); for (int i = 0; i < 20; i++) { await bufferBlock .SendAsync(ProduceTimeData(i)) .ConfigureAwait(false); } bufferBlock.Complete(); //await bufferBlock.Completion.ConfigureAwait(false); //await broadCastBlock.Completion.ConfigureAwait(false); //await transform1.Completion.ConfigureAwait(false); //await transform2.Completion.ConfigureAwait(false); // Because we are using PropagateCompletion = true and the last block is a single ActionBlock, // we will wait for all our marbles to reach the finish line with a single line. await actionBlock.Completion.ConfigureAwait(false); Console.WriteLine("Finished!"); Console.ReadKey(); }
public void TestArgumentExceptions() { Assert.Throws <ArgumentNullException>(() => new JoinBlock <int, int>(null)); Assert.Throws <ArgumentNullException>(() => new JoinBlock <int, int, int>(null)); Assert.Throws <NotSupportedException>(() => { var ignored = new JoinBlock <int, int>().Target1.Completion; }); Assert.Throws <NotSupportedException>(() => { var ignored = new JoinBlock <int, int, int>().Target3.Completion; }); DataflowTestHelpers.TestArgumentsExceptions <Tuple <int, int> >(new JoinBlock <int, int>()); DataflowTestHelpers.TestArgumentsExceptions <Tuple <int, int, int> >(new JoinBlock <int, int, int>()); }
public void TestJoinInvalidArgumentValidation() { Assert.Throws <ArgumentNullException>(() => new JoinBlock <int, int>(null)); Assert.Throws <ArgumentNullException>(() => new JoinBlock <int, int, int>(null)); Assert.Throws <NotSupportedException>(() => { var ignored = new JoinBlock <int, int>().Target1.Completion; }); Assert.Throws <NotSupportedException>(() => { var ignored = new JoinBlock <int, int, int>().Target3.Completion; }); Assert.True(ISourceBlockTestHelper.TestArgumentsExceptions <Tuple <int, int> >(new JoinBlock <int, int>())); Assert.True(ISourceBlockTestHelper.TestArgumentsExceptions <Tuple <int, int, int> >(new JoinBlock <int, int, int>())); }
public static async Task JoinBlockNonGreedy() { var producer1 = new BufferBlock <int>(); var producer2 = new BufferBlock <int>(); var joinBlock = new JoinBlock <int, int>( new GroupingDataflowBlockOptions { Greedy = false // because this non greedy }); // this line will never be execute var actionBlock = new ActionBlock <Tuple <int, int> >(item => System.Console.WriteLine(item)); var actionBlockB = new ActionBlock <int>(item => Console.WriteLine(item)); producer1.LinkTo(joinBlock.Target1, new DataflowLinkOptions { PropagateCompletion = true }); producer2.LinkTo(joinBlock.Target2, new DataflowLinkOptions { PropagateCompletion = true }); joinBlock.LinkTo(actionBlock, new DataflowLinkOptions { PropagateCompletion = true }); //this action block will suck up all the data before join block has a chance producer1.LinkTo(actionBlockB, new DataflowLinkOptions { PropagateCompletion = true }); producer1.Post(1); producer2.Post(5); producer1.Post(2); producer2.Post(2); producer1 .Post(3); // In non greedymode,the joinblock will postpone receiving this message //producer1.Complete(); //joinBlock.Complete(); await actionBlock.Completion; System.Console.WriteLine("done"); }
public void NonGreedyJoin3WithBoundedCapacityTest() { var scheduler = new TestScheduler(); var block = new JoinBlock <int, int, int> ( new GroupingDataflowBlockOptions { Greedy = false, BoundedCapacity = 1, TaskScheduler = scheduler }); var source1 = new BufferBlock <int> (new DataflowBlockOptions { TaskScheduler = scheduler }); var source2 = new BufferBlock <int> (new DataflowBlockOptions { TaskScheduler = scheduler }); var source3 = new BufferBlock <int> (new DataflowBlockOptions { TaskScheduler = scheduler }); Assert.IsNotNull(source1.LinkTo(block.Target1)); Assert.IsNotNull(source2.LinkTo(block.Target2)); Assert.IsNotNull(source3.LinkTo(block.Target3)); Assert.IsTrue(source1.Post(11)); Assert.IsTrue(source2.Post(21)); Assert.IsTrue(source3.Post(31)); scheduler.ExecuteAll(); Assert.IsTrue(source1.Post(12)); Assert.IsTrue(source2.Post(22)); Assert.IsTrue(source3.Post(32)); scheduler.ExecuteAll(); int i; Assert.IsTrue(source1.TryReceive(out i)); Assert.AreEqual(12, i); Assert.IsTrue(source1.Post(13)); Tuple <int, int, int> tuple; Assert.IsTrue(block.TryReceive(out tuple)); Assert.AreEqual(Tuple.Create(11, 21, 31), tuple); scheduler.ExecuteAll(); Assert.IsTrue(block.TryReceive(out tuple)); Assert.AreEqual(Tuple.Create(13, 22, 32), tuple); }
static void Main(string[] args) { var broadcastBlock = new BroadcastBlock <int>(a => a); broadcastBlock.Completion.ContinueWith(a => Console.WriteLine("broadcastBlock completed")); var a1 = new TransformBlock <int, int>(n => { Console.WriteLine($"Message {n} received by Consumer 1"); Task.Delay(n % 2 == 0 ? 300 : 100).Wait(); // Join block will still pair them correctly return(n * -1); }, new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 2 }); var a2 = new TransformBlock <int, int>(n => { Console.WriteLine($"Message {n} received by Consumer 2"); Task.Delay(n % 2 == 0 ? 100 : 300).Wait(); // Join block will still pair them correctly return(n); }, new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 2 }); broadcastBlock.LinkTo(a1, new DataflowLinkOptions { PropagateCompletion = true }); broadcastBlock.LinkTo(a2, new DataflowLinkOptions { PropagateCompletion = true }); var joinBlock = new JoinBlock <int, int>(); a1.LinkTo(joinBlock.Target1, new DataflowLinkOptions { PropagateCompletion = true }); a2.LinkTo(joinBlock.Target2, new DataflowLinkOptions { PropagateCompletion = true }); var finalBlock = new ActionBlock <Tuple <int, int> >(a => Console.WriteLine($"Message {a.Item1},{a.Item2} was processed")); joinBlock.LinkTo(finalBlock, new DataflowLinkOptions { PropagateCompletion = true }); for (int i = 0; i < 10; i++) { broadcastBlock.SendAsync(i); // Like Post, if receivers are not ready then they will be ignored, there is no retry } broadcastBlock.Complete(); finalBlock.Completion.Wait(); Console.WriteLine("Finished!"); }
static void Main(string[] args) { var broadcastBlock = new BroadcastBlock <int>(a => a); var a1 = new TransformBlock <int, int>(a => { Console.WriteLine($"Message {a} was processed by Consumer 1"); return(a); }, new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 10 } ); var a2 = new TransformBlock <int, int>(a => { Console.WriteLine($"Message {a} was processed by Consumer 2"); Task.Delay(1300).Wait(); return(a); } ); var joinBlock = new JoinBlock <int, int>(); a1.LinkTo(joinBlock.Target1); a2.LinkTo(joinBlock.Target2); var printBlock = new ActionBlock <Tuple <int, int> >(i => Console.WriteLine(i)); joinBlock.LinkTo(printBlock); broadcastBlock.LinkTo(a1); broadcastBlock.LinkTo(a2); for (int i = 0; i < 10; i++) { broadcastBlock.SendAsync(i) .ContinueWith(a => { if (a.Result) { Console.WriteLine($"Message {i} was accepted"); } else { Console.WriteLine($"Message {i} was rejected"); } }); } Console.WriteLine("Finished!"); Console.ReadKey(); }
protected override void InitBufferObjects() { Transformation = new RowTransformation <Tuple <TInput1, TInput2>, TOutput>(this); if (MaxBufferSize > 0) { Transformation.MaxBufferSize = this.MaxBufferSize; } JoinBlock = new JoinBlock <TInput1, TInput2>(new GroupingDataflowBlockOptions() { BoundedCapacity = MaxBufferSize }); }
public void CompletionTest () { var block = new JoinBlock<int, int, int> (); Assert.IsTrue (block.Target1.Post (1)); block.Complete (); Tuple<int, int, int> tuple; Assert.IsFalse (block.TryReceive (out tuple)); Assert.IsTrue (block.Completion.Wait (1000)); }
public void DeadlockTest () { Tuple<int, int> tuple = null; var evt = new ManualResetEventSlim (false); var ablock = new ActionBlock<Tuple<int, int>> (t => { tuple = t; evt.Set (); }); var block = new JoinBlock<int, int> (); block.LinkTo (ablock); Task.Factory.StartNew (() => block.Target1.Post (42)); Task.Factory.StartNew (() => block.Target2.Post (24)); Assert.IsTrue (evt.Wait (1000)); Assert.IsNotNull (tuple); Assert.AreEqual (42, tuple.Item1); Assert.AreEqual (24, tuple.Item2); }
public void BoundedCapacityTest () { var block = new JoinBlock<int, int> ( new GroupingDataflowBlockOptions { BoundedCapacity = 1 }); Assert.IsTrue (block.Target1.Post (1)); Assert.IsFalse (block.Target1.Post (2)); Assert.IsTrue (block.Target2.Post (10)); Assert.IsFalse (block.Target2.Post (11)); Assert.IsFalse (block.Target1.Post (3)); Assert.AreEqual (Tuple.Create (1, 10), block.Receive ()); Assert.IsTrue (block.Target1.Post (4)); }
public async Task TestLinkTo_DoubleLinking() { foreach (bool greedy in DataflowTestHelpers.BooleanValues) foreach (bool append in DataflowTestHelpers.BooleanValues) { var source1 = new BufferBlock<int>(); var source2 = new BufferBlock<int>(); var jb = new JoinBlock<int, int>(new GroupingDataflowBlockOptions { MaxNumberOfGroups = 1, Greedy = greedy }); var ignored = source1.Completion.ContinueWith(_ => jb.Target1.Complete(), TaskScheduler.Default); ignored = source2.Completion.ContinueWith(_ => jb.Target2.Complete(), TaskScheduler.Default); using (source1.LinkTo(jb.Target1)) { source1.LinkTo(jb.Target1, new DataflowLinkOptions { Append = append }); // force NopLinkPropagator creation } using (source2.LinkTo(jb.Target2)) { source2.LinkTo(jb.Target2, new DataflowLinkOptions { Append = append }); // force NopLinkPropagator creation } source1.Post(42); source2.Post(43); source1.Complete(); source2.Complete(); var tuple = jb.Receive(); Assert.Equal(expected: 42, actual: tuple.Item1); Assert.Equal(expected: 43, actual: tuple.Item2); } ITargetBlock<int> target = new ActionBlock<int>(i => { }); ISourceBlock<int> source = new BufferBlock<int>(); using (source.LinkTo(target)) { source.LinkTo(target, new DataflowLinkOptions { PropagateCompletion = true }); source.LinkTo(target, new DataflowLinkOptions { PropagateCompletion = true }, f => false); } source.Fault(new FormatException()); await Assert.ThrowsAsync<AggregateException>(() => target.Completion); }
public void TestLinkTo_TwoPhaseCommit() { var source1 = new BufferBlock<int>(); var source2 = new BufferBlock<int>(); var jb = new JoinBlock<int, int>(new GroupingDataflowBlockOptions { Greedy = false, MaxNumberOfGroups = 1 }); source1.Completion.ContinueWith(_ => jb.Target1.Complete(), TaskScheduler.Default); source2.Completion.ContinueWith(_ => jb.Target2.Complete(), TaskScheduler.Default); source1.LinkTo(jb.Target1); source2.LinkTo(jb.Target2); source1.Post(42); source2.Post(43); source1.Complete(); source2.Complete(); var tuple = jb.Receive(); Assert.Equal(expected: 42, actual: tuple.Item1); Assert.Equal(expected: 43, actual: tuple.Item2); }
public async Task TestEncapsulate_ReserveAndRelease() { var buffer1 = new BufferBlock<int>(); var action1 = new ActionBlock<int>(i => buffer1.Post(i)); var ignored = action1.Completion.ContinueWith(delegate { buffer1.Complete(); }, TaskScheduler.Default); IPropagatorBlock<int, int> encapsulated1 = DataflowBlock.Encapsulate(action1, buffer1); var buffer2 = new BufferBlock<string>(); var action2 = new ActionBlock<string>(i => buffer2.Post(i)); ignored = action2.Completion.ContinueWith(delegate { buffer2.Complete(); }, TaskScheduler.Default); IPropagatorBlock<string, string> encapsulated2 = DataflowBlock.Encapsulate(action2, buffer2); var join = new JoinBlock<int, string>(new GroupingDataflowBlockOptions { Greedy = false }); encapsulated1.LinkTo(join.Target1, new DataflowLinkOptions { PropagateCompletion = true }); encapsulated2.LinkTo(join.Target2, new DataflowLinkOptions { PropagateCompletion = true }); for (int i = 0; i < 2; i++) { encapsulated1.Post(1); encapsulated2.Post("2"); Tuple<int, string> result = await join.ReceiveAsync(); } encapsulated1.Complete(); encapsulated2.Complete(); await join.Completion; }
internal static bool BuffersToNonGreedyJoinToAction() { bool passed = true; const int ITERS = 2; var b1 = new BufferBlock<string>(); var b2 = new BufferBlock<int>(); var j = new JoinBlock<string, int>(new GroupingDataflowBlockOptions { Greedy = false }); b1.LinkWithCompletion(j.Target1); b2.LinkWithCompletion(j.Target2); var a = new ActionBlock<Tuple<string, int>>(t => Assert.True((t.Item1 == t.Item2.ToString()))); j.LinkWithCompletion(a); for (int i = 0; i < ITERS; i++) { b1.Post(i.ToString()); b2.Post(i); } b1.Complete(); b2.Complete(); a.Completion.Wait(); return passed; }
public async Task BuffersToNonGreedyJoinToAction() { var b1 = new BufferBlock<string>(); var b2 = new BufferBlock<int>(); var j = new JoinBlock<string, int>(new GroupingDataflowBlockOptions { Greedy = false }); b1.LinkTo(j.Target1, new DataflowLinkOptions { PropagateCompletion = true }); b2.LinkTo(j.Target2, new DataflowLinkOptions { PropagateCompletion = true }); var a = new ActionBlock<Tuple<string, int>>(t => Assert.True((t.Item1 == t.Item2.ToString()))); j.LinkTo(a, new DataflowLinkOptions { PropagateCompletion = true }); for (int i = 0; i < Iterations; i++) { b1.Post(i.ToString()); b2.Post(i); } b1.Complete(); b2.Complete(); await a.Completion; }
public void NonGreedyJoinWithPostTest () { var block = new JoinBlock<int, int> (new GroupingDataflowBlockOptions { Greedy = false }); Assert.IsFalse (block.Target1.Post (42)); }
public void NonGreedyJoin3WithBoundedCapacityTest () { var scheduler = new TestScheduler (); var block = new JoinBlock<int, int, int> ( new GroupingDataflowBlockOptions { Greedy = false, BoundedCapacity = 1, TaskScheduler = scheduler }); var source1 = new BufferBlock<int> (new DataflowBlockOptions { TaskScheduler = scheduler }); var source2 = new BufferBlock<int> (new DataflowBlockOptions { TaskScheduler = scheduler }); var source3 = new BufferBlock<int> (new DataflowBlockOptions { TaskScheduler = scheduler }); Assert.IsNotNull (source1.LinkTo (block.Target1)); Assert.IsNotNull (source2.LinkTo (block.Target2)); Assert.IsNotNull (source3.LinkTo (block.Target3)); Assert.IsTrue (source1.Post (11)); Assert.IsTrue (source2.Post (21)); Assert.IsTrue (source3.Post (31)); scheduler.ExecuteAll (); Assert.IsTrue (source1.Post (12)); Assert.IsTrue (source2.Post (22)); Assert.IsTrue (source3.Post (32)); scheduler.ExecuteAll (); int i; Assert.IsTrue (source1.TryReceive (out i)); Assert.AreEqual (12, i); Assert.IsTrue (source1.Post (13)); Tuple<int, int, int> tuple; Assert.IsTrue (block.TryReceive (out tuple)); Assert.AreEqual (Tuple.Create (11, 21, 31), tuple); scheduler.ExecuteAll (); Assert.IsTrue (block.TryReceive (out tuple)); Assert.AreEqual (Tuple.Create (13, 22, 32), tuple); }
public void MaxNumberOfGroupsTest () { var scheduler = new TestScheduler (); var block = new JoinBlock<int, int> ( new GroupingDataflowBlockOptions { MaxNumberOfGroups = 1, TaskScheduler = scheduler }); Assert.IsTrue (block.Target1.Post (1)); Assert.IsFalse (block.Target1.Post (2)); Assert.IsTrue (block.Target2.Post (3)); Assert.IsFalse (block.Target2.Post (4)); Tuple<int, int> batch; Assert.IsTrue (block.TryReceive (out batch)); Assert.AreEqual (Tuple.Create (1, 3), batch); Assert.IsFalse (block.TryReceive (out batch)); scheduler.ExecuteAll (); Assert.IsTrue (block.Completion.Wait (1000)); }
public void NonGreedyMaxNumberOfGroupsTest () { var scheduler = new TestScheduler (); var block = new JoinBlock<int, int> ( new GroupingDataflowBlockOptions { MaxNumberOfGroups = 1, Greedy = false, TaskScheduler = scheduler }); var source1 = new TestSourceBlock<int> (); var source2 = new TestSourceBlock<int> (); var header1 = new DataflowMessageHeader (1); source1.AddMessage (header1, 11); source2.AddMessage (header1, 21); Assert.AreEqual (DataflowMessageStatus.Postponed, block.Target1.OfferMessage (header1, 11, source1, false)); Assert.AreEqual (DataflowMessageStatus.Postponed, block.Target2.OfferMessage (header1, 21, source2, false)); scheduler.ExecuteAll (); Assert.IsTrue (source1.WasConsumed (header1)); Assert.IsTrue (source2.WasConsumed (header1)); var header2 = new DataflowMessageHeader (2); Assert.AreEqual (DataflowMessageStatus.DecliningPermanently, block.Target1.OfferMessage (header2, 21, source1, false)); Tuple<int, int> tuple; Assert.IsTrue (block.TryReceive (out tuple)); Assert.AreEqual (Tuple.Create (11, 21), tuple); Assert.IsTrue (block.Completion.Wait (1000)); }