/// <summary>
 /// Updates the state of a command on the server side.
 /// </summary>
 public async Task UpdateCommand(ScheduledCommand command)
 {
     if (Connected)
     {
         await hubConnection.SendAsync("UpdateCommand", new[] { command });
     }
 }
        public override async Task When_a_clock_is_set_on_a_command_then_it_takes_precedence_over_GetClockName()
        {
            // arrange
            var clockName        = Any.CamelCaseName();
            var targetId         = Any.CamelCaseName();
            var command          = new CreateCommandTarget(targetId);
            var scheduledCommand = new ScheduledCommand <CommandTarget>(
                targetId: targetId,
                command: command,
                dueTime: DateTimeOffset.Parse("2016-03-20 09:00:00 AM"))
            {
                Clock = new CommandScheduler.Clock
                {
                    Name   = clockName,
                    UtcNow = DateTimeOffset.Parse("2016-03-01 02:00:00 AM")
                }
            };

            // act
            await scheduler.Schedule(scheduledCommand);

            await Configuration.Current.SchedulerClockTrigger()
            .AdvanceClock(clockName, by: 30.Days());

            //assert
            var target = await store.Get(targetId);

            target.Should().NotBeNull();
        }
        private async Task ServerClient_ServerCommandRecieved(ScheduledCommand command)
        {
            switch (command.Name)
            {
            case "arm":
                await RunRequestedCommand(async() => { return(await Arm()); }, command);

                break;

            case "disarm":
                await RunRequestedCommand(async() => { return(await Disarm()); }, command);

                break;

            case "alarm":
                await RunRequestedCommand(async() => { return(await Alarm()); }, command);

                break;

            case "silence":
                await RunRequestedCommand(async() => { return(await Silence()); }, command);

                break;
            }
        }
        public void A_ScheduledCommand_with_an_non_event_sourced_target_has_a_null_AggregateId()
        {
            var command = new ScheduledCommand <NonEventSourcedCommandTarget>(new NonEventSourcedCommandTarget.TestCommand(),
                                                                              Any.Guid().ToString());

            command.AggregateId.Should().Be(null);
        }
Exemple #5
0
        protected static async Task ScheduleCommandAgainstEventSourcedAggregate(
            string targetId,
            string etag,
            DateTimeOffset?dueTime          = null,
            IPrecondition deliveryDependsOn = null)
        {
            var aggregateId = Guid.Parse(targetId);

            var repository = Configuration.Current.Repository <Order>();

            if (await repository.GetLatest(aggregateId) == null)
            {
                await repository.Save(new Order(new CreateOrder(Any.FullName())
                {
                    AggregateId = aggregateId
                }));
            }

            var command = new AddItem
            {
                ETag        = etag,
                ProductName = Any.Word(),
                Price       = 10m
            };

            var scheduledCommand = new ScheduledCommand <Order>(
                command,
                aggregateId,
                dueTime,
                deliveryDependsOn);

            var scheduler = Configuration.Current.CommandScheduler <Order>();

            await scheduler.Schedule(scheduledCommand);
        }
Exemple #6
0
        public void HandleCommand(ByteReader data)
        {
            ScheduledCommand cmd = ScheduledCommand.Deserialize(data);

            cmd.issuedBySelf = data.ReadBool();
            OnMainThread.ScheduleCommand(cmd);
        }
 /// <summary>
 /// Deserializes a scheduled command from SQL storage and delivers it to the target.
 /// </summary>
 /// <param name="configuration">The configuration.</param>
 /// <param name="serializedCommand">The serialized command.</param>
 /// <param name="db">The command scheduler database context.</param>
 public static async Task DeserializeAndDeliver(
     this Configuration configuration,
     ScheduledCommand serializedCommand,
     CommandSchedulerDbContext db) =>
 await DeserializeAndDeliver(
     configuration.Container.Resolve <CommandDelivererResolver>(),
     serializedCommand,
     db);
Exemple #8
0
 public static Map GetMap(this ScheduledCommand cmd)
 {
     if (cmd.mapId == ScheduledCommand.Global)
     {
         return(null);
     }
     return(Find.Maps.Find(map => map.uniqueID == cmd.mapId));
 }
