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();
            }
        }
Exemplo n.º 2
0
        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();
            }
        }