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...", () => { }); } }
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); } } }
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 }); } } }
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); } }
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(); } }