示例#1
0
        private async Task <bool> DispatchProjection(ProjectionDescriptor projection, MessageEnvelope envelope, ProjectingContext context)
        {
            while (true)
            {
                try
                {
                    await TryDispatch(projection, envelope, context).NotOnCapturedContext();

                    return(true);
                }
                catch (ProjectingException ex)
                {
                    ProjectingError(ex);
                    if (context.ExceptionSolution == ExceptionSolutions.Ignore)
                    {
                        return(true);
                    }
                    if (context.ExceptionSolution == ExceptionSolutions.Drop)
                    {
                        projection.Drop();
                        return(false);
                    }
                    if (!context.CanRetry())
                    {
                        projection.Drop();
                        throw;
                    }
                    context.NextRetry();
                }
            }
        }
示例#2
0
 public ProjectingException(ProjectionDescriptor descriptor, MessageEnvelope envelope, ProjectingContext context, Exception exception)
     : base($"Projecting '{descriptor.ContractName}' with message '{envelope.Meta.MessageContractName}' exception.", exception)
 {
     Descriptor = descriptor;
     Envelope   = envelope;
     Context    = context;
 }
 private DispatchingResult(ProjectionDescriptor descriptor, Statuses status, int envelopesCount, long elapsedMilliseconds, bool anyDispatched, Exception exception = null)
     : this(descriptor, status)
 {
     EnvelopesCount      = envelopesCount;
     ElapsedMilliseconds = elapsedMilliseconds;
     AnyDispatched       = anyDispatched;
     Exception           = exception;
 }
示例#4
0
 private async Task TryDispatch(ProjectionDescriptor descriptor, MessageEnvelope envelope, ProjectingContext context)
 {
     try
     {
         var instance = ProjectionFactory.CreateProjectionInstance(descriptor.ProjectionType);
         if (instance == null)
         {
             throw new NullReferenceException($"Projection instance {descriptor.ProjectionType.FullName} is null.");
         }
         await descriptor.Invoke(instance, envelope.Message, envelope.Meta, context);
     }
     catch (Exception e)
     {
         throw new ProjectingException(descriptor, envelope, context, e);
     }
 }
示例#5
0
        private async Task <DispatchingResult> Dispatch(ProjectionDescriptor descriptor, List <MessageEnvelope> envelopes, CancellationToken token)
        {
            if (descriptor.IsDropped())
            {
                return(DispatchingResult.StillDropped(descriptor));
            }

            var sw            = new Stopwatch();
            var context       = new ProjectingContext(MaxProjectingRetries, descriptor.Checkpoint.Position);
            var anyDispatched = false;

            try
            {
                sw.Start();
                using (var scope = this.NewTransactionScope())
                {
                    foreach (var envelope in envelopes)
                    {
                        if (!descriptor.CanDispatch(envelope.Message.GetType(), envelope.Meta.MessagePosition))
                        {
                            continue;
                        }

                        context.Reset();
                        if (await DispatchProjection(descriptor, envelope, context).NotOnCapturedContext())
                        {
                            descriptor.Checkpoint.Position = envelope.Meta.MessagePosition;
                            anyDispatched = true;
                        }
                    }

                    await UpdateCheckpoint(descriptor.Checkpoint, descriptor.UndropRequested, token).NotOnCapturedContext();

                    scope.Complete();
                }
                sw.Stop();
                return(DispatchingResult.Dispatched(descriptor, envelopes.Count, sw.ElapsedMilliseconds, anyDispatched));
            }
            catch (Exception e) // error in batch
            {
                sw.Stop();
                descriptor.Checkpoint.Position = context.StartingBatchAtPosition; // restoring position
                await UpdateCheckpoint(descriptor.Checkpoint, descriptor.UndropRequested, token).NotOnCapturedContext();

                return(DispatchingResult.DroppedOnException(descriptor, envelopes.Count, sw.ElapsedMilliseconds, e));
            }
        }
示例#6
0
 public DispatchingContext(ProjectionDescriptor descriptor, List <MessageEnvelope> envelopes)
 {
     Descriptor = descriptor;
     Envelopes  = envelopes;
 }
 private DispatchingResult(ProjectionDescriptor descriptor, Statuses status)
 {
     Descriptor = descriptor;
     Status     = status;
 }
 internal static DispatchingResult DroppedOnException(ProjectionDescriptor descriptor, int envelopesCount, long elapsedMilliseconds, Exception exception)
 {
     return(new DispatchingResult(descriptor, Statuses.DroppedOnException, envelopesCount, elapsedMilliseconds, false, exception));
 }
 internal static DispatchingResult Dispatched(ProjectionDescriptor descriptor, int envelopesCount, long elapsedMilliseconds, bool anyDispatched)
 {
     return(new DispatchingResult(descriptor, Statuses.Dispatched, envelopesCount, elapsedMilliseconds, anyDispatched));
 }
 internal static DispatchingResult StillDropped(ProjectionDescriptor descriptor) => new DispatchingResult(descriptor, Statuses.StillDropped);