orleans: Exceptions on stream consumers are not logged

Hey folks!

I don’t know if it the desired behaviour but I noticed that when a grain receives a message and it throw an exception it doesn’t even write a a Warning log. It just swallow the exception:

image

If I set FireAndForgetDelivery = false, then the caller get the exception:

image

This is my repro code:

[ImplicitStreamSubscription("MyStream")]
    public class ConsumerGrain : Grain, IConsumerGrain
    {
        private readonly ILogger _logger;

        public ConsumerGrain(ILoggerFactory loggerFactory)
        {
            this._logger = loggerFactory.CreateLogger<ConsumerGrain>();
        }

        public override async Task OnActivateAsync()
        {
            var provider = this.GetStreamProvider("MyProvider");
            var stream = provider.GetStream<int>(this.GetPrimaryKey(), "MyStream");

            var handles = await stream.GetAllSubscriptionHandles();
            if (handles.Count > 0)
            {
                var tasks = new List<Task>();
                foreach (var handle in handles)
                {
                    tasks.Add(handle.ResumeAsync(this.Consume));
                }
                await Task.WhenAll(tasks);
            }
            else
            {
                await stream.SubscribeAsync(this.Consume);
            }
        }
        public Task Consume(int number, StreamSequenceToken token)
        {
            if (number % 2 == 0)
            {
                this._logger.LogInformation($"Stream received a message with an even number: {number}");

            }
            else
            {
                throw new InvalidOperationException($"Ops, we got an odd number and that is not cool: {number}");
            }

            return Task.CompletedTask;
        }
    }
public class PublisherGrain : Grain, IPublisherGrain
    {
        private IAsyncStream<int> _stream;
        private readonly Random _rnd;
        private readonly ILogger _logger;

        public PublisherGrain(ILoggerFactory loggerFactory)
        {
            this._logger = loggerFactory.CreateLogger<PublisherGrain>();
            this._rnd = new Random();
        }

        public override Task OnActivateAsync()
        {
            var provider = this.GetStreamProvider("MyProvider");
            this._stream = provider.GetStream<int>(this.GetPrimaryKey(), "MyStream");

            this.RegisterTimer(_ =>
            {
                return _stream.OnNextAsync(this._rnd.Next());
            }, null, TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(2));

            return Task.CompletedTask;
        }
        public Task Publish()
        {
            this._logger.LogInformation("Running tests!");
            return Task.CompletedTask;
        }
    }

So, FireAndForgetDelivery makes sense to ignore exceptions on the caller. However, other providers doesn’t have that option (nor make sense to).

Shouldn’t the stream runtime notify as a Warning that it tried to delivery a message but an exception happened? I know it does that if the consumer grain fail to get activated (i.e. fail on OnActivateAsync()) but not on the processing method…

Any thoughts?

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 21 (21 by maintainers)

Most upvoted comments

I think there is a general acknowledgement of the issue. Team will discuss proper fix. Hopefully we can get it in 2.2, but I can’t commit to release atm.

Resolved via #5230.