Ejemplo n.º 1
0
        public async Task OnCommandAsync(ICommand command, CommandContext context, CancellationToken cancellationToken)
        {
            var skip = !IsEnabled ||
                       context.OuterContext != null || // Should be top-level command
                       command is IInvalidateCommand || // Second handler here will take care of it
                       Computed.IsInvalidating();

            if (skip)
            {
                await context.InvokeRemainingHandlersAsync(cancellationToken).ConfigureAwait(false);

                return;
            }

            if (InvalidationInfoProvider.RequiresInvalidation(command))
            {
                context.Items.Set(InvalidateCommand.New(command));
            }

            await context.InvokeRemainingHandlersAsync(cancellationToken).ConfigureAwait(false);

            var invalidate = context.Items.TryGet <IInvalidateCommand>();

            if (invalidate != null)
            {
                await context.Commander.RunAsync(invalidate, true, default).ConfigureAwait(false);
            }
        }
Ejemplo n.º 2
0
 public virtual void OnOperationCompleted(IOperation operation)
 {
     if (operation.AgentId == AgentInfo.Id.Value)
     {
         // Local operations are invalidated by InvalidationHandler
         return;
     }
     if (!(operation.Command is ICommand command))
     {
         return;
     }
     if (!InvalidationInfoProvider.RequiresInvalidation(command))
     {
         return;
     }
     if (Log.IsEnabled(LogLevel.Debug))
     {
         Log.LogDebug("Invalidating operation: agent {0}, command {1}", operation.AgentId, command);
     }
     Commander.Start(InvalidateCommand.New(command, operation), true);
 }
Ejemplo n.º 3
0
        public async Task OnCommandAsync(ICommand command, CommandContext context, CancellationToken cancellationToken)
        {
            var skip = context.OuterContext != null || // Should be top-level command
                       command is IInvalidateCommand || // Second handler here will take care of it
                       Computed.IsInvalidating();

            if (skip)
            {
                await context.InvokeRemainingHandlersAsync(cancellationToken).ConfigureAwait(false);

                return;
            }

            var tScope = typeof(IDbOperationScope <TDbContext>);

            if (context.Items[tScope] != null) // Safety check
            {
                throw Stl.Internal.Errors.InternalError($"'{tScope}' scope is already provided. Duplicate handler?");
            }

            var logEnabled = LogLevel != LogLevel.None && Log.IsEnabled(LogLevel);

            await using var scope = Services.GetRequiredService <IDbOperationScope <TDbContext> >();
            scope.Command         = command;
            context.Items.Set(scope);
            if (logEnabled)
            {
                Log.Log(LogLevel, "+ Operation started: {0}", command);
            }

            IOperation?operation = null;

            try {
                await context.InvokeRemainingHandlersAsync(cancellationToken).ConfigureAwait(false);

                // Building IOperation.Items from CommandContext.Items
                foreach (var(key, value) in context.Items.Items)
                {
                    if (value is IOperationItem)
                    {
                        scope.Items = scope.Items.Set(key, value);
                    }
                }
                operation = await scope.CommitAsync(cancellationToken);

                if (logEnabled)
                {
                    Log.Log(LogLevel, "- Operation succeeded: {0}", command);
                }
            }
            catch (OperationCanceledException) {
                throw;
            }
            catch (Exception e) {
                Log.LogError(e, "! Operation failed: {0}", command);
                try {
                    await scope.RollbackAsync();
                }
                catch {
                    // Intended
                }
                throw;
            }
            if (operation != null)
            {
                if (InvalidationInfoProvider?.RequiresInvalidation(command) ?? false)
                {
                    context.Items.Set(InvalidateCommand.New(command, operation));
                }
                OperationCompletionNotifier?.NotifyCompleted(operation);
            }
        }