/// <summary>Notification that the list of sensors has changed</summary> internal static void OnSensorsChanged(Guid sensorId, SensorAvailabilityChange change) { if (SensorsChanged != null) { SensorsChanged.Invoke(new SensorsChangedEventArgs(sensorId, change)); } }
void IMessageReceiver.ReceiveMessage(IPeerManager sender, DistributedMessage distributedMessage) { if (sensorsInstances.Any() || Loader.Instance.Network.IsMaster) { return; } var allSensorsString = distributedMessage.Content.PopString(); var allSensors = JsonConvert.DeserializeObject <SensorData[]>(allSensorsString); var enabledSensorsString = distributedMessage.Content.PopString(); var enabledSensors = JsonConvert.DeserializeObject <List <string> >(enabledSensorsString); InstantiateSensors(allSensors); foreach (var instance in sensorsInstances) { if (enabledSensors.Contains(instance.Key)) { instance.Value.Enable(); } else { instance.Value.Disable(); } } SensorsChanged?.Invoke(); }
private void DistributeSensors() { var network = SimulatorManager.Instance.Network; if (!network.IsMaster || network.Master.Clients.Count <= 0) { return; } var sensorsToDistribute = new List <SensorInstanceController>(); foreach (var sensorData in sensorsInstances) { if (sensorData.Value.Instance.CanBeDelegatedToClient) { sensorsToDistribute.Add(sensorData.Value); } } var peerSensors = new JSONArray(); //Distribute sensors between clients and master simulation var sensorsPerPeer = sensorsToDistribute.Count / network.Master.Clients.Count; var currentSensorI = 0; //Clients for (var i = 0; i < network.Master.Clients.Count; i++) { var client = network.Master.Clients[i]; peerSensors = new JSONArray(); for (; currentSensorI < sensorsPerPeer * (i + 1); currentSensorI++) { peerSensors.Add(sensorsToDistribute[currentSensorI].Configuration); sensorsToDistribute[currentSensorI].Disable(); } var content = new BytesStack(); content.PushString(peerSensors.ToString()); var message = new Message(Key, content, MessageType.ReliableUnordered); UnicastMessage(client.Peer.PeerEndPoint, message); } SensorsChanged?.Invoke(); }
private void DistributeSensors() { var network = Loader.Instance.Network; var master = network.Master; var clients = master.Clients; if (!network.IsMaster || clients.Count <= 0) { return; } var clientsCount = clients.Count; var clientsSensors = new Dictionary <IPeerManager, List <string> >(); for (var i = 0; i < clientsCount; i++) { clientsSensors.Add(clients[i].Peer, new List <string>()); } //Order sensors by distribution type, so ultra high loads will be handled first var sensorsByDistributionType = sensorsInstances.Values.Where(controller => controller.Instance.DistributionType != SensorBase.SensorDistributionType.MainOnly) .OrderByDescending(controller => controller.Instance.DistributionType); var loadBalancer = master.LoadBalancer; foreach (var sensorData in sensorsByDistributionType) { IPeerManager sensorPeer; switch (sensorData.Instance.DistributionType) { case SensorBase.SensorDistributionType.MainOnly: loadBalancer.AppendMasterLoad(sensorData.Instance.PerformanceLoad); break; case SensorBase.SensorDistributionType.MainOrClient: sensorPeer = loadBalancer.AppendLoad(sensorData.Instance.PerformanceLoad, true); if (sensorPeer != null) { //Sensor will be distributed to lowest load client clientsSensors[sensorPeer].Add(sensorData.Configuration.Name); sensorData.Disable(); SimulatorManager.Instance.Sensors.AppendEndPoint(sensorData.Instance, sensorPeer.PeerEndPoint); } break; case SensorBase.SensorDistributionType.ClientOnly: sensorPeer = loadBalancer.AppendLoad(sensorData.Instance.PerformanceLoad, false); //Sensor will be distributed to lowest load client clientsSensors[sensorPeer].Add(sensorData.Configuration.Name); SimulatorManager.Instance.Sensors.AppendEndPoint(sensorData.Instance, sensorPeer.PeerEndPoint); sensorData.Disable(); break; default: throw new ArgumentOutOfRangeException(); } } var sensorsData = sensorsInstances.Select(s => s.Value.Configuration); var allSensors = JsonConvert.SerializeObject(sensorsData, JsonSettings.camelCase); var sensorsLength = BytesStack.GetMaxByteCount(allSensors); //Send sensors data to clients for (var i = 0; i < clientsCount; i++) { var client = network.Master.Clients[i]; var enabledSensors = JsonConvert.SerializeObject(clientsSensors[client.Peer], JsonSettings.camelCase); var message = MessagesPool.Instance.GetMessage(sensorsLength + BytesStack.GetMaxByteCount(enabledSensors)); message.AddressKey = Key; message.Content.PushString(enabledSensors); message.Content.PushString(allSensors); message.Type = DistributedMessageType.ReliableOrdered; ((IMessageSender)this).UnicastMessage(client.Peer.PeerEndPoint, message); } SensorsChanged?.Invoke(); }
private void InstantiateSensors(SensorData[] sensors) { var parents = new Dictionary <string, GameObject>() { { string.Empty, gameObject }, }; var Controller = GetComponent <IAgentController>(); var requested = sensors.ToList(); var baseLink = transform.GetComponentInChildren <BaseLink>(); while (requested.Count > 0) { // remember how many are still looking to find their parent int requestedCount = requested.Count; for (int i = 0; i < requested.Count(); i++) { var item = requested[i]; string parentName = item.Parent != null ? item.Parent : string.Empty; if (!parents.ContainsKey(parentName)) { continue; } var parentObject = parents[parentName]; var name = item.Name; var type = item.Type; GameObject prefab = null; if (item.Plugin.AssetGuid == null) { prefab = Config.SensorPrefabs.FirstOrDefault(s => GetSensorType(s) == type).gameObject; } else if (Config.SensorTypeLookup.ContainsKey(item.Plugin.AssetGuid)) { prefab = Config.SensorTypeLookup[item.Plugin.AssetGuid]?.gameObject; } else { var dir = Path.Combine(Config.PersistentDataPath, "Sensors"); var vfs = VfsEntry.makeRoot(dir); Config.CheckDir(vfs.GetChild(item.Plugin.AssetGuid), Config.LoadSensorPlugin); if (Config.SensorTypeLookup.ContainsKey(item.Plugin.AssetGuid)) { prefab = Config.SensorTypeLookup[item.Plugin.AssetGuid]?.gameObject; } } if (prefab == null) { throw new Exception($"Issue loading sensor type {type} for gameobject {gameObject.name} check logs"); } var sensor = CreateSensor(gameObject, parentObject, prefab, item, baseLink); var sensorBase = sensor.GetComponent <SensorBase>(); sensorBase.Name = name; sensor.name = name; if (AgentBridgeClient != null) { sensor.GetComponent <SensorBase>().OnBridgeSetup(AgentBridgeClient.Bridge); } parents.Add(name, sensor); requested.RemoveAt(i); i--; var sensorInstanceController = new SensorInstanceController(item, sensorBase); if (SimulatorManager.InstanceAvailable) { SimulatorManager.Instance.Sensors.RegisterSensor(sensorBase); } sensorInstanceController.Enable(); Controller?.AgentSensors.Add(sensorBase); sensorsInstances.Add(name, sensorInstanceController); } // no sensors found their parent this round, they also won't find it next round if (requestedCount == requested.Count) { throw new Exception($"Failed to create {requested.Count} sensor(s), cannot determine parent-child relationship"); } SensorsChanged?.Invoke(); } }
private void InstantiateSensors(string sensors) { var available = Simulator.Web.Config.Sensors.ToDictionary(sensor => sensor.Name); var prefabs = Simulator.Web.Config.SensorPrefabs.ToDictionary(sensor => GetSensorType(sensor)); var parents = new Dictionary <string, GameObject>() { { string.Empty, gameObject }, }; var agentController = GetComponent <AgentController>(); var requested = JSONNode.Parse(sensors).Children.ToList(); while (requested.Count != 0) { int requestedCount = requested.Count; foreach (var parent in parents.Keys.ToArray()) { var parentObject = parents[parent]; for (int i = 0; i < requested.Count; i++) { var item = requested[i]; if (item["parent"].Value == parent) { var name = item["name"].Value; var type = item["type"].Value; SensorConfig config; if (!available.TryGetValue(type, out config)) { throw new Exception($"Unknown sensor type {type} for {gameObject.name} vehicle"); } var sensor = CreateSensor(gameObject, parentObject, prefabs[type].gameObject, item); var sensorBase = sensor.GetComponent <SensorBase>(); sensorBase.Name = name; sensor.name = name; SIM.LogSimulation(SIM.Simulation.SensorStart, name); if (AgentBridgeClient != null) { sensor.GetComponent <SensorBase>().OnBridgeSetup(AgentBridgeClient.Bridge); } parents.Add(name, sensor); requested.RemoveAt(i); i--; var sensorInstanceController = new SensorInstanceController(item, sensorBase); sensorInstanceController.Enable(); agentController.AgentSensors.Add(sensorBase); sensorsInstances.Add(name, sensorInstanceController); } } } if (requestedCount == requested.Count) { throw new Exception( $"Failed to create {requested.Count} sensor(s), cannot determine parent-child relationship"); } SensorsChanged?.Invoke(); } }
private void DistributeSensors() { var network = Loader.Instance.Network; var master = network.Master; var clients = master.Clients; if (!network.IsMaster || clients.Count <= 0) { return; } var clientsCount = clients.Count; var clientsSensors = new List <SensorData> [clientsCount]; for (var i = 0; i < clientsSensors.Length; i++) { clientsSensors[i] = new List <SensorData>(); } //Order sensors by distribution type, so ultra high loads will be handled first var sensorsByDistributionType = sensorsInstances.Values .Where(controller => controller.Instance.DistributionType != SensorBase.SensorDistributionType.DoNotDistribute) .OrderByDescending(controller => controller.Instance.DistributionType); //Track the load of simulations var clientsLoad = new float[clientsCount]; //Decrease master simulation sensors load var masterLoad = 0.15f; foreach (var sensorData in sensorsByDistributionType) { var lowestLoadIndex = 0; switch (sensorData.Instance.DistributionType) { case SensorBase.SensorDistributionType.LowLoad: var lowLoadValue = 0.05f; for (var i = 1; i < clientsCount; i++) { if (clientsLoad[i] < clientsLoad[lowestLoadIndex]) { lowestLoadIndex = i; } } if (masterLoad >= clientsLoad[lowestLoadIndex]) { //Sensor will be distributed to lowest load client clientsLoad[lowestLoadIndex] += lowLoadValue; clientsSensors[lowestLoadIndex].Add(sensorData.Configuration); sensorData.Disable(); SimulatorManager.Instance.Sensors.AppendEndPoint(sensorData.Instance, clients[lowestLoadIndex].Peer.PeerEndPoint); } else { //Sensor won't be distributed, instance on master is not disabled masterLoad += lowLoadValue; } break; case SensorBase.SensorDistributionType.HighLoad: var highLoadValue = 0.1f; for (var i = 1; i < clientsCount; i++) { if (clientsLoad[i] < clientsLoad[lowestLoadIndex]) { lowestLoadIndex = i; } } if (masterLoad >= clientsLoad[lowestLoadIndex]) { //Sensor will be distributed to lowest load client clientsLoad[lowestLoadIndex] += highLoadValue; clientsSensors[lowestLoadIndex].Add(sensorData.Configuration); sensorData.Disable(); SimulatorManager.Instance.Sensors.AppendEndPoint(sensorData.Instance, clients[lowestLoadIndex].Peer.PeerEndPoint); } else { //Sensor won't be distributed, instance on master is not disabled masterLoad += highLoadValue; } break; case SensorBase.SensorDistributionType.UltraHighLoad: var ultraHighLoadValue = 1.0f; for (var i = 1; i < clientsCount; i++) { if (clientsLoad[i] < clientsLoad[lowestLoadIndex]) { lowestLoadIndex = i; } } //Sensor will be distributed to lowest load client clientsLoad[lowestLoadIndex] += ultraHighLoadValue; clientsSensors[lowestLoadIndex].Add(sensorData.Configuration); SimulatorManager.Instance.Sensors.AppendEndPoint(sensorData.Instance, clients[lowestLoadIndex].Peer.PeerEndPoint); sensorData.Disable(); break; default: throw new ArgumentOutOfRangeException(); } } //Check if any client is overloaded var overloadedClients = clientsLoad.Count(load => load > 1.0f); if (overloadedClients > 0) { if (masterLoad > 1.0f) { overloadedClients++; } Debug.LogWarning($"Running cluster simulation with {overloadedClients} overloaded instances. Decrease sensors count or extend the cluster for best performance."); } else if (masterLoad > 1.0f) { Debug.LogWarning($"Running cluster simulation with overloaded master simulation. Used sensors cannot be distributed to the clients."); } //Send sensors data to clients for (var i = 0; i < clientsCount; i++) { var client = network.Master.Clients[i]; var sensorString = JsonConvert.SerializeObject(clientsSensors[i], JsonSettings.camelCase); var message = MessagesPool.Instance.GetMessage(BytesStack.GetMaxByteCount(sensorString)); message.AddressKey = Key; message.Content.PushString(sensorString); message.Type = DistributedMessageType.ReliableOrdered; UnicastMessage(client.Peer.PeerEndPoint, message); } SensorsChanged?.Invoke(); }
protected void OnSensorsChanged() { SensorsChanged?.Invoke(this); }