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());
        }
Exemple #2
0
        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);
        }
Exemple #3
0
        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);
        }
Exemple #4
0
        /// <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);
        }
Exemple #7
0
		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));
     }
 }
Exemple #9
0
 public DataflowMessageStatus OfferMessage(
     DataflowMessageHeader messageHeader,
     CrawlerMessage messageValue,
     ISourceBlock <CrawlerMessage> source,
     bool consumeToAccept)
 {
     return(_input.OfferMessage(
                messageHeader, messageValue, source, consumeToAccept));
 }
Exemple #10
0
        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);
        }
Exemple #11
0
        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());
        }
Exemple #14
0
        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);
        }
Exemple #15
0
        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));
        }
Exemple #16
0
        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);
        }
Exemple #19
0
		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;
        }
Exemple #21
0
        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);
            }
        }
Exemple #22
0
        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));
        }
Exemple #25
0
        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);
            }
        }
Exemple #26
0
        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));
        }
Exemple #27
0
        /// <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();
            }
        }
Exemple #28
0
 public DataflowMessageStatus OfferMessage(DataflowMessageHeader messageHeader, T messageValue, ISourceBlock <T> source, bool consumeToAccept)
 {
     return(_timeoutBlock.OfferMessage(messageHeader, messageValue, source, consumeToAccept));
 }
Exemple #29
0
 // 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));
 }