简体   繁体   中英

Akka.Net Streams - Source stops pulling elements when buffer throws error

I've been playing a little with the streams extension package for Akka.Net and noticed this error at attempting to combine buffer and throttle methods:

using (var system = ActorSystem.Create("test-system"))
using (var materializer = system.Materializer(GetSettings(system)))
{
            int index = 0;
            var sink = Sink.ActorRefWithAck<KeyValue>(
                system.ActorOf<Writer>(), 
                new OnInitMessage(), 
                new OnAcknowledgeMessage(), 
                OnComplete.Instance, 
                exception => new OnError(exception));

            ServiceBusSource
                .Create(client, message =>
                {
                    var json = new StreamReader(message.GetBody<Stream>(), Encoding.UTF8).ReadToEnd();
                    var result = JsonConvert.DeserializeObject<KeyValue>(json);

                    message.Complete();

                    return result;
                })
                .WithLogger(system, entity => $"{entity.Key} => {entity.Value}")
                .Buffer(1, OverflowStrategy.Fail)
                .Throttle(1, TimeSpan.FromSeconds(5), 3, ThrottleMode.Shaping)
                .ToMaterialized(sink, Keep.Right)
                .Run(materializer);

            Console.ReadLine();
}

I'm using ServiceBusSource from Alpakka These are the packages I'm referencing:

  • Akka.Streams: 1.3.1
  • Akka.Streams.Azure.ServiceBus: 0.1.0
  • WindowsAzure.ServiceBus: 4.1.3

I'm intentionally making it fail in order to see how behaves BUT , after failing from buffer's strategy, the stream completes and no more elements are being pulled.

KeyValue.cs

public class KeyValue
{
    public int Id { get; set; }

    public string Key { get; set; }

    public string Value { get; set; }

    public DateTime Produced { get; set; }

    public DateTime Emitted { get; set; }

    public override string ToString()
    {
        return $"[{Produced}] - [{Emitted}] => {Id} {Key}:{Value}";
    }
}

GetSettings Method:

ActorMaterializerSettings GetSettings(ActorSystem system)
        {
            return ActorMaterializerSettings.Create(system)
                .WithSupervisionStrategy(cause =>
                {
                    system.Log.Error(cause, "Failed");
                    return Directive.Resume;
                });
        }

There are several ways of handling errors inside of a stream - most of them described in docs :

  1. Use Recover to make a fallback event from error.
  2. Use RecoverWithRetries to allow to redirect to a different stream upon error.
  3. Use Restart.WithBackoff to rebuild a retry stream after exponential backoff delay.
  4. Use WithSupervisionStrategy - which is a very limited option, as it works only on stages that refer to it explicitly (as explained in docs).

Your case is by design - when you use OverflowStrategy.Fail it means, that once overflow is reached, an error will be produced. Reaction of most of the akka stages is to close stream immediately upon failure.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM