Ejemplo n.º 1
0
        public async Task HandleAsync(CommandContext context, NextDelegate next)
        {
            var logContext = (id : context.ContextId.ToString(), command : context.Command.GetType().Name);

            try
            {
                log.LogDebug(logContext, (ctx, w) => w
                             .WriteProperty("action", "HandleCommand.")
                             .WriteProperty("actionId", ctx.id)
                             .WriteProperty("status", "Started")
                             .WriteProperty("commandType", ctx.command));

                using (log.MeasureInformation(logContext, (ctx, w) => w
                                              .WriteProperty("action", "HandleCommand.")
                                              .WriteProperty("actionId", ctx.id)
                                              .WriteProperty("status", "Completed")
                                              .WriteProperty("commandType", ctx.command)))
                {
                    await next(context);
                }

                log.LogInformation(logContext, (ctx, w) => w
                                   .WriteProperty("action", "HandleCommand.")
                                   .WriteProperty("actionId", ctx.id)
                                   .WriteProperty("status", "Succeeded")
                                   .WriteProperty("commandType", ctx.command));
            }
            catch (Exception ex)
            {
                log.LogError(ex, logContext, (ctx, w) => w
                             .WriteProperty("action", "HandleCommand.")
                             .WriteProperty("actionId", ctx.id)
                             .WriteProperty("status", "Failed")
                             .WriteProperty("commandType", ctx.command));

                throw;
            }

            if (!context.IsCompleted)
            {
                log.LogFatal(logContext, (ctx, w) => w
                             .WriteProperty("action", "HandleCommand.")
                             .WriteProperty("actionId", ctx.id)
                             .WriteProperty("status", "Unhandled")
                             .WriteProperty("commandType", ctx.command));
            }
        }
Ejemplo n.º 2
0
        private async Task HandleAsync(SchedulerBatch <T> document)
        {
            var canRetry = document.RetryCount < schedulerOptions.ExecutionRetries.Length;

            try
            {
                if (currentHandler != null)
                {
                    using (var timeout = new CancellationTokenSource(schedulerOptions.Timeout))
                    {
                        await currentHandler.HandleAsync(document.Jobs, !canRetry, timeout.Token);
                    }
                }

                await schedulerStore.CompleteAsync(document.Id);
            }
            catch (Exception ex)
            {
                log.LogError(ex, w => w
                             .WriteProperty("action", "HandleJob")
                             .WriteProperty("status", "Failed"));

                if (canRetry)
                {
                    var wait = Duration.FromMilliseconds(schedulerOptions.ExecutionRetries[document.RetryCount]);

                    var nextTime = document.DueTime.Plus(wait);

                    await schedulerStore.RetryAsync(document.Id, nextTime);
                }
                else if (currentHandler != null)
                {
                    try
                    {
                        await currentHandler.HandleExceptionAsync(document.Jobs, ex);
                    }
                    catch (Exception ex2)
                    {
                        log.LogFatal(ex2, w => w
                                     .WriteProperty("action", "HandleJobException")
                                     .WriteProperty("status", "Failed"));
                    }
                }
            }
        }
Ejemplo n.º 3
0
        public async Task HandleAsync(CommandContext context, Func <Task> next)
        {
            try
            {
                log.LogInformation(w => w
                                   .WriteProperty("action", "HandleCommand.")
                                   .WriteProperty("actionId", context.ContextId.ToString())
                                   .WriteProperty("status", "Started")
                                   .WriteProperty("commandType", context.Command.GetType().Name));

                using (log.MeasureInformation(w => w
                                              .WriteProperty("action", "HandleCommand.")
                                              .WriteProperty("actionId", context.ContextId.ToString())
                                              .WriteProperty("status", "Completed")
                                              .WriteProperty("commandType", context.Command.GetType().Name)))
                {
                    await next();
                }

                log.LogInformation(w => w
                                   .WriteProperty("action", "HandleCommand.")
                                   .WriteProperty("actionId", context.ContextId.ToString())
                                   .WriteProperty("status", "Succeeded")
                                   .WriteProperty("commandType", context.Command.GetType().Name));
            }
            catch (Exception ex)
            {
                log.LogError(ex, w => w
                             .WriteProperty("action", "HandleCommand.")
                             .WriteProperty("actionId", context.ContextId.ToString())
                             .WriteProperty("status", "Failed")
                             .WriteProperty("commandType", context.Command.GetType().Name));

                throw;
            }

            if (!context.IsCompleted)
            {
                log.LogFatal(w => w
                             .WriteProperty("action", "HandleCommand.")
                             .WriteProperty("actionId", context.ContextId.ToString())
                             .WriteProperty("status", "Unhandled")
                             .WriteProperty("commandType", context.Command.GetType().Name));
            }
        }
Ejemplo n.º 4
0
        private void Stop(Exception ex, IEventConsumer eventConsumer)
        {
            foreach (var block in blocks)
            {
                block.Stop();
            }

            try
            {
                eventConsumerInfoRepository.StopAsync(eventConsumer.Name, ex.ToString()).Wait();
            }
            catch (Exception ex2)
            {
                log.LogFatal(ex2, w => w
                             .WriteProperty("action", "StopConsumer")
                             .WriteProperty("state", "Failed"));
            }
        }
Ejemplo n.º 5
0
        public Task <bool> HandleAsync(CommandContext context)
        {
            var exception = context.Exception;

            if (exception != null)
            {
                log.LogError(exception, w => w
                             .WriteProperty("action", "HandleCommand.")
                             .WriteProperty("actionId", context.ContextId.ToString())
                             .WriteProperty("state", "Failed")
                             .WriteProperty("commandType", context.Command.GetType().Name));
            }

            if (!context.IsHandled)
            {
                log.LogFatal(exception, w => w
                             .WriteProperty("action", "HandleCommand.")
                             .WriteProperty("actionId", context.ContextId.ToString())
                             .WriteProperty("state", "Unhandled")
                             .WriteProperty("commandType", context.Command.GetType().Name));
            }

            return(TaskHelper.False);
        }
Ejemplo n.º 6
0
        private async Task HandleAsync(Envelope <IEvent> input)
        {
            var eventNumber = input.Headers.EventNumber();

            if (eventNumber <= lastReceivedEventNumber || !isRunning)
            {
                return;
            }

            try
            {
                await eventConsumerInfoRepository.SetLastHandledEventNumberAsync(eventConsumer.Name, eventNumber);
            }
            catch (Exception ex)
            {
                OnError?.Invoke(ex);

                log.LogFatal(ex, w => w
                             .WriteProperty("action", "UpdateState")
                             .WriteProperty("state", "Failed")
                             .WriteProperty("eventId", input.Headers.EventId().ToString())
                             .WriteProperty("eventNumber", input.Headers.EventNumber()));
            }
        }
Ejemplo n.º 7
0
        public async Task MigrateAsync(CancellationToken ct = default)
        {
            var version = 0;

            try
            {
                while (!await migrationStatus.TryLockAsync())
                {
                    log.LogInformation(w => w
                                       .WriteProperty("action", "Migrate")
                                       .WriteProperty("mesage", $"Waiting {LockWaitMs}ms to acquire lock."));

                    await Task.Delay(LockWaitMs, ct);
                }

                version = await migrationStatus.GetVersionAsync();

                while (!ct.IsCancellationRequested)
                {
                    var(newVersion, migrations) = migrationPath.GetNext(version);

                    if (migrations == null || !migrations.Any())
                    {
                        break;
                    }

                    foreach (var migration in migrations)
                    {
                        var name = migration.GetType().ToString();

                        log.LogInformation(w => w
                                           .WriteProperty("action", "Migration")
                                           .WriteProperty("status", "Started")
                                           .WriteProperty("migrator", name));

                        try
                        {
                            using (log.MeasureInformation(w => w
                                                          .WriteProperty("action", "Migration")
                                                          .WriteProperty("status", "Completed")
                                                          .WriteProperty("migrator", name)))
                            {
                                await migration.UpdateAsync();
                            }
                        }
                        catch (Exception ex)
                        {
                            log.LogFatal(ex, w => w
                                         .WriteProperty("action", "Migration")
                                         .WriteProperty("status", "Failed")
                                         .WriteProperty("migrator", name));

                            throw new MigrationFailedException(name, ex);
                        }
                    }

                    version = newVersion;
                }
            }
            finally
            {
                await migrationStatus.UnlockAsync(version);
            }
        }
Ejemplo n.º 8
0
        private async Task OnMessage(object message)
        {
            if (isStopped)
            {
                return;
            }

            try
            {
                var oldStateId = stateId;
                var newStateId = stateId = Guid.NewGuid();

                switch (message)
                {
                case Teardown teardown:
                {
                    isStopped = true;

                    return;
                }

                case Setup setup:
                {
                    eventConsumer = setup.EventConsumer;

                    var status = await eventConsumerInfoRepository.FindAsync(eventConsumer.Name);

                    if (status != null)
                    {
                        statusError     = status.Error;
                        statusPosition  = status.Position;
                        statusIsRunning = !status.IsStopped;
                    }

                    if (statusIsRunning)
                    {
                        await SubscribeThisAsync(statusPosition);
                    }

                    break;
                }

                case StartConsumerMessage startConsumer:
                {
                    if (statusIsRunning)
                    {
                        return;
                    }

                    await SubscribeThisAsync(statusPosition);

                    statusError     = null;
                    statusIsRunning = true;

                    break;
                }

                case StopConsumerMessage stopConsumer:
                {
                    if (!statusIsRunning)
                    {
                        return;
                    }

                    await UnsubscribeThisAsync();

                    statusIsRunning = false;

                    break;
                }

                case ResetConsumerMessage resetConsumer:
                {
                    await UnsubscribeThisAsync();
                    await ClearAsync();
                    await SubscribeThisAsync(null);

                    statusError     = null;
                    statusPosition  = null;
                    statusIsRunning = true;

                    break;
                }

                case Reconnect reconnect:
                {
                    if (!statusIsRunning || reconnect.StateId != oldStateId)
                    {
                        return;
                    }

                    await SubscribeThisAsync(statusPosition);

                    break;
                }

                case SubscriptionFailed subscriptionFailed:
                {
                    if (subscriptionFailed.Subscription != eventSubscription)
                    {
                        return;
                    }

                    await UnsubscribeThisAsync();

                    if (retryWindow.CanRetryAfterFailure())
                    {
                        Task.Delay(ReconnectWaitMs).ContinueWith(t => dispatcher.SendAsync(new Reconnect {
                                StateId = newStateId
                            })).Forget();
                    }
                    else
                    {
                        throw subscriptionFailed.Exception;
                    }

                    break;
                }

                case SubscriptionEventReceived eventReceived:
                {
                    if (eventReceived.Subscription != eventSubscription)
                    {
                        return;
                    }

                    var @event = ParseEvent(eventReceived.Event);

                    await DispatchConsumerAsync(@event);

                    statusError    = null;
                    statusPosition = @eventReceived.Event.EventPosition;

                    break;
                }
                }

                await eventConsumerInfoRepository.SetAsync(eventConsumer.Name, statusPosition, !statusIsRunning, statusError);
            }
            catch (Exception ex)
            {
                try
                {
                    await UnsubscribeThisAsync();
                }
                catch (Exception unsubscribeException)
                {
                    ex = new AggregateException(ex, unsubscribeException);
                }

                log.LogFatal(ex, w => w
                             .WriteProperty("action", "HandleEvent")
                             .WriteProperty("state", "Failed")
                             .WriteProperty("eventConsumer", eventConsumer.Name));

                statusError     = ex.ToString();
                statusIsRunning = false;

                await eventConsumerInfoRepository.SetAsync(eventConsumer.Name, statusPosition, !statusIsRunning, statusError);
            }
        }
Ejemplo n.º 9
0
        public async Task MigrateAsync(
            CancellationToken ct = default)
        {
            if (!await TryLockAsync(ct))
            {
                return;
            }

            try
            {
                var version = await migrationStatus.GetVersionAsync(ct);

                while (!ct.IsCancellationRequested)
                {
                    var(newVersion, migrations) = migrationPath.GetNext(version);

                    if (migrations == null || !migrations.Any())
                    {
                        break;
                    }

                    foreach (var migration in migrations)
                    {
                        var name = migration.ToString() !;

                        log.LogInformation(w => w
                                           .WriteProperty("action", "Migration")
                                           .WriteProperty("status", "Started")
                                           .WriteProperty("migrator", name));

                        try
                        {
                            using (log.MeasureInformation(w => w
                                                          .WriteProperty("action", "Migration")
                                                          .WriteProperty("status", "Completed")
                                                          .WriteProperty("migrator", name)))
                            {
                                await migration.UpdateAsync(ct);
                            }
                        }
                        catch (Exception ex)
                        {
                            log.LogFatal(ex, w => w
                                         .WriteProperty("action", "Migration")
                                         .WriteProperty("status", "Failed")
                                         .WriteProperty("migrator", name));

                            throw new MigrationFailedException(name, ex);
                        }
                    }

                    version = newVersion;

                    await migrationStatus.CompleteAsync(newVersion, ct);
                }
            }
            finally
            {
                await UnlockAsync();
            }
        }