public void OfferMessageWithSourceTest() { var block = new BufferBlock <int> (new DataflowBlockOptions { BoundedCapacity = 1 }); ITargetBlock <int> target = block; var source = new TestSourceBlock <int> (); Assert.AreEqual(DataflowMessageStatus.Accepted, target.OfferMessage(new DataflowMessageHeader(1), 42, source, false)); var header = new DataflowMessageHeader(2); source.AddMessage(header, 43); Assert.AreEqual(DataflowMessageStatus.Postponed, target.OfferMessage(header, 43, source, false)); Assert.AreEqual(42, block.Receive(TimeSpan.FromMilliseconds(100))); Assert.IsFalse(block.Completion.Wait(100)); Assert.IsTrue(source.WasConsumed(header)); Assert.AreEqual(43, block.Receive(TimeSpan.FromMilliseconds(100))); Assert.AreEqual(DataflowMessageStatus.Accepted, target.OfferMessage(new DataflowMessageHeader(3), 44, source, false)); Assert.AreEqual(44, block.Receive()); }
internal static bool TestArgumentsExceptions <T>(ITargetBlock <T> target) { bool passed = true; var validMessageHeader = new DataflowMessageHeader(1); var invalidMessageHeader = default(DataflowMessageHeader); var validSource = new BufferBlock <T>(); ISourceBlock <T> invalidSource = null; Assert.Throws <ArgumentException>(() => target.OfferMessage(invalidMessageHeader, default(T), validSource, false)); Assert.Throws <ArgumentException>(() => target.OfferMessage(invalidMessageHeader, default(T), invalidSource, false)); Assert.Throws <ArgumentException>(() => target.OfferMessage(validMessageHeader, default(T), invalidSource, true)); return(passed); }
public DataflowMessageStatus OfferMessage( DataflowMessageHeader messageHeader, Uri messageValue, ISourceBlock <Uri> source, bool consumeToAccept) { if (_markedForCompletion || _cancellationToken.IsCancellationRequested) { return(DataflowMessageStatus.DecliningPermanently); } if (_shouldAccept(messageValue)) { var status = _target.OfferMessage(SingleMessageHeader, messageValue, null, false); if (status != DataflowMessageStatus.Accepted) { return(status); } _emitHeartbeat(); _events.OnAccepted(new AcceptedContext(messageValue)); } return(DataflowMessageStatus.Accepted); }
/// <summary> /// Offers the message (belong to the target). /// </summary> /// <param name="messageHeader">The message header.</param> /// <param name="messageValue">The message value.</param> /// <param name="source">The source.</param> /// <param name="consumeToAccept">if set to <c>true</c> [consume to accept].</param> /// <returns></returns> public DataflowMessageStatus OfferMessage( DataflowMessageHeader messageHeader, TIn messageValue, ISourceBlock <TIn> source, bool consumeToAccept) { DataflowMessageStatus result = _target.OfferMessage(messageHeader, messageValue, source, consumeToAccept); BlockInfo.PushOfferingCounter.Increment(result); #region BlockInfo.PushOffering.Add(...) var hookSource = source as ISourceHook <TIn>; if (!(source is LinkHook <TIn>)) // optimization, in this case the like hook will handle the message { string sourceName = string.Empty; if (hookSource != null) { sourceName = hookSource.BlockInfo.Name; } var msg = new OfferMessageTrace(messageHeader.Id, messageValue, consumeToAccept, result, sourceName, BlockInfo.Name); BlockInfo.PushOffering.Add(msg); } #endregion // BlockInfo.PushOffering.Add(...) BlockInfo.Refresh(); return(result); }
public DataflowMessageStatus OfferMessage(DataflowMessageHeader messageHeader, TInput messageValue, ISourceBlock <TInput> source, bool consumeToAccept) { return(target.OfferMessage(messageHeader, messageValue, source, consumeToAccept)); }
/// <include file='XmlDocs/CommonXmlDocComments.xml' path='CommonXmlDocComments/Sources/Member[@name="ReleaseReservation"]/*' /> void ISourceBlock <T> .ReleaseReservation(DataflowMessageHeader messageHeader, ITargetBlock <T> target) { // Validate arguments if (!messageHeader.IsValid) { throw new ArgumentException(SR.Argument_InvalidMessageHeader, "messageHeader"); } if (target == null) { throw new ArgumentNullException("target"); } Contract.EndContractBlock(); // As long as the message is the one we have, everything's fine. if (_header.Id != messageHeader.Id) { throw new InvalidOperationException(SR.InvalidOperation_MessageNotReservedByTarget); } // In other blocks, upon release we typically re-offer the message to all linked targets. // We need to do the same thing for WriteOnceBlock, in order to account for cases where the block // may be linked to a join or similar block, such that the join could never again be satisfied // if it didn't receive another offer from this source. However, since the message is broadcast // and all targets can get a copy, we don't need to broadcast to all targets, only to // the target that released the message. Note that we don't care whether it's accepted // or not, nor do we care about any exceptions which may emerge (they should just propagate). Debug.Assert(_header.IsValid, "A valid header is required."); bool useCloning = _cloningFunction != null; target.OfferMessage(_header, _value, this, consumeToAccept: useCloning); }
public static bool Post<TInput> (this ITargetBlock<TInput> target, TInput item) { if (target == null) throw new ArgumentNullException ("target"); return target.OfferMessage (new DataflowMessageHeader(1), item, null, false) == DataflowMessageStatus.Accepted; }
internal static void TestOfferMessage_AcceptsDataDirectly <T>(ITargetBlock <T> target, int messages = 3) { for (int i = 1; i <= messages; i++) { Assert.Equal( expected: DataflowMessageStatus.Accepted, actual: target.OfferMessage(new DataflowMessageHeader(i), default(T), null, false)); } }
public DataflowMessageStatus OfferMessage( DataflowMessageHeader messageHeader, CrawlerMessage messageValue, ISourceBlock <CrawlerMessage> source, bool consumeToAccept) { return(_input.OfferMessage( messageHeader, messageValue, source, consumeToAccept)); }
public static bool Post <TInput> (this ITargetBlock <TInput> target, TInput item) { if (target == null) { throw new ArgumentNullException("target"); } return(target.OfferMessage(globalHeader.Increment(), item, null, false) == DataflowMessageStatus.Accepted); }
DataflowMessageStatus ITargetBlock <T> .OfferMessage(DataflowMessageHeader messageHeader, T messageValue, ISourceBlock <T> source, bool consumeToAccept) { var t = new TimedFunc <T, DataflowMessageStatus>(_time, v => _base.OfferMessage(messageHeader, messageValue, source, consumeToAccept)); var status = t.Do((t1, cont, status) => _subject.OnNext(t1), messageValue, messageValue); return(status); }
internal static void TestOfferMessage_CompleteAndOffer <T>(ITargetBlock <T> target, int messages = 3) { target.Complete(); for (int i = 1; i <= messages; i++) { Assert.Equal( expected: DataflowMessageStatus.DecliningPermanently, actual: target.OfferMessage(new DataflowMessageHeader(4), default(T), null, false)); } }
public void OfferMessageTest() { var block = new BufferBlock <int> (new DataflowBlockOptions { BoundedCapacity = 1 }); ITargetBlock <int> target = block; Assert.AreEqual(DataflowMessageStatus.Accepted, target.OfferMessage(new DataflowMessageHeader(1), 42, null, false)); Assert.AreEqual(DataflowMessageStatus.Declined, target.OfferMessage(new DataflowMessageHeader(2), 43, null, false)); Assert.AreEqual(42, block.Receive()); Assert.AreEqual(DataflowMessageStatus.Accepted, target.OfferMessage(new DataflowMessageHeader(3), 44, null, false)); Assert.AreEqual(44, block.Receive()); }
internal static bool TestOfferMessage <T>(ITargetBlock <T> target) { Console.WriteLine("* TestOfferMessage"); var status = target.OfferMessage(new DataflowMessageHeader(1), default(T), null, false); if (status != DataflowMessageStatus.Accepted) { Console.WriteLine("> OfferMessage failed! expected return value to be Accepted and actual {0}", status); return(false); } var src = new BufferBlock <T>(); src.Post(default(T)); src.LinkTo(target); var expectedStatus = DataflowMessageStatus.NotAvailable; if (target is WriteOnceBlock <T> ) // write once will always DecliningPermanently after the first msg { expectedStatus = DataflowMessageStatus.DecliningPermanently; } status = target.OfferMessage(new DataflowMessageHeader(2), default(T), src, true); if (status != expectedStatus) { Console.WriteLine("> OfferMessage failed! expected return value to be {0} and actual {1}", expectedStatus, status); return(false); } target.Complete(); status = target.OfferMessage(new DataflowMessageHeader(3), default(T), null, false); if (status != DataflowMessageStatus.DecliningPermanently) { Console.WriteLine("> OfferMessage failed! expected return value to be DecliningPermanently and actual {0}", status); return(false); } return(true); }
public void NonGreedyMaxNumberOfGroupsTest() { var scheduler = new TestScheduler(); var block = new BatchBlock <int> (2, new GroupingDataflowBlockOptions { MaxNumberOfGroups = 1, Greedy = false, TaskScheduler = scheduler }); ITargetBlock <int> target = block; 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, target.OfferMessage(header1, 11, source1, false)); Assert.AreEqual(DataflowMessageStatus.Postponed, target.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, target.OfferMessage(header2, 21, source1, false)); int[] batch; Assert.IsTrue(block.TryReceive(out batch)); CollectionAssert.AreEquivalent(new[] { 11, 21 }, batch); Assert.IsTrue(block.Completion.Wait(100)); }
public void ProcessForTarget(ITargetBlock <T> target, ISourceBlock <T> source, bool consumeToAccept, ref DataflowMessageHeader headers) { if (target == null) { return; } foreach (var output in GetNonBlockingConsumingEnumerable()) { target.OfferMessage(headers.Increment(), output, source, consumeToAccept); } VerifyCompleteness(); }
public IDisposable LinkTo(ITargetBlock <T> target, DataflowLinkOptions linkOptions) { // Validate arguments if (target == null) { throw new ArgumentNullException("target"); } if (linkOptions == null) { throw new ArgumentNullException("linkOptions"); } Contract.EndContractBlock(); bool hasValue; bool isCompleted; lock (ValueLock) { hasValue = HasValue; isCompleted = _completionReserved; // If we haven't gotten a value yet and the block is not complete, add the target and bail if (!hasValue && !isCompleted) { _targetRegistry.Add(ref target, linkOptions); return(Common.CreateUnlinker(ValueLock, _targetRegistry, target)); } } // If we already have a value, send it along to the linking target if (hasValue) { bool useCloning = _cloningFunction != null; target.OfferMessage(_header, _value, this, consumeToAccept: useCloning); } // If completion propagation has been requested, do it safely. // The Completion property will ensure the lazy TCS is initialized. if (linkOptions.PropagateCompletion) { Common.PropagateCompletionOnceCompleted(Completion, target); } return(Disposables.Nop); }
/// <summary> /// Offers the message (hook the link's messaging). /// </summary> /// <param name="messageHeader">The message header.</param> /// <param name="messageValue">The message value.</param> /// <param name="source">The source.</param> /// <param name="consumeToAccept">if set to <c>true</c> [consume to accept].</param> /// <returns></returns> public DataflowMessageStatus OfferMessage( DataflowMessageHeader messageHeader, T messageValue, ISourceBlock <T> source, bool consumeToAccept) { DataflowMessageStatus result = _target.OfferMessage(messageHeader, messageValue, this, consumeToAccept); LinkInfo.PushOfferingCounter.Increment(result); var msg = new OfferMessageTrace(messageHeader.Id, messageValue, consumeToAccept, result, _source.BlockInfo.Name, _targetName); LinkInfo.PushOffering.Add(msg); if (_targetInfo != null) { _targetInfo.PushOffering.Add(msg); } return(result); }
public static Task<bool> SendAsync<TInput> ( this ITargetBlock<TInput> target, TInput item, CancellationToken cancellationToken) { if (target == null) throw new ArgumentNullException ("target"); cancellationToken.ThrowIfCancellationRequested (); var status = target.OfferMessage ( new DataflowMessageHeader (1), item, null, false); if (status == DataflowMessageStatus.Accepted) return Task.FromResult (true); if (status != DataflowMessageStatus.Declined && status != DataflowMessageStatus.Postponed) return Task.FromResult (false); var block = new SendBlock<TInput> (target, item, cancellationToken); return block.Send (); }
internal static async Task TestOfferMessage_AcceptsViaLinking <T>(ITargetBlock <T> target, int messages = 3) { var src = new BufferBlock <T>(); var stingySource = new DelegatePropagator <T, T> { ConsumeMessageDelegate = (DataflowMessageHeader _, ITargetBlock <T> __, out bool messageConsumed) => { messageConsumed = false; return(default(T)); } }; Assert.Equal( expected: DataflowMessageStatus.NotAvailable, actual: target.OfferMessage(new DataflowMessageHeader(1), default(T), stingySource, consumeToAccept: true)); src.PostRange(1, messages + 1, i => default(T)); Assert.Equal(expected: messages, actual: src.Count); src.LinkTo(target); src.Complete(); await src.Completion; }
void TriggerMessage(T1 val1, T2 val2) { Tuple <T1, T2> tuple = Tuple.Create(val1, val2); ITargetBlock <Tuple <T1, T2> > target = targets.Current; if (target == null) { outgoing.AddData(tuple); } else { target.OfferMessage(headers.Increment(), tuple, this, false); } if (!outgoing.IsEmpty && (target = targets.Current) != null) { outgoing.ProcessForTarget(target, this, false, ref headers); } }
void MakeBatch(ITargetBlock <T[]> target, int size) { T[] batch = new T[size]; for (int i = 0; i < size; ++i) { messageQueue.TryTake(out batch[i]); } if (target == null) { outgoing.AddData(batch); } else { target.OfferMessage(headers.Increment(), batch, this, false); } if (!outgoing.IsEmpty && targets.Current != null) { outgoing.ProcessForTarget(targets.Current, this, false, ref headers); } }
private List <Exception> OfferToTargets() { Common.ContractAssertMonitorStatus(ValueLock, held: false); // If there is a message, offer it to everyone. Return values // don't matter, because we only get one message and then complete, // and everyone who wants a copy can get a copy. List <Exception> exceptions = null; if (HasValue) { TargetRegistry <T> .LinkedTargetInfo cur = _targetRegistry.FirstTargetNode; while (cur != null) { TargetRegistry <T> .LinkedTargetInfo next = cur.Next; ITargetBlock <T> target = cur.Target; try { // Offer the message. If there's a cloning function, we force the target to // come back to us to consume the message, allowing us the opportunity to run // the cloning function once we know they want the data. If there is no cloning // function, there's no reason for them to call back here. bool useCloning = _cloningFunction != null; target.OfferMessage(_header, _value, this, consumeToAccept: useCloning); } catch (Exception exc) { // Track any erroneous exceptions that may occur // and return them to the caller so that they may // be logged in the completion task. Common.StoreDataflowMessageValueIntoExceptionData(exc, _value); Common.AddException(ref exceptions, exc); } cur = next; } } return(exceptions); }
public void BoundedPostponedTest() { var scheduler = new TestScheduler(); var broadcast = new BroadcastBlock <int> ( null, new DataflowBlockOptions { TaskScheduler = scheduler, BoundedCapacity = 1 }); ITargetBlock <int> target = broadcast; var source = new TestSourceBlock <int> (); Assert.IsTrue(broadcast.Post(1)); var header = new DataflowMessageHeader(1); source.AddMessage(header, 2); Assert.AreEqual(DataflowMessageStatus.Postponed, target.OfferMessage(header, 2, source, false)); Assert.IsFalse(source.WasConsumed(header)); scheduler.ExecuteAll(); Assert.IsTrue(source.WasConsumed(header)); }
private static void Intro2() { ISourceBlock <string> mock = A.Fake <ISourceBlock <string> >(); //A.CallTo(() => mock.ConsumeMessage( // A<DataflowMessageHeader>.Ignored, // A<ITargetBlock<string>>.Ignored, // out bool b)) // .Returns(false); _target = new ActionBlock <string>(async item => { Console.WriteLine($"processing {item}"); await Task.Delay(500).ConfigureAwait(false); Console.WriteLine($"processed {item}"); }, new ExecutionDataflowBlockOptions { BoundedCapacity = 4 /* internal queue size*/ }); ITargetBlock <string> target = _target; for (int i = 1; i <= 10; i++) { //if(!_target.Post(i.ToString())) // Console.WriteLine($"Drop {i}"); DataflowMessageStatus response = target.OfferMessage( new DataflowMessageHeader(i), i.ToString(), mock, false); Console.WriteLine(response); } }
public DataflowMessageStatus OfferMessage( DataflowMessageHeader messageHeader, T messageValue, ISourceBlock <T> source, bool consumeToAccept) { if (!messageHeader.IsValid) { throw new ArgumentException("The messageHeader is not valid.", "messageHeader"); } if (consumeToAccept && source == null) { throw new ArgumentException( "consumeToAccept may only be true if provided with a non-null source.", "consumeToAccept"); } if (!predicate(messageValue)) { return(DataflowMessageStatus.Declined); } return(actualTarget.OfferMessage(messageHeader, messageValue, sourceBlock, consumeToAccept)); }
/// <summary> /// Offers the item to the target and hadles its response. /// </summary> void PerformSend() { DisableCancel(); if (taskCompletionSource.Task.IsCanceled) { return; } var status = sendTarget.OfferMessage(sendHeader, item, this, false); if (status == DataflowMessageStatus.Accepted) { SetResult(true); } else if (status != DataflowMessageStatus.Postponed) { SetResult(false); } else { EnableCancel(); } }
public DataflowMessageStatus OfferMessage(DataflowMessageHeader messageHeader, T messageValue, ISourceBlock <T> source, bool consumeToAccept) { return(_timeoutBlock.OfferMessage(messageHeader, messageValue, source, consumeToAccept)); }
// Asynchronously passes a message to the target block, giving the target the // opportunity to consume the message. DataflowMessageStatus ITargetBlock <T> .OfferMessage(DataflowMessageHeader messageHeader, T messageValue, ISourceBlock <T> source, bool consumeToAccept) { return(m_target.OfferMessage(messageHeader, messageValue, source, consumeToAccept)); }
internal static void TestOfferMessage_ArgumentValidation <T>(ITargetBlock <T> target) { Assert.Throws <ArgumentException>(() => target.OfferMessage(default(DataflowMessageHeader), default(T), new BufferBlock <T>(), false)); Assert.Throws <ArgumentException>(() => target.OfferMessage(default(DataflowMessageHeader), default(T), null, false)); Assert.Throws <ArgumentException>(() => target.OfferMessage(new DataflowMessageHeader(1), default(T), null, true)); }