Exemple #9
0
 public static Faction GetFaction(this ScheduledCommand cmd)
 {
     if (cmd.factionId == ScheduledCommand.NoFaction)
     {
         return(null);
     }
     return(Find.FactionManager.GetById(cmd.factionId));
 }
        public void HandleCommand(ByteReader data)
        {
            ScheduledCommand cmd = ScheduledCommand.Deserialize(data);

            cmd.issuedBySelf = data.ReadBool();
            OnMainThread.ScheduleCommand(cmd);
            Multiplayer.session.localCmdId++;
            Multiplayer.session.ProcessTimeControl();
        }
        public void HandleWorldData(ByteReader data)
        {
            connection.State = ConnectionStateEnum.ClientPlaying;
            Log.Message("Game data size: " + data.Length);

            int factionId = data.ReadInt32();

            Multiplayer.session.myFactionId = factionId;

            int tickUntil = data.ReadInt32();

            byte[] worldData = GZipStream.UncompressBuffer(data.ReadPrefixedBytes());
            OnMainThread.cachedGameData = worldData;

            List <int> mapsToLoad = new List <int>();

            int mapCmdsCount = data.ReadInt32();

            for (int i = 0; i < mapCmdsCount; i++)
            {
                int mapId = data.ReadInt32();

                int mapCmdsLen = data.ReadInt32();
                List <ScheduledCommand> mapCmds = new List <ScheduledCommand>(mapCmdsLen);
                for (int j = 0; j < mapCmdsLen; j++)
                {
                    mapCmds.Add(ScheduledCommand.Deserialize(new ByteReader(data.ReadPrefixedBytes())));
                }

                OnMainThread.cachedMapCmds[mapId] = mapCmds;
            }

            int mapDataCount = data.ReadInt32();

            for (int i = 0; i < mapDataCount; i++)
            {
                int    mapId      = data.ReadInt32();
                byte[] rawMapData = data.ReadPrefixedBytes();

                byte[] mapData = GZipStream.UncompressBuffer(rawMapData);
                OnMainThread.cachedMapData[mapId] = mapData;
                mapsToLoad.Add(mapId);
            }

            Multiplayer.session.localCmdId = data.ReadInt32();

            TickPatch.tickUntil = tickUntil;

            TickPatch.SkipTo(
                toTickUntil: true,
                onFinish: () => Multiplayer.Client.Send(Packets.Client_WorldReady),
                cancelButtonKey: "Quit",
                onCancel: GenScene.GoToMainMenu
                );

            ReloadGame(mapsToLoad);
        }
        protected void AddScheduledCommand(ScheduledCommand command)
        {
            if (command == null)
            {
                throw new ArgumentNullException(nameof(command));
            }

            _pendingScheduledCommands.Add(command);
        }
Exemple #13
0
        public Task UpdateCommand(ScheduledCommand command)
        {
            using (IServiceScope scope = _serviceProvider.CreateScope())
            {
                ApplicationDbContext _context = scope.ServiceProvider.GetRequiredService <ApplicationDbContext>();

                CommandStatusUpdated?.Invoke(command, _context);
                return(Task.CompletedTask);
            }
        }
Exemple #14
0
        internal static ScheduledCommand ToScheduledCommand(this PersistedScheduledCommand instance)
        {
            var result = new ScheduledCommand();

            result.CommandName = instance.CommandName;
            result.Data        = instance.Data;
            result.ExecuteTime = instance.ExecuteTime;

            return(result);
        }
Exemple #15
0
        public static byte[] SerializeCmds(List <ScheduledCommand> cmds)
        {
            ByteWriter writer = new ByteWriter();

            writer.WriteInt32(cmds.Count);
            foreach (var cmd in cmds)
            {
                writer.WritePrefixedBytes(ScheduledCommand.Serialize(cmd));
            }

            return(writer.ToArray());
        }
