/// <summary>
        /// Start a service connection without the lifetime management.
        /// To get full lifetime management including dispose or restart, use <see cref="ServiceConnectionContainerBase"/>
        /// </summary>
        /// <param name="target">The target instance Id</param>
        /// <returns>The task of StartAsync</returns>
        public async Task StartAsync(string target = null)
        {
            // Codes in try block should catch and log exceptions separately.
            // The catch here should be very rare to reach.
            try
            {
                if (await StartAsyncCore(target))
                {
                    _serviceConnectionStartTcs.TrySetResult(true);
                    _isConnected = true;
                    await ProcessIncomingAsync();

                    _isConnected = false;
                }

                _serviceConnectionStartTcs.TrySetResult(false);
            }
            catch (Exception ex)
            {
                Status = ServiceConnectionStatus.Disconnected;
                _serviceConnectionStartTcs.TrySetException(ex);
                Log.UnexpectedExceptionInStart(_logger, ConnectionId, ex);
            }
            finally
            {
                await StopAsync();
            }
        }
Exemplo n.º 2
0
        private IEnumerator CheckServiceConnection()
        {
            while (true)
            {
                ServiceConnectionStatus status = _plugin.TestServiceConnection();
                if (status != _ServiceConnectionStatus)
                {
                    _ServiceConnectionStatus = ChangeServiceConnectionStatus(status);
                }

                if (status == ServiceConnectionStatus.Connected)
                {
                    var suitConnection = _plugin.TestDeviceConnection();
                    if (suitConnection != _DeviceConnectionStatus)
                    {
                        _DeviceConnectionStatus = ChangeDeviceConnectionStatus(suitConnection);
                    }
                }
                else
                {
                    if (_DeviceConnectionStatus != DeviceConnectionStatus.Disconnected)
                    {
                        _DeviceConnectionStatus = ChangeDeviceConnectionStatus(DeviceConnectionStatus.Disconnected);
                    }
                }
                yield return(new WaitForSeconds(0.5f));
            }
        }
Exemplo n.º 3
0
        public void ChangeConnectionStatus(ServiceConnectionStatus status, ServiceDisconnectedStatus disconnectedStatus, ServiceMachineStatus machineConnectionStatus = ServiceMachineStatus.Disconnected)
        {
            ChangeConnectionStatus(status, machineConnectionStatus);

            ChangeDisconnectedStatus(disconnectedStatus);

            _DomainManagerProxy.SendAllMessagePackets();
        }
 public TestServiceConnection(ServiceConnectionStatus status = ServiceConnectionStatus.Connected, bool throws = false, ILogger logger = null) : base(
         new ServiceProtocol(),
         Guid.NewGuid().ToString(),
         new HubServiceEndpoint(),
         null, // TODO replace it with a NullMessageHandler
         ServiceConnectionType.Default,
         logger ?? NullLogger.Instance
         )
 {
     _expectedStatus = status;
     _throws         = throws;
     _logger         = logger ?? NullLogger.Instance;
 }
Exemplo n.º 5
0
        private ServiceConnectionStatus ChangeServiceConnectionStatus(ServiceConnectionStatus newStatus)
        {
            if (newStatus == ServiceConnectionStatus.Connected)
            {
                OnServiceConnected(new ServiceConnectionArgs());
            }
            else
            {
                OnServiceDisconnected(new ServiceConnectionArgs());
            }

            return(newStatus);
        }
Exemplo n.º 6
0
 public TestServiceConnection(ServiceConnectionStatus status = ServiceConnectionStatus.Connected, bool throws = false,
                              ILogger logger = null,
                              IServiceMessageHandler serviceMessageHandler = null
                              ) : base(
         new ServiceProtocol(),
         "serverId",
         Guid.NewGuid().ToString(),
         new HubServiceEndpoint(),
         serviceMessageHandler,
         ServiceConnectionType.Default,
         logger ?? NullLogger.Instance
         )
 {
     _expectedStatus = status;
     _throws         = throws;
 }
Exemplo n.º 7
0
        private async Task <bool> StartAsyncCore(string target)
        {
            // Lock here in case somebody tries to send before the connection is assigned
            await _serviceConnectionLock.WaitAsync();

            try
            {
                Status            = ServiceConnectionStatus.Connecting;
                ConnectionContext = await CreateConnection(target);

                ErrorMessage = null;

                if (await HandshakeAsync())
                {
                    Log.ServiceConnectionConnected(_logger, ConnectionId);
                    Status = ServiceConnectionStatus.Connected;
                    return(true);
                }
                else
                {
                    // False means we got a HandshakeResponseMessage with error. Will take below actions:
                    // - Dispose the connection
                    Status = ServiceConnectionStatus.Disconnected;
                    await DisposeConnection();

                    return(false);
                }
            }
            catch (Exception ex)
            {
                Log.FailedToConnect(_logger, ex);

                Status = ServiceConnectionStatus.Disconnected;
                await DisposeConnection();

                return(false);
            }
            finally
            {
                _serviceConnectionLock.Release();
            }
        }
        internal async Task TestIfConnectionWillNotRestartAfterShutdown(ServiceConnectionStatus status)
        {
            List <IServiceConnection> connections = new List <IServiceConnection>
            {
                new SimpleTestServiceConnection(),
                new SimpleTestServiceConnection(status: status)
            };

            IServiceConnection connection = connections[1];

            using TestServiceConnectionContainer container = new TestServiceConnectionContainer(connections, factory: new SimpleTestServiceConnectionFactory());
            container.ShutdownForTest();

            await container.OnConnectionCompleteForTestShutdown(connection);

            // the connection should not be replaced when shutting down
            Assert.Equal(container.Connections[1], connection);
            // its status is not changed
            Assert.Equal(status, container.Connections[1].Status);
            // the container is not listening to the connection's status changes after shutdown
            Assert.Equal(1, (connection as SimpleTestServiceConnection).ConnectionStatusChangedRemoveCount);
        }
