/// <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(); } }
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)); } }
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; }
private ServiceConnectionStatus ChangeServiceConnectionStatus(ServiceConnectionStatus newStatus) { if (newStatus == ServiceConnectionStatus.Connected) { OnServiceConnected(new ServiceConnectionArgs()); } else { OnServiceDisconnected(new ServiceConnectionArgs()); } return(newStatus); }
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; }
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); }
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; }
public TestServiceConnection(ServiceConnectionStatus status = ServiceConnectionStatus.Connected, bool throws = false) : base(null, null, null, null, ServerConnectionType.Default, NullLogger.Instance) { _expectedStatus = status; _throws = throws; }
public void SetStatus(ServiceConnectionStatus status) { Status = status; _expectedStatus = status; }
public Task StartAsync(string target = null) { Status = ServiceConnectionStatus.Connected; return(Task.CompletedTask); }
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; }
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(); }
public TestContainer(ServiceConnectionStatus status) { Status = status; }
public TestServiceConnection(ServiceConnectionStatus status = ServiceConnectionStatus.Connected, bool throws = false) { Status = status; _throws = throws; }
public StatusChange(ServiceConnectionStatus oldStatus, ServiceConnectionStatus newStatus) { OldStatus = oldStatus; NewStatus = newStatus; }