public IpcClientTcpServerRouterFactory(string ipcClient, string tcpServer, int runtimeTimeoutMs, TcpServerRouterFactory.CreateInstanceDelegate factory, ILogger logger) { _logger = logger; _ipcClientRouterFactory = new IpcClientRouterFactory(ipcClient, logger); _tcpServerRouterFactory = factory(tcpServer, runtimeTimeoutMs, logger); }
public IpcClientTcpServerRouterFactory(string ipcClient, string tcpServer, int runtimeTimeoutMs, ILogger logger) { _logger = logger; _ipcClientRouterFactory = new IpcClientRouterFactory(ipcClient, logger); _tcpServerRouterFactory = new TcpServerRouterFactory(tcpServer, runtimeTimeoutMs, logger); }
async static Task <int> runRouter(CancellationToken token, TcpServerRouterFactory routerFactory, Callbacks callbacks) { List <Task> runningTasks = new List <Task>(); List <Router> runningRouters = new List <Router>(); try { routerFactory.Start(); callbacks?.OnRouterStarted(routerFactory.TcpServerAddress); while (!token.IsCancellationRequested) { Task <Router> routerTask = null; Router router = null; try { routerTask = routerFactory.CreateRouterAsync(token); do { // Search list and clean up dead router instances before continue waiting on new instances. runningRouters.RemoveAll(IsRouterDead); runningTasks.Clear(); foreach (var runningRouter in runningRouters) { runningTasks.Add(runningRouter.RouterTaskCompleted.Task); } runningTasks.Add(routerTask); }while (await Task.WhenAny(runningTasks.ToArray()).ConfigureAwait(false) != routerTask); if (routerTask.IsFaulted || routerTask.IsCanceled) { //Throw original exception. routerTask.GetAwaiter().GetResult(); } if (routerTask.IsCompleted) { router = routerTask.Result; router.Start(); // Add to list of running router instances. runningRouters.Add(router); router = null; } routerTask.Dispose(); routerTask = null; } catch (Exception ex) { router?.Dispose(); router = null; routerTask?.Dispose(); routerTask = null; // Timing out on accepting new streams could mean that either the frontend holds an open connection // alive (but currently not using it), or we have a dead backend. If there are no running // routers we assume a dead backend. Reset current backend endpoint and see if we get // reconnect using same or different runtime instance. if (ex is BackendStreamTimeoutException && runningRouters.Count == 0) { routerFactory.Logger.LogDebug("No backend stream available before timeout."); routerFactory.Reset(); } // Timing out on accepting a new runtime connection means there is no runtime alive. // Shutdown router to prevent instances to outlive runtime process (if auto shutdown is enabled). if (ex is RuntimeTimeoutException) { routerFactory.Logger.LogInformation("No runtime connected before timeout."); routerFactory.Logger.LogInformation("Starting automatic shutdown."); throw; } } } } catch (Exception ex) { routerFactory.Logger.LogInformation($"Shutting down due to error: {ex.Message}"); } finally { if (token.IsCancellationRequested) { routerFactory.Logger.LogInformation("Shutting down due to cancelation request."); } runningRouters.RemoveAll(IsRouterDead); runningRouters.Clear(); await routerFactory?.Stop(); callbacks?.OnRouterStopped(); routerFactory.Logger.LogInformation("Router stopped."); } return(0); }