Exemple #16
0
        public async Task Multiple_scheduled_commands_having_the_some_causative_command_etag_have_repeatable_and_unique_etags()
        {
            var senderId = Any.Word();
            await store.Put(new CommandTarget(senderId));

            var targetIds = new[] { Any.Word(), Any.Word(), Any.Word() };

            var results = new ConcurrentBag <RequestReply>();

            configuration.TraceScheduledCommands(
                onScheduling: cmd =>
            {
                var requestReply = ((dynamic)cmd).Command as RequestReply;
                if (requestReply != null)
                {
                    results.Add(requestReply);
                }
            });


            var initialEtag = "initial".ToETag();

            var firstCommand = new SendRequests(targetIds)
            {
                ETag = initialEtag
            };

            var scheduledCommand = new ScheduledCommand <CommandTarget>(
                firstCommand,
                senderId);

            await scheduler.Deliver(scheduledCommand);

            var secondCommand = new SendRequests(targetIds)
            {
                ETag = initialEtag
            };

            scheduledCommand = new ScheduledCommand <CommandTarget>(
                secondCommand,
                senderId);

            // redeliver
            await scheduler.Deliver(scheduledCommand);

            Console.WriteLine(results.ToJson());

            results.Should().HaveCount(6);
            results.Select(r => r.ETag)
            .Distinct()
            .Should()
            .HaveCount(3);
        }
        public async Task Multiple_scheduled_commands_having_the_some_causative_command_etag_have_repeatable_and_unique_etags()
        {
            var senderId = Any.Word();

            await Save(new NonEventSourcedCommandTarget(senderId));

            var targetIds = new[] { Any.Word(), Any.Word(), Any.Word() };

            var results = new ConcurrentBag<RequestReply>();

            Configuration.Current
                         .TraceScheduledCommands(
                             onScheduling: cmd =>
                             {
                                 var requestReply = ((dynamic) cmd).Command as RequestReply;
                                 if (requestReply != null)
                                 {
                                     results.Add(requestReply);
                                 }
                             });

            var initialEtag = "initial".ToETag();

            var firstCommand = new SendRequests(targetIds)
                               {
                                   ETag = initialEtag
                               };

            var scheduledCommand = new ScheduledCommand<NonEventSourcedCommandTarget>(
                firstCommand,
                senderId);

            await Deliver(scheduledCommand);

            var secondCommand = new SendRequests(targetIds)
                                {
                                    ETag = initialEtag
                                };

            scheduledCommand = new ScheduledCommand<NonEventSourcedCommandTarget>(
                secondCommand,
                senderId);

            // redeliver
            await Deliver(scheduledCommand);

            results.Should().HaveCount(6);
            results.Select(r => r.ETag)
                   .Distinct()
                   .Should()
                   .HaveCount(3);
        }
        /// <summary>
        /// Append the data for the given command in a somewhat readable form to the provided string builder
        /// </summary>
        /// <param name="builder">The builder to append data to</param>
        /// <param name="cmd">The command to append</param>
        private static void PrintCmdInfo(StringBuilder builder, ScheduledCommand cmd)
        {
            //Add basic data
            builder.Append($"{cmd.type} {cmd.ticks} {cmd.mapId} {cmd.factionId}");

            //If this is a sync command, add data on the handler used.
            if (cmd.type == CommandType.Sync)
            {
                builder.Append($" {Sync.handlers[BitConverter.ToInt32(cmd.data, 0)]}");
            }

            builder.AppendLine();
        }
Exemple #19
0
        public void AddScheduledCommand_adds_envelope()
        {
            ProcessManager sut = Mock.Of <ProcessManager>();
            MethodInfo     mut = typeof(ProcessManager).GetMethod(
                "AddScheduledCommand", BindingFlags.NonPublic | BindingFlags.Instance);
            var scheduledCommand = new ScheduledCommand(new object(), DateTime.UtcNow);

            mut.Invoke(sut, new[] { scheduledCommand });

            IEnumerable <ScheduledCommand> actual = sut.FlushPendingScheduledCommands();

            actual.Should().ContainSingle().Which.Should().BeSameAs(scheduledCommand);
        }
Exemple #20
0
        /// <summary>
        /// Updates a command in the database with new
        /// State and Result enum values.
        /// </summary>
        /// <param name="commands">ScheduledCommand to update. GUIDs must match.</param>
        public async Task SetScheduledCommands(ScheduledCommand command)
        {
            using (IServiceScope scope = _provider.CreateScope())
            {
                ApplicationDbContext _context = scope.ServiceProvider.GetRequiredService <ApplicationDbContext>();

                ScheduledCommand dbCommand = await _context.ScheduledCommands.Select(s => s).Where(p => (p.Id == command.Id)).FirstAsync();

                dbCommand.State  = command.State;
                dbCommand.Result = command.Result;
                _context.ScheduledCommands.Update(dbCommand);
                await _context.SaveChangesAsync();
            }
        }
Exemple #21
0
        private List <ScheduledCommand> DeserializeCmds(byte[] data)
        {
            var reader = new ByteReader(data);

            int count  = reader.ReadInt32();
            var result = new List <ScheduledCommand>(count);

            for (int i = 0; i < count; i++)
            {
                result.Add(ScheduledCommand.Deserialize(new ByteReader(reader.ReadPrefixedBytes())));
            }

            return(result);
        }
