public async Task Execute(IDurabilityAgentStorage storage, IDurabilityAgent agent) { if (_workers.QueuedCount > _options.MaximumLocalEnqueuedBackPressureThreshold) { return; } await storage.Session.Begin(); Envelope[] incoming = null; try { var gotLock = await storage.Session.TryGetGlobalLock(TransportConstants.IncomingMessageLockId); if (!gotLock) { await storage.Session.Rollback(); return; } incoming = await storage.Incoming.LoadPageOfLocallyOwned(); if (!incoming.Any()) { await storage.Session.Rollback(); return; } await storage.Incoming.Reassign(_options.UniqueNodeId, incoming); await storage.Session.Commit(); } catch (Exception) { await storage.Session.Rollback(); throw; } finally { await storage.Session.ReleaseGlobalLock(TransportConstants.IncomingMessageLockId); } _logger.RecoveredIncoming(incoming); foreach (var envelope in incoming) { envelope.OwnerId = _options.UniqueNodeId; await _workers.Enqueue(envelope); } if (incoming.Length == _options.Retries.RecoveryBatchSize && _workers.QueuedCount < _options.MaximumLocalEnqueuedBackPressureThreshold) { agent.RescheduleIncomingRecovery(); } }
public async Task Execute(IDurabilityAgentStorage storage, IDurabilityAgent agent) { // TODO -- enforce back pressure here on the retries listener! await storage.Session.Begin(); Envelope[] incoming = null; try { var gotLock = await storage.Session.TryGetGlobalLock(TransportConstants.IncomingMessageLockId); if (!gotLock) { await storage.Session.Rollback(); return; } incoming = await storage.Incoming.LoadPageOfLocallyOwned(); if (!incoming.Any()) { await storage.Session.Rollback(); return; } await storage.Incoming.Reassign(_settings.UniqueNodeId, incoming); await storage.Session.Commit(); } catch (Exception) { await storage.Session.Rollback(); throw; } finally { await storage.Session.ReleaseGlobalLock(TransportConstants.IncomingMessageLockId); } _logger.RecoveredIncoming(incoming); foreach (var envelope in incoming) { envelope.OwnerId = _settings.UniqueNodeId; envelope.Callback = new DurableCallback(envelope, _workers, _persistence, _logger); await _workers.Enqueue(envelope); } // TODO -- this should be smart enough later to check for back pressure before rescheduling if (incoming.Length == _settings.RecoveryBatchSize) { agent.RescheduleIncomingRecovery(); } }
public async Task Execute(SqlConnection conn, ISchedulingAgent agent) { if (_workers.QueuedCount > _settings.MaximumLocalEnqueuedBackPressureThreshold) { return; } var tx = conn.BeginTransaction(); List <Envelope> incoming = null; try { if (!await conn.TryGetGlobalTxLock(tx, IncomingMessageLockId)) { tx.Rollback(); return; } incoming = await conn.CreateCommand(tx, _findAtLargeEnvelopesSql) .ExecuteToEnvelopes(); if (!incoming.Any()) { tx.Rollback(); return; } await markOwnership(conn, tx, incoming); tx.Commit(); } catch (Exception) { tx.Rollback(); throw; } _logger.RecoveredIncoming(incoming); foreach (var envelope in incoming) { envelope.OwnerId = _settings.UniqueNodeId; await _workers.Enqueue(envelope); } if (incoming.Count == _settings.Retries.RecoveryBatchSize && _workers.QueuedCount < _settings.MaximumLocalEnqueuedBackPressureThreshold) { agent.RescheduleIncomingRecovery(); } }
public async Task Execute(IDocumentSession session, ISchedulingAgent agent) { if (_workers.QueuedCount > _settings.MaximumLocalEnqueuedBackPressureThreshold) { return; } if (!await session.TryGetGlobalTxLock(IncomingMessageLockId)) { return; } var incoming = await session.Connection.CreateCommand(_findAtLargeEnvelopesSql) .ExecuteToEnvelopes(); if (!incoming.Any()) { return; } session.MarkOwnership(_marker.Incoming, _settings.UniqueNodeId, incoming); await session.SaveChangesAsync(); _logger.RecoveredIncoming(incoming); foreach (var envelope in incoming) { envelope.OwnerId = _settings.UniqueNodeId; await _workers.Enqueue(envelope); } if (incoming.Count == _settings.Retries.RecoveryBatchSize && _workers.QueuedCount < _settings.MaximumLocalEnqueuedBackPressureThreshold) { agent.RescheduleIncomingRecovery(); } }