Exemplo n.º 9
0
        private void ChangeConnectionStatus(ServiceConnectionStatus status, ServiceMachineStatus machineConnectionStatus)
        {
            ConnectionStatus = status;

            _DomainManagerProxy.AddMessage(
                new DeviceVariableUpdateMessage(ConnectionStatusName, ConnectionStatus)
                );

            switch (ConnectionStatus)
            {
            case ServiceConnectionStatus.Connecting:
            case ServiceConnectionStatus.Connected:
                break;

            case ServiceConnectionStatus.Disabled:
                foreach (var machine in _Machines)
                {
                    machine.ChangeMachineStatus(ServiceMachineStatus.Disabled);
                }
                break;

            case ServiceConnectionStatus.Disconnected:
                foreach (var machine in _Machines)
                {
                    machine.ChangeMachineStatus(machineConnectionStatus);
                    machine.IsConnected = false;
                    // TODO: Test / clean-up these falgs
                    machine.IsHuskyMachineServiceConnected = false;
                }

                HeartbeatTimer.Interval = _ConnectionTimerIntervalMilliseconds;
                HeartbeatTimer.Restart();

                break;
            }
        }
 public TestSimpleServiceConnection(ServiceConnectionStatus status = ServiceConnectionStatus.Connected, bool throws = false, TaskCompletionSource <object> writeAsyncTcs = null)
 {
     Status         = status;
     _throws        = throws;
     _writeAsyncTcs = writeAsyncTcs;
 }
Exemplo n.º 11
0
 public TestServiceConnection(ServiceConnectionStatus status = ServiceConnectionStatus.Connected, bool throws = false) : base(null, null, null, null, ServerConnectionType.Default, NullLogger.Instance)
 {
     _expectedStatus = status;
     _throws         = throws;
 }
Exemplo n.º 12
0
 public void SetStatus(ServiceConnectionStatus status)
 {
     Status          = status;
     _expectedStatus = status;
 }
 public Task StartAsync(string target = null)
 {
     Status = ServiceConnectionStatus.Connected;
     return(Task.CompletedTask);
 }
Exemplo n.º 14
0
 public TestServiceConnection(ServiceConnectionStatus status = ServiceConnectionStatus.Connected, bool throws = false) : base(null, null, null, null, ServerConnectionType.Default, null)
 {
     _status = status;
     _throws = throws;
 }
 public SimpleTestServiceConnection(ServiceConnectionStatus status = ServiceConnectionStatus.Disconnected)
 {
     Status = status;
 }
Exemplo n.º 16
0
        private async Task ProcessIncomingAsync()
        {
            var keepAliveTimer = StartKeepAliveTimer();

            try
            {
                while (true)
                {
                    var result = await ConnectionContext.Transport.Input.ReadAsync();

                    var buffer = result.Buffer;

                    try
                    {
                        if (result.IsCanceled)
                        {
                            Log.ReadingCancelled(_logger, ConnectionId);
                            break;
                        }

                        if (!buffer.IsEmpty)
                        {
                            Log.ReceivedMessage(_logger, buffer.Length, ConnectionId);

                            UpdateReceiveTimestamp();

                            // No matter what kind of message come in, trigger send ping check
                            _ = TrySendPingAsync();

                            while (ServiceProtocol.TryParseMessage(ref buffer, out var message))
                            {
                                _ = DispatchMessageAsync(message);
                            }
                        }

                        if (result.IsCompleted)
                        {
                            // The connection is closed (reconnect)
                            Log.ServiceConnectionClosed(_logger, ConnectionId);
                            break;
                        }
                    }
                    catch (Exception ex)
                    {
                        // Error occurs in handling the message, but the connection between SDK and service still works.
                        // So, just log error instead of breaking the connection
                        Log.ErrorProcessingMessages(_logger, ex);
                    }
                    finally
                    {
                        ConnectionContext.Transport.Input.AdvanceTo(buffer.Start, buffer.End);
                    }
                }
            }
            catch (Exception ex)
            {
                // Fatal error: There is something wrong for the connection between SDK and service.
                // Abort all the client connections, close the httpConnection.
                // Only reconnect can recover.
                Log.ConnectionDropped(_logger, ConnectionId, ex);
            }
            finally
            {
                keepAliveTimer.Stop();

                await _serviceConnectionLock.WaitAsync();

                try
                {
                    Status = ServiceConnectionStatus.Disconnected;
                    await DisposeConnection();
                }
                finally
                {
                    _serviceConnectionLock.Release();
                }
            }

            // TODO: Never cleanup connections unless Service asks us to do that
            // Current implementation is based on assumption that Service will drop clients
            // if server connection fails.
            await CleanupConnections();
        }
Exemplo n.º 17
0
 public TestContainer(ServiceConnectionStatus status)
 {
     Status = status;
 }
 public TestServiceConnection(ServiceConnectionStatus status = ServiceConnectionStatus.Connected, bool throws = false)
 {
     Status  = status;
     _throws = throws;
 }
Exemplo n.º 19
0
 public StatusChange(ServiceConnectionStatus oldStatus, ServiceConnectionStatus newStatus)
 {
     OldStatus = oldStatus;
     NewStatus = newStatus;
 }