Exemple #22
0
        private static async Task DeserializeAndDeliver(
            CommandSchedulerResolver schedulerResolver,
            ScheduledCommand serializedCommand,
            CommandSchedulerDbContext db)
        {
            dynamic scheduler = schedulerResolver.ResolveSchedulerForAggregateTypeNamed(serializedCommand.AggregateType);

            await Storage.DeserializeAndDeliverScheduledCommand(
                serializedCommand,
                scheduler);

            serializedCommand.Attempts++;

            await db.SaveChangesAsync();
        }
Exemple #23
0
        /// <summary>
        /// Pushes a single command to the controller from the server side.
        /// Always called when a command is being executed on a live connection.
        /// </summary>
        private async Task PushCommandToController(CabinetController controller, ScheduledCommand command)
        {
            // Don't send if the controller is offline!
            if (!ValidateController(controller))
            {
                throw new Exception("The controller is not connected to the hub!");
            }

            if (command.State != CommandState.Scheduled)
            {
                throw new Exception("Command is in an incorrect state. It may be invalid or have completed already.");
            }

            await _hub.Clients.Client(controller.HubConnectionId)?.SendCoreAsync("RecieveCommand", new[] { command });
        }
Exemple #24
0
 public async Task ScheduleCommand(ScheduledCommand command)
 {
     try
     {
         await ScheduledCommands.InsertOneAsync(command);
     }
     catch (MongoBulkWriteException ex)
     {
         if (ex.WriteErrors.All(x => x.Category == ServerErrorCategory.DuplicateKey))
         {
             return;
         }
         throw;
     }
 }
Exemple #25
0
        public void AddScheduledCommand_appends_envelope()
        {
            ProcessManager sut = Mock.Of <ProcessManager>();
            MethodInfo     mut = typeof(ProcessManager).GetMethod(
                "AddScheduledCommand", BindingFlags.NonPublic | BindingFlags.Instance);
            var existingScheduledCommand = new ScheduledCommand(new object(), DateTime.UtcNow);

            mut.Invoke(sut, new[] { existingScheduledCommand });
            var scheduledCommand = new ScheduledCommand(new object(), DateTime.UtcNow);

            mut.Invoke(sut, new[] { scheduledCommand });

            IEnumerable <ScheduledCommand> actual = sut.FlushPendingScheduledCommands();

            actual.Should().HaveCount(2).And.HaveElementAt(1, scheduledCommand);
        }
 public async Task ScheduleCommand(ScheduledCommand command)
 {
     try
     {
         using (var db = ConstructDbContext())
         {
             var persistable = command.ToPersistable();
             var result      = db.Set <PersistedScheduledCommand>().Add(persistable);
             await db.SaveChangesAsync();
         }
     }
     catch (DbUpdateException)
     {
         //log
     }
 }
        /// <summary>
        /// Handles a command from the server.
        /// </summary>
        private async Task HandleCommand(ScheduledCommand command)
        {
            // Update the server state of the command
            command.State = CommandState.InProgress;
            await UpdateCommand(command);

            switch (command.Name)
            {
            case "arm":
                await ServerCommandRecieved.Invoke(command);

                break;

            case "disarm":
                await ServerCommandRecieved.Invoke(command);

                break;

            case "alarm":
                await ServerCommandRecieved.Invoke(command);

                break;

            case "silence":
                await ServerCommandRecieved.Invoke(command);

                break;

            case "clientDelete":
                command.State  = CommandState.Complete;
                command.Result = CommandResult.Success;
                await UpdateCommand(command);
                await Unenroll();

                break;

            default:
                // Command is invalid.
                command.State  = CommandState.Complete;
                command.Result = CommandResult.Invalid;
                await UpdateCommand(command);

                break;
            }
        }
Exemple #28
0
        public static void ScheduleCommand(ScheduledCommand cmd)
        {
            MpLog.Log($"Cmd: {cmd.type}, faction: {cmd.factionId}, map: {cmd.mapId}, ticks: {cmd.ticks}");
            cachedMapCmds.GetOrAddNew(cmd.mapId).Add(cmd);

            if (Current.ProgramState != ProgramState.Playing)
            {
                return;
            }

            if (cmd.mapId == ScheduledCommand.Global)
            {
                Multiplayer.WorldComp.cmds.Enqueue(cmd);
            }
            else
            {
                cmd.GetMap()?.AsyncTime().cmds.Enqueue(cmd);
            }
        }
