private async Task <ScheduledCommand> StoreScheduledCommand(IScheduledCommand <TAggregate> scheduledCommandEvent)
        {
            ScheduledCommand storedScheduledCommand;

            using (var db = createCommandSchedulerDbContext())
            {
                var domainTime = Domain.Clock.Now();

                // store the scheduled command
                var clockName = await ClockNameForEvent(scheduledCommandEvent, db);

                var schedulerClock = await db.Clocks.SingleOrDefaultAsync(c => c.Name == clockName);

                if (schedulerClock == null)
                {
                    Debug.WriteLine(string.Format("SqlCommandScheduler: Creating clock '{0}' @ {1}", clockName, domainTime));

                    schedulerClock = new Clock
                    {
                        Name      = clockName,
                        UtcNow    = domainTime,
                        StartTime = domainTime
                    };
                    db.Clocks.Add(schedulerClock);
                    await db.SaveChangesAsync();
                }

                storedScheduledCommand = new ScheduledCommand
                {
                    AggregateId       = scheduledCommandEvent.AggregateId,
                    SequenceNumber    = scheduledCommandEvent.SequenceNumber,
                    AggregateType     = eventStreamName,
                    SerializedCommand = scheduledCommandEvent.ToJson(),
                    CreatedTime       = domainTime,
                    DueTime           = scheduledCommandEvent.DueTime,
                    Clock             = schedulerClock
                };

                if (storedScheduledCommand.ShouldBeDeliveredImmediately() &&
                    !scheduledCommandEvent.Command.RequiresDurableScheduling)
                {
                    storedScheduledCommand.NonDurable = true;
                    return(storedScheduledCommand);
                }

                Debug.WriteLine(string.Format("SqlCommandScheduler: Storing command '{0}' ({1}:{2}) on clock '{3}'",
                                              scheduledCommandEvent.Command.CommandName,
                                              scheduledCommandEvent.AggregateId,
                                              scheduledCommandEvent.SequenceNumber,
                                              clockName));

                db.ScheduledCommands.Add(storedScheduledCommand);

                while (true)
                {
                    try
                    {
                        db.SaveChanges();
                        break;
                    }
                    catch (DbUpdateException exception)
                    {
                        if (exception.IsConcurrencyException())
                        {
                            if (storedScheduledCommand.SequenceNumber < 0)
                            {
                                // for scheduler-assigned sequence numbers, decrement and retry
                                storedScheduledCommand.SequenceNumber--;
                            }
                            else
                            {
                                // this is not a scheduler-assigned sequence number, so the concurrency exception indicates an actual issue
                                break;
                            }
                        }
                        else
                        {
                            throw;
                        }
                    }
                }
            }

            return(storedScheduledCommand);
        }
Пример #2
0
        private ScheduledCommand StoreScheduledCommand(IScheduledCommand <TAggregate> scheduledCommandEvent)
        {
            ScheduledCommand storedScheduledCommand;

            using (var db = createCommandSchedulerDbContext())
            {
                var domainTime = Domain.Clock.Now();

                // store the scheduled command
                var clockName      = ClockNameForEvent(scheduledCommandEvent, db);
                var schedulerClock = db.Clocks.SingleOrDefault(c => c.Name == clockName);

                if (schedulerClock == null)
                {
                    schedulerClock = new Clock
                    {
                        Name      = clockName,
                        UtcNow    = domainTime,
                        StartTime = domainTime
                    };
                    db.Clocks.Add(schedulerClock);
                    db.SaveChanges();
                }

                storedScheduledCommand = new ScheduledCommand
                {
                    AggregateId       = scheduledCommandEvent.AggregateId,
                    SequenceNumber    = scheduledCommandEvent.SequenceNumber,
                    AggregateType     = eventStreamName,
                    SerializedCommand = scheduledCommandEvent.ToJson(),
                    CreatedTime       = domainTime,
                    DueTime           = scheduledCommandEvent.DueTime,
                    Clock             = schedulerClock
                };

                if (storedScheduledCommand.ShouldBeDeliveredImmediately() &&
                    !scheduledCommandEvent.Command.RequiresDurableScheduling)
                {
                    storedScheduledCommand.NonDurable = true;
                    return(storedScheduledCommand);
                }

                db.ScheduledCommands.Add(storedScheduledCommand);

                while (true)
                {
                    try
                    {
                        db.SaveChanges();
                        break;
                    }
                    catch (DbUpdateException exception)
                    {
                        if (exception.IsConcurrencyException())
                        {
                            if (storedScheduledCommand.SequenceNumber < 0)
                            {
                                // for scheduler-assigned sequence numbers, decrement and retry
                                storedScheduledCommand.SequenceNumber--;
                            }
                            else
                            {
                                // this is not a scheduler-assigned sequence number, so the concurrency exception indicates
                                break;
                            }
                        }
                        else
                        {
                            throw;
                        }
                    }
                }
            }

            return(storedScheduledCommand);
        }