private Task EstablishConnectionAsync(IPEndPoint tcpEndPoint, IPEndPoint httpEndPoint) { lock (_connectionLock) { if (_isActive) { throw new InvalidOperationException("EventStoreConnection is already active"); } _isActive = true; _tcpEndPoint = tcpEndPoint; _httpEndPoint = httpEndPoint; _lastReconnectionTimestamp = DateTime.UtcNow; _connection = _connector.CreateTcpConnection(_tcpEndPoint, OnPackageReceived, OnConnectionEstablished, OnConnectionClosed); _timeoutCheckStopwatch.Start(); _worker = new Thread(MainLoop) { IsBackground = true, Name = "Worker thread" }; _worker.Start(); return(Tasks.CreateCompleted()); } }
public EventStoreConnection(IPEndPoint tcpEndPoint, int maxConcurrentRequests = 50, int maxAttemptsForOperation = 10, int maxReconnections = 10, ILogger logger = null) { Ensure.NotNull(tcpEndPoint, "tcpEndPoint"); Ensure.Positive(maxConcurrentRequests, "maxConcurrentRequests"); Ensure.Nonnegative(maxAttemptsForOperation, "maxAttemptsForOperation"); Ensure.Nonnegative(maxReconnections, "maxReconnections"); _tcpEndPoint = tcpEndPoint; _maxConcurrentItems = maxConcurrentRequests; _maxAttempts = maxAttemptsForOperation; _maxReconnections = maxReconnections; LogManager.RegisterLogger(logger); _log = LogManager.GetLogger(); _connector = new TcpConnector(_tcpEndPoint); _subscriptionsChannel = new SubscriptionsChannel(_connector); //TODO TD: WAT? _projectionsManager = new ProjectionsManager(new IPEndPoint(_tcpEndPoint.Address, _tcpEndPoint.Port + 1000)); _lastReconnectionTimestamp = DateTime.UtcNow; _connection = _connector.CreateTcpConnection(OnPackageReceived, OnConnectionEstablished, OnConnectionClosed); _timeoutCheckStopwatch.Start(); _worker = new Thread(MainLoop) { IsBackground = true, Name = "Worker thread" }; _worker.Start(); }
public EventStoreConnection(IPEndPoint tcpEndPoint) { Ensure.NotNull(tcpEndPoint, "tcpEndPoint"); _tcpEndPoint = tcpEndPoint; _connector = new TcpConnector(_tcpEndPoint); _outstandingOperations = new ConcurrentDictionary <Guid, ITaskCompletionWrapper>(); _lastReconnectionTimestamp = DateTime.UtcNow; _connection = _connector.CreateTcpConnection(OnPackageReceived, ConnectionEstablished, ConnectionClosed); _timeoutCheckStopwatch.Start(); _monitoringThread = new Thread(MonitoringLoop) { IsBackground = true, Name = string.Format("Monitoring thread") }; _monitoringThread.Start(); }
private void MonitoringLoop() { while (!_monitoringThreadStop) { TcpPackage nextPackage; if (_inProgressCount < TcpSentReceiveWindow && _sendQueue.TryDequeue(out nextPackage)) { Interlocked.Increment(ref _inProgressCount); var workItem = new WorkItem(nextPackage); Send(workItem, null); } else { Thread.Sleep(1); } lock (_connectionLock) { if (_reconnectionStopwatch.IsRunning && _reconnectionStopwatch.Elapsed >= ReconnectionDelay) { _reconnectionsCount += 1; _lastReconnectionTimestamp = DateTime.UtcNow; _connection = _connector.CreateTcpConnection(OnPackageReceived, ConnectionEstablished, ConnectionClosed); _reconnectionStopwatch.Stop(); } } if (_timeoutCheckStopwatch.Elapsed > EventTimeoutCheckPeriod) { var now = DateTime.UtcNow; foreach (var kvp in _inProgress) { var correlationId = kvp.Key; var workerItem = kvp.Value; var lastUpdated = new DateTime(Interlocked.Read(ref workerItem.LastUpdatedTicks)); if (now - lastUpdated > EventTimeoutDelay || _reconnectionsCount > 10) { if (lastUpdated > _lastReconnectionTimestamp || _reconnectionsCount > 10) { WorkItem workItem; ITaskCompletionWrapper completionWrapper; if (RemoveInProgressItem(correlationId, " -ML timeout", out workItem, out completionWrapper)) { completionWrapper.Fail( new Exception( string.Format("Timed out event {0} which " + "never got response from server was discovered. " + "Last state update: {1}, last reconnect: {2}, now: {3}.", workerItem.TcpPackage.CorrelationId, lastUpdated, _lastReconnectionTimestamp, now))); } } else { Retry(correlationId); } } } _timeoutCheckStopwatch.Restart(); } } }
private void MainLoop() { while (!_stopping) { IClientOperation operation; if (_inProgressCount < _maxConcurrentItems && _queue.TryDequeue(out operation)) { Interlocked.Increment(ref _inProgressCount); Send(new WorkItem(operation)); } else { Thread.Sleep(1); } lock (_connectionLock) { if (_reconnectionStopwatch.IsRunning && _reconnectionStopwatch.Elapsed >= ReconnectionDelay) { _reconnectionsCount += 1; if (_reconnectionsCount > _maxReconnections) { throw new CannotEstablishConnectionException(); } _lastReconnectionTimestamp = DateTime.UtcNow; _connection = _connector.CreateTcpConnection(OnPackageReceived, OnConnectionEstablished, OnConnectionClosed); _reconnectionStopwatch.Stop(); } } if (_timeoutCheckStopwatch.Elapsed > OperationTimeoutCheckPeriod) { var now = DateTime.UtcNow; var retriable = new List <WorkItem>(); foreach (var workerItem in _inProgress.Values) { var lastUpdated = new DateTime(Interlocked.Read(ref workerItem.LastUpdatedTicks)); if (now - lastUpdated > OperationTimeout) { Console.WriteLine("Timed out, corrId: {0}.", workerItem.Operation.CorrelationId); //Debugger.Break(); if (lastUpdated >= _lastReconnectionTimestamp) { var err = string.Format("{0} never got response from server" + "Last state update : {1}, last reconnect : {2}, now(utc) : {3}.", workerItem, lastUpdated, _lastReconnectionTimestamp, now); if (TryRemoveWorkItem(workerItem)) { _log.Error(err); workerItem.Operation.Fail(new OperationTimedOutException(err)); } _log.Error(err); } else { retriable.Add(workerItem); } } } foreach (var workItem in retriable.OrderBy(wi => wi.SeqNo)) { Retry(workItem); } _timeoutCheckStopwatch.Restart(); } } }
public EventStoreConnection(IPEndPoint tcpEndPoint) { Ensure.NotNull(tcpEndPoint, "tcpEndPoint"); _tcpEndPoint = tcpEndPoint; _connector = new TcpConnector(_tcpEndPoint); _outstandingOperations = new ConcurrentDictionary<Guid, ITaskCompletionWrapper>(); _lastReconnectionTimestamp = DateTime.UtcNow; _connection = _connector.CreateTcpConnection(OnPackageReceived, ConnectionEstablished, ConnectionClosed); _timeoutCheckStopwatch.Start(); _monitoringThread = new Thread(MonitoringLoop) { IsBackground = true, Name = string.Format("Monitoring thread") }; _monitoringThread.Start(); }