Ejemplo n.º 1
0
        internal static ScheduledCommandInterceptor <TAggregate> WithInMemoryDeferredScheduling <TAggregate>(Configuration configuration)
            where TAggregate : class
        {
            return(async(command, next) =>
            {
                var etagStore = configuration.Container.Resolve <InMemoryCommandETagStore>();

                if (!etagStore.TryAdd(scope: command.TargetId, etag: command.Command.ETag))
                {
                    command.Result = new CommandDeduplicated(command, "Schedule");
                }
                else if (command.Result == null)
                {
                    var clock = Clock.Current;

                    command.Result = new CommandScheduled(command, clock);

                    VirtualClock.Schedule(
                        command,
                        command.DueTime ?? Clock.Now().AddTicks(1),
                        (s, c) =>
                    {
                        Domain.CommandScheduler.DeliverImmediatelyOnConfiguredScheduler(c, configuration).Wait();
                        return Disposable.Empty;
                    });
                }

                await next(command);
            });
        }
        /// <summary>
        /// Schedules the specified command.
        /// </summary>
        /// <param name="scheduledCommand">The scheduled command.</param>
        /// <returns>A task that is complete when the command has been successfully scheduled.</returns>
        public async Task Schedule(IScheduledCommand <TAggregate> scheduledCommand)
        {
            var dueTime = scheduledCommand.DueTime;

            var domainNow = Clock.Current.Now();

            if (dueTime == null || dueTime <= domainNow)
            {
                Debug.WriteLine(string.Format("Schedule (applying {1} immediately): @ {0}", domainNow, scheduledCommand.Command.CommandName));

                // schedule immediately
                await Deliver(scheduledCommand);

                return;
            }

            // schedule for later
            VirtualClock.Schedule(scheduledCommand,
                                  dueTime.Value,
                                  (s, command) =>
            {
                try
                {
                    Deliver(command).Wait();
                }
                catch (Exception exception)
                {
                    Console.WriteLine("InMemoryCommandScheduler caught:\n" + exception);
                }

                return(Disposable.Empty);
            });
        }
        /// <summary>
        /// Schedules the specified command.
        /// </summary>
        /// <param name="scheduledCommand">The scheduled command.</param>
        /// <returns>A task that is complete when the command has been successfully scheduled.</returns>
        public async Task Schedule(IScheduledCommand <TAggregate> scheduledCommand)
        {
            var dueTime = scheduledCommand.DueTime;

            var domainNow = Clock.Current.Now();

            if (dueTime == null || dueTime <= domainNow)
            {
                if (!await VerifyPrecondition(scheduledCommand))
                {
                    this.DeliverIfPreconditionIsSatisfiedWithin(
                        TimeSpan.FromSeconds(3),
                        scheduledCommand,
                        Configuration.Current.EventBus);
                }
                else
                {
                    Debug.WriteLine(string.Format("Schedule (applying {1} immediately): @ {0}", domainNow, scheduledCommand.Command.CommandName));

                    resetEvent.Reset();

                    // schedule immediately
                    await Deliver(scheduledCommand);
                }

                return;
            }

            // schedule for later
            VirtualClock.Schedule(scheduledCommand,
                                  dueTime.Value,
                                  (s, command) =>
            {
                resetEvent.Reset();

                try
                {
                    Deliver(command).Wait();
                }
                catch (Exception exception)
                {
                    Console.WriteLine("InMemoryCommandScheduler caught:\n" + exception);
                }

                return(Disposable.Empty);
            });
        }
Ejemplo n.º 4
0
        internal static ScheduledCommandInterceptor <TAggregate> WithInMemoryDeferredScheduling <TAggregate>(Configuration configuration)
            where TAggregate : class, IEventSourced
        {
            return(async(command, next) =>
            {
                if (command.Result == null)
                {
                    command.Result = new CommandScheduled(command);

                    // deliver the command immediately if appropriate
                    if (command.IsDue())
                    {
                        var preconditionVerifier = configuration.Container.Resolve <ICommandPreconditionVerifier>();

                        // sometimes the command depends on a precondition event that hasn't been saved
                        if (!await preconditionVerifier.IsPreconditionSatisfied(command))
                        {
                            Domain.CommandScheduler.DeliverIfPreconditionIsSatisfiedSoon(command, configuration);
                        }
                        else
                        {
                            await Domain.CommandScheduler.DeliverImmediatelyOnConfiguredScheduler(command, configuration);

                            return;
                        }
                    }

                    if (!(command.Result is CommandDelivered))
                    {
                        VirtualClock.Schedule(
                            command,
                            command.DueTime ?? Clock.Now().AddTicks(1),
                            (s, c) =>
                        {
                            Domain.CommandScheduler.DeliverImmediatelyOnConfiguredScheduler(c, configuration).Wait();
                            return Disposable.Empty;
                        });
                    }
                }

                await next(command);
            });
        }