Exemple #1
0
        internal async Task Trigger(
            ScheduledCommand scheduled,
            SchedulerAdvancedResult result,
            CommandSchedulerDbContext db)
        {
            var deliver = commandDispatchers.IfContains(scheduled.AggregateType)
                          .ElseDefault();

            if (deliver == null)
            {
                // QUESTION: (Trigger) is this worth raising a warning for or is there a reasonable chance that not registering a handler was deliberate?
                //                var error = ScheduledCommandFailure();
                //
                //                activity.OnNext(new CommandSchedulerActivity(scheduled, error));
                //
                //                result.Add(error);
                //                db.Errors.Add(error);
            }
            else
            {
                await deliver(scheduled);

                result.Add(scheduled.Result);
            }

            scheduled.Attempts++;

            await db.SaveChangesAsync();
        }
        private async Task<SchedulerAdvancedResult> Advance(
            string clockName,
            DateTimeOffset? to = null,
            TimeSpan? by = null,
            Func<IQueryable<ScheduledCommand>, IQueryable<ScheduledCommand>> query = null)
        {
            if (clockName == null)
            {
                throw new ArgumentNullException(nameof(clockName));
            }
            if (to == null && by == null)
            {
                throw new ArgumentException($"Either {nameof(to)} or {nameof(by)} must be specified.");
            }

            using (var db = createCommandSchedulerDbContext())
            {
                var clock = await db.Clocks.SingleOrDefaultAsync(c => c.Name == clockName);

                if (clock == null)
                {
                    throw new ObjectNotFoundException($"No clock named {clockName} was found.");
                }

                to = to ?? clock.UtcNow.Add(by.Value);

                if (to < clock.UtcNow)
                {
                    throw new InvalidOperationException($"A clock cannot be moved backward. ({new { Clock = clock.ToJson(), RequestedTime = to }})");
                }

                var result = new SchedulerAdvancedResult(to.Value);

                clock.UtcNow = to.Value;
                await db.SaveChangesAsync();

                var commands = db.ScheduledCommands
                                 .Due(asOf: to)
                                 .Where(c => c.Clock.Id == clock.Id);

                if (query != null)
                {
                    commands = query(commands);
                }

                // ToArray closes the connection so that when we perform saves during the loop there are no connection errors
                foreach (var scheduled in await commands.ToArrayAsync())
                {
                    await Configuration.Current.DeserializeAndDeliver(scheduled, db);
                    result.Add(scheduled.Result);
                }

                return result;
            }
        }
        private async Task<SchedulerAdvancedResult> Advance(
            string clockName,
            DateTimeOffset? to = null,
            TimeSpan? by = null,
            Func<IQueryable<ScheduledCommand>, IQueryable<ScheduledCommand>> query = null)
        {
            if (clockName == null)
            {
                throw new ArgumentNullException(nameof(clockName));
            }
            if (to == null && by == null)
            {
                throw new ArgumentException($"Either {nameof(to)} or {nameof(by)} must be specified.");
            }

            using (var db = createCommandSchedulerDbContext())
            {
                var clock = await db.Clocks.SingleOrDefaultAsync(c => c.Name == clockName);

                if (clock == null)
                {
                    throw new ObjectNotFoundException($"No clock named {clockName} was found.");
                }

                to = to ?? clock.UtcNow.Add(by.Value);

                if (to < clock.UtcNow)
                {
                    throw new InvalidOperationException($"A clock cannot be moved backward. ({new { Clock = clock.ToJson(), RequestedTime = to }})");
                }

                var result = new SchedulerAdvancedResult(to.Value);

                clock.UtcNow = to.Value;
                await db.SaveChangesAsync();

                var commands = db.ScheduledCommands
                                 .Due(asOf: to)
                                 .Where(c => c.Clock.Id == clock.Id);

                if (query != null)
                {
                    commands = query(commands);
                }

                // ToArray closes the connection so that when we perform saves during the loop there are no connection errors
                foreach (var scheduled in await commands.ToArrayAsync())
                {
                    await Configuration.Current.DeserializeAndDeliver(scheduled, db);
                    result.Add(scheduled.Result);
                }

                return result;
            }
        }