Exemple #29
0
        public void HandleMapResponse(ByteReader data)
        {
            int mapId = data.ReadInt32();

            int mapCmdsLen = data.ReadInt32();
            List <ScheduledCommand> mapCmds = new List <ScheduledCommand>(mapCmdsLen);

            for (int j = 0; j < mapCmdsLen; j++)
            {
                mapCmds.Add(ScheduledCommand.Deserialize(new ByteReader(data.ReadPrefixedBytes())));
            }

            OnMainThread.cachedMapCmds[mapId] = mapCmds;

            byte[] mapData = GZipStream.UncompressBuffer(data.ReadPrefixedBytes());
            OnMainThread.cachedMapData[mapId] = mapData;

            //ClientJoiningState.ReloadGame(TickPatch.tickUntil, Find.Maps.Select(m => m.uniqueID).Concat(mapId).ToList());
            // todo Multiplayer.client.Send(Packets.CLIENT_MAP_LOADED);
        }
Exemple #30
0
        /// <summary>
        /// Queues a new command with the cabinet management controller (CMC).
        /// </summary>
        /// <param name="command">The command to send to the controller.</param>
        /// <param name="data">Additional data to send with the command.</param>
        public async Task <ScheduledCommand> SendCommandToController(string command, IDictionary <string, dynamic> data = null)
        {
            ScheduledCommand scheduledCommand = new ScheduledCommand()
            {
                ControllerId = controller.Id,
                Name         = command,
                UserId       = CurrentUserId,
                Payload      = data,
                State        = CommandState.Scheduled,
                Result       = CommandResult.None,
                TimeCreated  = DateTime.Now,
            };

            await _context.ScheduledCommands.AddAsync(scheduledCommand);

            await _context.SaveChangesAsync();

            await PushCommandToController(controller, scheduledCommand);

            return(scheduledCommand);
        }
        public async Task <IActionResult> Post(Guid id, [FromBody] ScheduledCommand _scheduledCommand)
        {
            CabinetController cabinetController = await GetController(id);

            if (cabinetController == null)
            {
                return(GetCommandError(_scheduledCommand, ErrorStrings.ControllerNotFound));
            }

            // Make sure the controller is online
            ControllerProxy proxy = GetControllerProxy(cabinetController);

            if (!proxy.ValidateController(cabinetController))
            {
                return(GetCommandError(_scheduledCommand, ErrorStrings.ControllerOffline));
            }

            // Send the command to the proxy
            ScheduledCommand command = await proxy.SendCommandToController(_scheduledCommand.Name, _scheduledCommand.Payload);

            return(new JsonResult(command));
        }
        public async Task Multiple_scheduled_commands_having_the_some_causative_command_etag_have_repeatable_and_unique_etags()
        {
            var id = Any.Word();
            await store.Put(new CommandTarget(id));

            var command = new SendRequests(new[] { Any.Word() })
            {
                ETag = "one".ToETag()
            };

            var scheduled = new ScheduledCommand<CommandTarget>(
                command, 
                id);

            await scheduler.Deliver(scheduled);

            Assert.Fail("Test not written yet.");
        }
        protected static async Task ScheduleCommandAgainstEventSourcedAggregate(
            string targetId,
            string etag,
            DateTimeOffset? dueTime = null,
            IPrecondition deliveryDependsOn = null)
        {
            var aggregateId = Guid.Parse(targetId);

            var repository = Configuration.Current.Repository<Order>();

            if (await repository.GetLatest(aggregateId) == null)
            {
                await repository.Save(new Order(new CreateOrder(Any.FullName())
                {
                    AggregateId = aggregateId
                }));
            }

            var command = new AddItem
            {
                ETag = etag,
                ProductName = Any.Word(),
                Price = 10m
            };

            var scheduledCommand = new ScheduledCommand<Order>(
                command,
                aggregateId,
                dueTime,
                deliveryDependsOn);

            var scheduler = Configuration.Current.CommandScheduler<Order>();

            await scheduler.Schedule(scheduledCommand);
        }
        protected async Task ScheduleCommandAgainstNonEventSourcedAggregate(
            string targetId,
            string etag,
            DateTimeOffset? dueTime = null,
            IPrecondition deliveryDependsOn = null)
        {
            var repository = Configuration.Current.Store<CommandTarget>();

            if (await repository.Get(targetId) == null)
            {
                await repository.Put(new CommandTarget(targetId));
            }

            var command = new ScheduledCommand<CommandTarget>(
                new TestCommand(etag),
                targetId,
                dueTime,
                deliveryDependsOn);

            var scheduler = Configuration.Current.CommandScheduler<CommandTarget>();

            await scheduler.Schedule(command);
        }