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;
            }
        }
Beispiel #4
0
        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");
                }
            }
        }