private static void CloseClient(ref ExecServerRemoteClient client) { if (client != null) { try { client.Dispose(); } catch (Exception) { } client = null; } }
private static void CloseClient(ref ExecServerRemoteClient client) { if (client != null) { try { //Console.WriteLine("Closing client"); client.Close(); } catch (Exception) { //Console.WriteLine("Exception while closing {0}", client); } client = null; } }
/// <summary> /// Runs the client side by calling ExecServer remote server and passing arguments. If ExecServer remote is not running, /// it will start it automatically. /// </summary> /// <param name="executablePath">The executable path.</param> /// <param name="workingDirectory">The working directory.</param> /// <param name="args">The arguments.</param> /// <returns>Return status.</returns> private int RunClient(string executablePath, string workingDirectory, Dictionary <string, string> environmentVariables, List <string> args) { var binding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None) { MaxReceivedMessageSize = int.MaxValue, OpenTimeout = TimeSpan.FromMilliseconds(100), SendTimeout = TimeSpan.FromHours(1), ReceiveTimeout = TimeSpan.FromHours(1), }; // Number of concurrent processes: use number of CPU, but no more than 8 int maxServerInstanceIndex = Math.Max(Environment.ProcessorCount, 8); // All tried connections will be kept open until we're done // TODO: Small optimization: as soon as service.Run() actually start (not busy), we could close all other connections var clients = new ExecServerRemoteClient[maxServerInstanceIndex]; try { for (int i = 0; i < MaxRetryCount; i++) { // Try each available server for (int serverInstanceIndex = 0; serverInstanceIndex < maxServerInstanceIndex; ++serverInstanceIndex) { int numberTriesAfterRunProcess = 0; var address = GetEndpointAddress(executablePath, serverInstanceIndex); var processHandle = IntPtr.Zero; int processId = 0; TrySameConnectionAgain: var redirectLog = new RedirectLogger(); var client = clients[serverInstanceIndex] ?? new ExecServerRemoteClient(redirectLog, binding, new EndpointAddress(address)); // Console.WriteLine("{0}: ExecServer Try to connect", DateTime.Now); var service = client.ChannelFactory.CreateChannel(); try { service.Check(); // Keep this connection clients[serverInstanceIndex] = client; //Console.WriteLine("{0}: ExecServer - running start", DateTime.Now); try { var result = service.Run(workingDirectory, environmentVariables, args.ToArray()); if (result == ExecServerRemote.BusyReturnCode) { // Try next server continue; } //Console.WriteLine("{0}: ExecServer - running end", DateTime.Now); return(result); } finally { CloseService(ref service); } } catch (EndpointNotFoundException) { CloseService(ref service); // Close and uncache client connection (server is not started yet) clients[serverInstanceIndex] = null; CloseClient(ref client); string finalExecServerPath; if (numberTriesAfterRunProcess++ == 0) { // The server is not running, we need to run it if (!RunServerProcess(executablePath, serverInstanceIndex, out processHandle, out processId, out finalExecServerPath)) { Console.WriteLine($"Cannot launch exec server for [{finalExecServerPath}]. Trying next one"); continue; } } if (numberTriesAfterRunProcess > MaxRetryStartedProcess) { Console.WriteLine("ERROR cannot connect to newly started proxy server for: {0} {1}", executablePath, string.Join(" ", args)); continue; } // Wait for the process to startup before trying again Console.WriteLine("Waiting {0}ms for the proxy server to start and connect to it", RetryStartedProcessWait); Thread.Sleep(RetryStartedProcessWait); // Check that the sever we tried to launch is still running, if not we have a severe error if (processHandle != IntPtr.Zero) { int exitCode; if (GetExitCodeProcess(processHandle, out exitCode)) { if (exitCode != ExitCodeServerAlreadyInUse && exitCode != PROCESS_STILL_ACTIVE) { Console.WriteLine($"Unexpected error: ExecServerApp has exited with the return code: {exitCode}"); var logPath = GetExecServerErrorLogFilePath(executablePath, processId); if (File.Exists(logPath)) { Console.WriteLine(File.ReadAllText(logPath)); File.Delete(logPath); } return(-300); } } } goto TrySameConnectionAgain; } catch (Exception e) { Console.WriteLine("Error {0}", e); return(-300); } } // Wait for the process to startup before trying again Console.WriteLine("Waiting {0}ms to create a new proxy server", RetryWait); // Wait little bit before trying everything again Thread.Sleep(RetryWait); } Console.WriteLine("ERROR cannot connect to proxy server for: {0} {1}", executablePath, string.Join(" ", args)); return(1); } finally { // Close all services CloseClients(clients); } }
/// <summary> /// Runs the client side by calling ExecServer remote server and passing arguments. If ExecServer remote is not running, /// it will start it automatically. /// </summary> /// <param name="executablePath">The executable path.</param> /// <param name="args">The arguments.</param> /// <returns>Return status.</returns> private int RunClient(string executablePath, List <string> args) { var address = GetEndpointAddress(executablePath); var binding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None) { MaxReceivedMessageSize = int.MaxValue, OpenTimeout = TimeSpan.FromMilliseconds(100), SendTimeout = TimeSpan.FromHours(1), ReceiveTimeout = TimeSpan.FromHours(1), }; var redirectLog = new RedirectLogger(); var client = new ExecServerRemoteClient(redirectLog, binding, new EndpointAddress(address)); try { bool tryToRunServerProcess = false; for (int i = 0; i < MaxRetryProcess; i++) { //Console.WriteLine("{0}: ExecServer Try to connect", DateTime.Now); var service = client.ChannelFactory.CreateChannel(); try { service.Check(); //Console.WriteLine("{0}: ExecServer - running start", DateTime.Now); try { var result = service.Run(args.ToArray()); //Console.WriteLine("{0}: ExecServer - running end", DateTime.Now); return(result); } finally { CloseService(service); } } catch (EndpointNotFoundException ex) { CloseService(service); if (!tryToRunServerProcess) { // The server is not running, we need to run it RunServerProcess(executablePath); tryToRunServerProcess = true; } } // Wait for Thread.Sleep(100); } } finally { try { client.Close(); } catch (Exception ex) { //Console.WriteLine("Exception while closing {0}", client); } } Console.WriteLine("ERROR cannot run command: {0} {1}", Assembly.GetEntryAssembly().Location, string.Join(" ", args)); return(1); }
/// <summary> /// Runs the client side by calling ExecServer remote server and passing arguments. If ExecServer remote is not running, /// it will start it automatically. /// </summary> /// <param name="executablePath">The executable path.</param> /// <param name="workingDirectory">The working directory.</param> /// <param name="args">The arguments.</param> /// <returns>Return status.</returns> private int RunClient(string executablePath, string workingDirectory, Dictionary <string, string> environmentVariables, List <string> args) { var binding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None) { MaxReceivedMessageSize = int.MaxValue, OpenTimeout = TimeSpan.FromMilliseconds(100), SendTimeout = TimeSpan.FromHours(1), ReceiveTimeout = TimeSpan.FromHours(1), }; // Number of concurrent processes: use number of CPU, but no more than 8 int maxServerInstanceIndex = Math.Max(Environment.ProcessorCount, 8); // All tried connections will be kept open until we're done // TODO: Small optimization: as soon as service.Run() actually start (not busy), we could close all other connections var clients = new ExecServerRemoteClient[maxServerInstanceIndex]; try { for (int i = 0; i < MaxRetryCount; i++) { // Try each available server for (int serverInstanceIndex = 0; serverInstanceIndex < maxServerInstanceIndex; ++serverInstanceIndex) { int numberTriesAfterRunProcess = 0; var address = GetEndpointAddress(executablePath, serverInstanceIndex); TrySameConnectionAgain: var redirectLog = new RedirectLogger(); var client = clients[serverInstanceIndex] ?? new ExecServerRemoteClient(redirectLog, binding, new EndpointAddress(address)); // Console.WriteLine("{0}: ExecServer Try to connect", DateTime.Now); var service = client.ChannelFactory.CreateChannel(); try { service.Check(); // Keep this connection clients[serverInstanceIndex] = client; //Console.WriteLine("{0}: ExecServer - running start", DateTime.Now); try { var result = service.Run(workingDirectory, environmentVariables, args.ToArray()); if (result == ExecServerRemote.BusyReturnCode) { // Try next server continue; } //Console.WriteLine("{0}: ExecServer - running end", DateTime.Now); return(result); } finally { CloseService(ref service); } } catch (EndpointNotFoundException) { CloseService(ref service); // Close and uncache client connection (server is not started yet) clients[serverInstanceIndex] = null; CloseClient(ref client); if (numberTriesAfterRunProcess++ == 0) { // The server is not running, we need to run it RunServerProcess(executablePath, serverInstanceIndex); } if (numberTriesAfterRunProcess > MaxRetryStartedProcess) { Console.WriteLine("ERROR cannot connect to newly started proxy server: {0} {1}", execServerPath, string.Join(" ", args)); continue; } // Wait for the process to startup before trying again Console.WriteLine("Waiting {0}ms for the proxy server to start and connect to it", RetryStartedProcessWait); Thread.Sleep(RetryStartedProcessWait); goto TrySameConnectionAgain; } catch (Exception e) { Console.WriteLine("Error {0}", e); return(-300); } } // Wait little bit before trying everything again Thread.Sleep(RetryWait); } Console.WriteLine("ERROR cannot connect to proxy server: {0} {1}", execServerPath, string.Join(" ", args)); return(1); } finally { Thread.Sleep(5000); // Close all services CloseClients(clients); } }