/// <summary> /// Receive a series of messages until the function returns null or the idle /// timeout is met (disabled by default) or the overall /// maximum duration is elapsed or expected messages count is reached. /// Returns the sequence of messages. /// /// Note that it is not an error to hit the `max` duration in this case. /// The max duration is scaled by <see cref="Dilated(TimeSpan)"/> /// </summary> public IReadOnlyList <T> ReceiveWhile <T>(Func <object, T> filter, TimeSpan?max = null, TimeSpan?idle = null, int msgs = int.MaxValue) where T : class { var maxValue = RemainingOrDilated(max); var start = Now; var stop = start + maxValue; ConditionalLog("Trying to receive {0}messages of type {1} while filter returns non-nulls during {2}", msgs == int.MaxValue ? "" : msgs + " ", typeof(T), maxValue); var count = 0; var acc = new List <T>(); var idleValue = idle.GetValueOrDefault(Timeout.InfiniteTimeSpan); MessageEnvelope msg = NullMessageEnvelope.Instance; while (count < msgs) { MessageEnvelope envelope; if (!TryReceiveOne(out envelope, (stop - Now).Min(idleValue))) { _testState.LastMessage = msg; break; } var message = envelope.Message; var result = filter(message); if (result == null) { _testState.Queue.AddFirst(envelope); //Put the message back in the queue _testState.LastMessage = msg; break; } msg = envelope; acc.Add(result); count++; } ConditionalLog("Received {0} messages with filter during {1}", count, Now - start); _testState.LastWasNoMsg = true; return(acc); }
/// <summary> /// Receive one message from the internal queue of the TestActor within /// the specified duration. The method blocks the specified duration. /// <remarks><b>Note!</b> that the returned <paramref name="envelope"/> /// is a <see cref="MessageEnvelope"/> containing the sender and the message.</remarks> /// <remarks>This method does NOT automatically scale its Duration parameter using <see cref="Dilated(TimeSpan)" />!</remarks> /// </summary> /// <param name="envelope">The received envelope.</param> /// <param name="max">Optional: The maximum duration to wait. /// If <c>null</c> the config value "akka.test.single-expect-default" is used as timeout. /// If set to a negative value or <see cref="Timeout.InfiniteTimeSpan"/>, blocks forever. /// <remarks>This method does NOT automatically scale its Duration parameter using <see cref="Dilated(TimeSpan)" />!</remarks></param> /// <returns><c>True</c> if a message was received within the specified duration; <c>false</c> otherwise.</returns> public bool TryReceiveOne(out MessageEnvelope envelope, TimeSpan?max = null) { return(TryReceiveOne(out envelope, max, CancellationToken.None)); }
/// <summary> /// Receive one message from the internal queue of the TestActor within /// the specified duration. /// <para><c>True</c> is returned if a message existed, and the message /// is returned in <paramref name="envelope" />. The method blocks the /// specified duration, and can be cancelled using the /// <paramref name="cancellationToken" />. /// </para> /// <remarks>This method does NOT automatically scale its duration parameter using <see cref="Dilated(TimeSpan)" />!</remarks> /// </summary> /// <param name="envelope">The received envelope.</param> /// <param name="max">The maximum duration to wait. /// If <c>null</c> the config value "akka.test.single-expect-default" is used as timeout. /// If set to <see cref="Timeout.InfiniteTimeSpan"/>, blocks forever (or until cancelled). /// <remarks>This method does NOT automatically scale its Duration parameter using <see cref="Dilated(TimeSpan)" />!</remarks> /// </param> /// <param name="cancellationToken">A token used to cancel the operation.</param> /// <returns><c>True</c> if a message was received within the specified duration; <c>false</c> otherwise.</returns> public bool TryReceiveOne(out MessageEnvelope envelope, TimeSpan?max, CancellationToken cancellationToken) { return(InternalTryReceiveOne(out envelope, max, cancellationToken, true)); }