private void CheckForDeletedSimulation(Services.Models.Simulation newSimulation)
 {
     if (newSimulation == null && this.simulation != null)
     {
         this.runner.Stop();
         this.simulation = null;
         this.log.Info("No simulation found in storage...", () => { });
     }
 }
示例#2
0
 private void CheckForNewSimulation(Services.Models.Simulation newSimulation)
 {
     if (newSimulation != null && this.simulation == null)
     {
         this.simulation = newSimulation;
         if (this.simulation.Enabled)
         {
             this.runner.Start(this.simulation);
         }
     }
 }
示例#3
0
 private void CheckForNewSimulation(Services.Models.Simulation newSimulation)
 {
     if (newSimulation != null && this.simulation == null)
     {
         this.simulation = newSimulation;
         if (this.simulation.ShouldBeRunning())
         {
             this.log.Debug("------ Starting new simulation ------", () => new { this.simulation });
             this.runner.Start(this.simulation);
             this.log.Debug("------ New simulation started ------", () => new { this.simulation });
         }
     }
 }
示例#4
0
        public async Task RunAsync()
        {
            this.log.Info("Simulation Agent running");

            // Keep running, checking if the simulation changes
            while (this.running)
            {
                var oldSimulation = this.simulation;
                try
                {
                    this.log.Debug("------ Checking for simulation changes ------");

                    var newSimulation = (await this.simulations.GetListAsync()).FirstOrDefault();
                    this.log.Debug("Simulation loaded", () => new { newSimulation });

                    // if the simulation is removed from storage & we're running stop simulation.
                    this.CheckForDeletedSimulation(newSimulation);

                    // if there's a new simulation and it's different from the current one
                    // stop the current one from running & start the new one if it's enabled
                    this.CheckForChangedSimulation(newSimulation);

                    // if there's no simulation running but there's one from storage start it
                    this.CheckForNewSimulation(newSimulation);

                    // if the current simulation was asked to stop, stop it.
                    this.CheckForStopOrStartToSimulation();
                }
                catch (Exception e)
                {
                    this.log.Error("Failure reading and starting simulation from storage.", e);
                    this.simulation = oldSimulation;
                }

                if (this.simulation != null && this.simulation.ShouldBeRunning())
                {
                    this.log.Debug("------ Current simulation being run ------");
                    foreach (var model in this.simulation.DeviceModels)
                    {
                        this.log.Debug("Device model", () => new { model });
                    }
                }

                Thread.Sleep(CHECK_INTERVAL_MSECS);
            }
        }
示例#5
0
        private void CheckForChangedSimulation(Services.Models.Simulation newSimulation)
        {
            if (newSimulation != null && this.simulation != null &&
                newSimulation.Modified != this.simulation.Modified)
            {
                this.log.Debug("The simulation has been modified, stopping the current " +
                               "simulation and starting the new one if enabled", () => { });
                this.runner.Stop();

                this.simulation = newSimulation;
                if (this.simulation.Enabled)
                {
                    this.runner.Start(this.simulation);
                    this.log.Debug("----Started new simulation ------", () => new { this.simulation });
                }
            }
        }
        /// <summary>
        /// For each device model in the simulation, create a 'Count'
        /// number of actors, each responsible for updating the simulated device state.
        ///
        /// For each device model in the simulation, and for each message in the model,
        /// create an actor responsible for
        /// sending the telemetry.
        /// </summary>
        public void Start(Services.Models.Simulation simulation)
        {
            // Use `starting` to exit as soon as possible, to minimize the number
            // of threads pending on the lock statement
            if (this.starting || this.running)
            {
                return;
            }

            lock (this.startLock)
            {
                if (this.running)
                {
                    return;
                }

                // Use `starting` to exit as soon as possible, to minimize the number
                // of threads pending on the lock statement
                this.starting = true;

                this.log.Info("Starting simulation...", () => new { simulation.Id });

                // Note: this is a singleton class, so we can call this once. This sets
                // the active hub, e.g. in case the user provided a custom connection string.
                this.devices.SetCurrentIotHub();

                // Create the devices
                try
                {
                    var devices = this.simulations.GetDeviceIds(simulation);

                    // This will ignore existing devices, creating only the missing ones
                    this.devices.CreateListAsync(devices)
                    .Wait(TimeSpan.FromSeconds(DEVICES_CREATION_TIMEOUT_SECS));
                }
                catch (Exception e)
                {
                    this.running  = false;
                    this.starting = false;
                    this.log.Error("Failed to create devices", () => new { e });
                    this.IncrementSimulationErrorsCount();

                    // Return and retry
                    return;
                }

                // Loop through all the device models used in the simulation
                var models = (from model in simulation.DeviceModels where model.Count > 0 select model).ToList();

                // Calculate the total number of devices
                var total = models.Sum(model => model.Count);

                foreach (var model in models)
                {
                    try
                    {
                        // Load device model and merge with overrides
                        var deviceModel = this.GetDeviceModel(model.Id, model.Override);

                        for (var i = 0; i < model.Count; i++)
                        {
                            this.CreateActorsForDevice(deviceModel, i, total);
                        }
                    }
                    catch (ResourceNotFoundException)
                    {
                        this.IncrementSimulationErrorsCount();
                        this.log.Error("The device model doesn't exist", () => new { model.Id });
                    }
                    catch (Exception e)
                    {
                        this.IncrementSimulationErrorsCount();
                        this.log.Error("Unexpected error preparing the device model", () => new { model.Id, e });
                    }
                }

                // Use `running` to avoid starting the simulation more than once
                this.running = true;

                // Reset, just in case
                this.starting = false;

                // Start threads
                this.TryToStartStateThread();

                this.TryToStartConnectionThread();

                this.TryToStartTelemetryThreads();

                this.TryToStartPropertiesThread();
            }
        }