private async Task <string> ProcessItem(BourneListens bourne, List <TcpClient> clients, Func <TcpClient, int, Task> func, int taskID) { //You can echo "Hello world!" | nc ::1 2575 to send messages to accept a new connection request TcpClient client = await bourne.AcceptTcpClientAsync(); string remote = client.Client.RemoteEndPoint.ToString(); var local = bourne.LocalEndpoint.ToString(); _logger.Log(LogLevel.Debug, $"{local} connected to: {remote}"); if (clients.Count < Connection.maxInboundConnections && _taskManager.CanStart($"{Connection.name}.read")) { clients.Add(client); _logger.Log(LogLevel.Debug, $"{local} added to clients: {remote}"); var endpoint = client.Client.RemoteEndPoint; var newTaskID = _taskManager.NewTaskID(); Task task = new Task(new Action(async() => await func(client, newTaskID)), _taskManager.cts.Token); await _taskManager.Start(newTaskID, task, $"{Connection.name}.read", $"{Connection.name}.read: {remote}", isLongRunning : false); } else { _logger.Log(LogLevel.Warning, $"{local} Max Connections: {Connection.maxInboundConnections} reached."); _logger.Log(LogLevel.Debug, $"client connection closed {taskID} due to max connections reached"); client.Close(); } return(local); }
public async Task Upload(int taskID, LifeImageCloudConnection Connection, ILifeImageCloudConnectionManager manager, IConnectionRoutedCacheManager cache, IHttpManager httpManager) { var taskInfo = $"task: {taskID} connection: {Connection.name}"; _logger.Log(LogLevel.Debug, $"{taskInfo} Entering Upload"); try { bool success = await manager.ToCloudSignal.WaitAsync(_profileStorage.Current.KickOffInterval, _taskManager.cts.Token) .ConfigureAwait(false); // ToCloudSignal.Dispose(); // ToCloudSignal = new SemaphoreSlim(0, 1); await _sendToCloudService.SendToCloud(taskID, Connection, cache, httpManager); //if (_profileStorage.Current.rules.DoesRouteDestinationExistForSource(Connection.name)) if (_rulesManager.DoesRouteDestinationExistForSource(Connection.name)) { if (_taskManager.CanStart($"{Connection.name}.GetRequests")) { var newTaskID = _taskManager.NewTaskID(); Task task = new Task(new Action(async() => await _cloudAgentTaskLoader.GetRequests(taskID, Connection, cache, httpManager)), _taskManager.cts.Token); await _taskManager.Start(newTaskID, task, $"{Connection.name}.GetRequests", isLongRunning : false); } } } catch (TaskCanceledException) { _logger.Log(LogLevel.Information, $"{taskInfo} Task was canceled."); } catch (OperationCanceledException) { _logger.Log(LogLevel.Warning, $"{taskInfo} Wait Operation Canceled. Exiting Upload"); } catch (Exception e) { _logger.LogFullException(e, taskInfo); _logger.Log(LogLevel.Critical, $"{taskInfo} Exiting Upload"); } finally { _taskManager.Stop($"{Connection.name}.Upload"); } }
private async Task kickOff(int taskID) { var profile = _profileStorage.Current; var taskInfo = $"task: {taskID}"; try { //2018-08-16 shb moved from init to enable task restartability after task cancellation. #if (DEBUG) if (_taskManager.CanStart("ReadConsole")) { var newTaskID = _taskManager.NewTaskID(); Task task = new Task(new Action(async() => await ReadConsole())); await _taskManager.Start(newTaskID, task, $"ReadConsole", isLongRunning : true); } #endif /* * 2018-07-05 shb responsive status reports as soon as task completes */ if (_taskManager.CanStart("TaskCompletion")) { var newTaskID = _taskManager.NewTaskID(); Task task = new Task(new Action(async() => await _taskManager.TaskCompletion(profile))); await _taskManager.Start(newTaskID, task, $"TaskCompletion", isLongRunning : true); } var cloudConnection = _connectionFinder.GetPrimaryLifeImageConnection(profile); var connectionManager = _connectionManagerFactory.GetManager(cloudConnection) as ILifeImageCloudConnectionManager; if (cloudConnection.loginNeeded) { await connectionManager.login(taskID); //await profile.GetPrimaryLifeImageConnection().login(taskID); } if (!cloudConnection.loginNeeded) { kickOffCount++; profile.lastKickOff = DateTime.Now; _logger.Log(LogLevel.Debug, $"{taskInfo} kickOffCount: {kickOffCount}"); _logger.Log(LogLevel.Debug, $"{taskInfo} -----------------KickOff----------------"); _logger.Log(LogLevel.Debug, $"{taskInfo} Processing UpgradeDowngrade"); UpgradeDowngrade(); _logger.Log(LogLevel.Debug, $"{taskInfo} Processing Run"); Run(); /* * 2018-07-06 shb purge async */ if ((kickOffCount + 9) % 10 == 0) { if (_taskManager.CanStart("Purge")) { var newTaskID = _taskManager.NewTaskID(); Task task = new Task(new Action(async() => await _litePurgeService.Purge(newTaskID))); await _taskManager.Start(newTaskID, task, $"Purge", isLongRunning : false); } } // Process the queues in the connections foreach (var conn in profile.connections) { _logger.Log(LogLevel.Debug, $"{taskInfo} connection: {conn.name} enabled: {conn.enabled}"); if (conn.enabled == false) { _logger.Log(LogLevel.Debug, $"{taskInfo} connection: {conn.name} enabled: {conn.enabled} skipping"); continue; } /* * 2018-05-10 shb prevent re-entrancy problems with Kickoff. */ if (_taskManager.CanStart($"{conn.name}.Kickoff") && conn.started) { var connManager = _connectionManagerFactory.GetManager(conn); var newTaskID = _taskManager.NewTaskID(); Task task = new Task(new Action(async() => await connManager.Kickoff(newTaskID)), _taskManager.cts.Token); await _taskManager.Start(newTaskID, task, $"{conn.name}.Kickoff", isLongRunning : false); } } /* * 2018-06-12 shb status is now long running. */ if (_taskManager.CanStart($"UpdateStatus")) { var newTaskID = _taskManager.NewTaskID(); Task task = new Task(new Action(async() => await _taskManager.UpdateStatus())); await _taskManager.Start(newTaskID, task, $"UpdateStatus", isLongRunning : true); } } else { _logger.Log(LogLevel.Information, "Primary LifeImage account loginNeeded, skipping kickOff until resolved"); await connectionManager.login(taskID); //await profile.GetPrimaryLifeImageConnection().login(taskID); } } catch (TaskCanceledException) { _logger.Log(LogLevel.Information, $"Task was canceled."); } catch (Exception e) { _logger.LogFullException(e, taskInfo); //throw e; throw; } }
private async Task StartImpl(HL7Connection Connection, List <BourneListens> listeners, ObservableCollection <BourneListens> deadListeners, List <TcpClient> clients, Func <TcpClient, int, Task> Read) { RemoveDeadListeners(listeners, deadListeners); //frequent DNS lookup required for Cloud and HA environments where a lower TTL results in faster failover. //For a listener this means a container might have been moved to another server with different IP. var hostEntry = Dns.GetHostEntry(Connection.localHostname); foreach (var ip in hostEntry.AddressList) { _logger.Log(LogLevel.Information, $"{Connection.name} hostEntry: {Connection.localHostname} ip: {ip}"); BourneListens bourne = null; if (ip.AddressFamily == AddressFamily.InterNetworkV6 && Connection.UseIPV6) { if (!listeners.Exists(x => x.localaddr.Equals(ip) && x.port.Equals(Connection.localPort))) { bourne = new BourneListens(ip, Connection.localPort); listeners.Add(bourne); //you can verify Start worked on mac by doing lsof -n -i:2575 | grep LISTEN, where 2575 is HL7 or whatever port you want. bourne.Start(); _logger.Log(LogLevel.Information, $"{Connection.name} is listening on {bourne.LocalEndpoint}"); _logger.Log(LogLevel.Information, $"{Connection.name} Verify with Mac/Linux:lsof -n -i:{Connection.localPort} | grep LISTEN and with echo \"Hello world\" | nc {Connection.localHostname} {Connection.localPort}"); _logger.Log(LogLevel.Information, $"{Connection.name} Verify with Windows:netstat -abno (requires elevated privileges)"); } } if ((ip.AddressFamily == AddressFamily.InterNetwork && Connection.UseIPV4 && !RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) || (ip.AddressFamily == AddressFamily.InterNetwork && Connection.UseIPV4 && !Connection.UseIPV6 && RuntimeInformation.IsOSPlatform(OSPlatform.Windows))) { if (!listeners.Exists(x => x.localaddr.Equals(ip) && x.port.Equals(Connection.localPort))) { bourne = new BourneListens(ip, Connection.localPort); listeners.Add(bourne); //you can verify Start worked on mac by doing lsof -n -i:2575 | grep LISTEN, where 2575 is HL7 or whatever port you want. bourne.Start(); _logger.Log(LogLevel.Information, $"{Connection.name} is listening on {bourne.LocalEndpoint}"); _logger.Log(LogLevel.Information, $"{Connection.name} Verify with Mac/Linux:lsof -n -i:{Connection.localPort} | grep LISTEN and with echo \"Hello world\" | nc {Connection.localHostname} {Connection.localPort}"); _logger.Log(LogLevel.Information, $"{Connection.name} Verify with Windows:netstat -abno (requires elevated privileges)"); } } } foreach (var listener in listeners) { if (listener != null && listener.LocalEndpoint != null) { if (_taskManager.CanStart($"{Connection.name}.accept: {listener.LocalEndpoint}")) { var newTaskID = _taskManager.NewTaskID(); Task task = new Task(new Action(async() => await _hl7AcceptService.Accept(Connection, listener, clients, Read, newTaskID)), _taskManager.cts.Token); await _taskManager.Start(newTaskID, task, $"{Connection.name}.accept: {listener.LocalEndpoint}", $"{Connection.name}.accept: {listener.LocalEndpoint}", isLongRunning : true); await Task.Delay(1000); } } else { _logger.Log(LogLevel.Information, $"listener is disposed but still in list. Ignoring"); } } }