private void HandleSpawnRequest(SpawnRequestPacket packet, IIncommingMessage message) { if (_spawnRequestHandler == null) { DefaultSpawnRequestHandler(packet, message); return; } _spawnRequestHandler.Invoke(packet, message); }
public void UpdateQueue() { // Ignore if there's no connection with the peer if (!Peer.IsConnected) { return; } // Ignore if nothing's in the queue if (_queue.Count == 0) { return; } if (_beingSpawned.Count >= MaxConcurrentRequests) { // If we're currently at the maximum available concurrent spawn count var finishedSpawns = _beingSpawned.Where(s => s.IsDoneStartingProcess); // Remove finished spawns foreach (var finishedSpawn in finishedSpawns) { _beingSpawned.Remove(finishedSpawn); } } // If we're still at the maximum concurrent requests if (_beingSpawned.Count >= MaxConcurrentRequests) { return; } var task = _queue.Dequeue(); var data = new SpawnRequestPacket() { SpawnerId = SpawnerId, CustomArgs = task.CustomArgs, Properties = task.Properties, SpawnId = task.SpawnId, SpawnCode = task.UniqueCode }; var msg = MessageHelper.Create((short)OpCodes.SpawnRequest, data); Peer.SendMessage(msg, (status, response) => { if (status != ResponseStatus.Success) { task.Abort(); Logs.Error("Spawn request was not handled. Status: " + status + " | " + response.AsString("Unknown Error")); return; } }); }
public void UpdateQueue() { // Ignore if there's no connection with the peer if (!Client.IsConnected) { return; } // Ignore if nothing's in the queue if (_queue.Count == 0) { return; } if (_beingSpawned.Count >= MaxConcurrentRequests) { // If we're currently at the maximum available concurrent spawn count var finishedSpawns = _beingSpawned.Where(s => s.IsDoneStartingProcess); // Remove finished spawns foreach (var finishedSpawn in finishedSpawns) { _beingSpawned.Remove(finishedSpawn); } } // If we're still at the maximum concurrent requests if (_beingSpawned.Count >= MaxConcurrentRequests) { return; } var task = _queue.Dequeue(); var data = new SpawnRequestPacket { SpawnerId = ID, SpawnTaskID = task.ID, SpawnCode = task.UniqueCode, Options = task.Options }; Client.SendMessage(Message.Create(MessageTags.RequestSpawnFromMasterToSpawner, data), SendMode.Reliable); }
protected virtual void HandleSpawnRequest(SpawnRequestPacket packet, IIncommingMessage message) { SpawnerController.DefaultSpawnRequestHandler(packet, message); }
public void DefaultSpawnRequestHandler(SpawnRequestPacket packet, IIncommingMessage message) { _logger.Debug("Default spawn handler started handling a request to spawn process"); var controller = _spawners.GetController(packet.SpawnerId); if (controller == null) { message.Respond("Failed to spawn a process. Spawner controller not found", ResponseStatus.Failed); return; } var port = _spawners.GetAvailablePort(); // Check if we're overriding an IP to master server var masterIp = string.IsNullOrEmpty(controller.DefaultSpawnerSettings.MasterIp) ? controller.Connection.ConnectionIp : controller.DefaultSpawnerSettings.MasterIp; // Check if we're overriding a port to master server var masterPort = controller.DefaultSpawnerSettings.MasterPort < 0 ? controller.Connection.ConnectionPort : controller.DefaultSpawnerSettings.MasterPort; // Machine Ip var machineIp = controller.DefaultSpawnerSettings.MachineIp; // Path to executable var path = controller.DefaultSpawnerSettings.ExecutablePath; if (string.IsNullOrEmpty(path)) { path = File.Exists(Environment.GetCommandLineArgs()[0]) ? Environment.GetCommandLineArgs()[0] : Process.GetCurrentProcess().MainModule.FileName; } // In case a path is provided with the request if (packet.Properties.ContainsKey(OptionKeys.ExecutablePath)) { path = packet.Properties[OptionKeys.ExecutablePath]; } // Get the scene name var sceneNameArgument = packet.Properties.ContainsKey(OptionKeys.SceneName) ? string.Format("{0} {1} ", CommandLineArgs.Names.LoadScene, packet.Properties[OptionKeys.SceneName]) : ""; if (!string.IsNullOrEmpty(packet.OverrideExePath)) { path = packet.OverrideExePath; } // If spawn in batchmode was set and `DontSpawnInBatchmode` arg is not provided var spawnInBatchmode = controller.DefaultSpawnerSettings.SpawnInBatchmode && !CommandLineArgs.DontSpawnInBatchmode; var startProcessInfo = new ProcessStartInfo(path) { CreateNoWindow = false, UseShellExecute = false, Arguments = " " + (spawnInBatchmode ? "-batchmode -nographics " : "") + (controller.DefaultSpawnerSettings.AddWebGlFlag ? CommandLineArgs.Names.WebGl + " " : "") + sceneNameArgument + string.Format("{0} {1} ", CommandLineArgs.Names.MasterIp, masterIp) + string.Format("{0} {1} ", CommandLineArgs.Names.MasterPort, masterPort) + string.Format("{0} {1} ", CommandLineArgs.Names.SpawnId, packet.SpawnId) + string.Format("{0} {1} ", CommandLineArgs.Names.AssignedPort, port) + string.Format("{0} {1} ", CommandLineArgs.Names.MachineIp, machineIp) + (CommandLineArgs.DestroyUi ? CommandLineArgs.Names.DestroyUi + " " : "") + string.Format("{0} \"{1}\" ", CommandLineArgs.Names.SpawnCode, packet.SpawnCode) + packet.CustomArgs }; _logger.Debug("Starting process with args: " + startProcessInfo.Arguments); var processStarted = false; try { new Thread(() => { try { _logger.Debug("New thread started"); using (var process = Process.Start(startProcessInfo)) { _logger.Debug("Process started. Spawn Id: " + packet.SpawnId + ", pid: " + process.Id); processStarted = true; lock (_processLock) { // Save the process _processes[packet.SpawnId] = process; } var processId = process.Id; // Notify server that we've successfully handled the request AppTimer.ExecuteOnMainThread(() => { message.Respond(ResponseStatus.Success); controller.NotifyProcessStarted(packet.SpawnId, processId, startProcessInfo.Arguments); }); process.WaitForExit(); } } catch (Exception e) { if (!processStarted) { AppTimer.ExecuteOnMainThread(() => { message.Respond(ResponseStatus.Failed); }); } _logger.Error("An exception was thrown while starting a process. Make sure that you have set a correct build path. " + "We've tried to start a process at: '" + path + "'. You can change it at 'SpawnerBehaviour' component"); _logger.Error(e); } finally { lock (_processLock) { // Remove the process _processes.Remove(packet.SpawnId); } AppTimer.ExecuteOnMainThread(() => { // Release the port number _spawners.ReleasePort(port); _logger.Debug("Notifying about killed process with spawn id: " + packet.SpawnerId); controller.NotifyProcessKilled(packet.SpawnId); }); } }).Start(); } catch (Exception e) { message.Respond(e.Message, ResponseStatus.Error); Logs.Error(e); } }
public void HandleSpawnRequest(IIncommingMessage message, SpawnRequestPacket data) { var port = GetAvailablePort(); // Machine Ip var machineIp = _spawnerConfig.MachineIp; // Path to executable var path = _spawnerConfig.ExecutablePath; if (string.IsNullOrEmpty(path)) { path = File.Exists(Environment.GetCommandLineArgs()[0]) ? Environment.GetCommandLineArgs()[0] : Process.GetCurrentProcess().MainModule.FileName; } // In case a path is provided with the request if (data.Properties.ContainsKey(OptionKeys.ExecutablePath)) { path = data.Properties[OptionKeys.ExecutablePath]; } // Get the scene name var sceneNameArgument = data.Properties.ContainsKey(OptionKeys.SceneName) ? $"{CommandLineArgs.LoadScene} {data.Properties[OptionKeys.SceneName]} " : ""; if (!string.IsNullOrEmpty(data.OverrideExePath)) { path = data.OverrideExePath; } // If spawn in batchmode was set and `DontSpawnInBatchmode` arg is not provided var spawnInBatchmode = _spawnerConfig.SpawnInBatchmode && !CommandLineArgs.DontSpawnInBatchmode; var startProcessInfo = new ProcessStartInfo(path) { CreateNoWindow = true, UseShellExecute = true, Arguments = " " + (spawnInBatchmode ? "-batchmode -nographics " : "") + (_spawnerConfig.AddWebGlFlag ? CommandLineArgs.WebGl + " " : "") + sceneNameArgument + $"{CommandLineArgs.MasterIp} {_client.Config.Network.Address} " + $"{CommandLineArgs.MasterPort} {_client.Config.Network.Port} " + $"{CommandLineArgs.SpawnId} {data.SpawnId} " + $"{CommandLineArgs.AssignedPort} {port} " + $"{CommandLineArgs.MachineIp} {machineIp} " + $"{CommandLineArgs.SpawnCode} \"{data.SpawnCode}\" " + data.CustomArgs }; var processStarted = false; try { new Thread(() => { try { using (var process = Process.Start(startProcessInfo)) { // Save the process _processes[data.SpawnId] = process; var processId = process.Id; // Notify server that we've successfully handled the request //AppTimer.ExecuteOnMainThread(() => //{ message.Respond(ResponseStatus.Success); NotifyProcessStarted(data.SpawnId, processId, startProcessInfo.Arguments); //}); processStarted = true; process.WaitForExit(); } } catch (Exception e) { if (!processStarted) { //AppTimer.ExecuteOnMainThread(() => //{ message.Respond(ResponseStatus.Failed); } //}); } finally { // Remove the process _processes.TryRemove(data.SpawnId, out _); //AppTimer.ExecuteOnMainThread(() => //{ // Release the port number ReleasePort(port); NotifyProcessKilled(data.SpawnId); //}); } }).Start(); } catch (Exception e) { message.Respond(e.Message, ResponseStatus.Error); } }