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)
        {
            var hasLock = await storage.Session.TryGetGlobalLock(TransportConstants.OutgoingMessageLockId);

            if (!hasLock)
            {
                return;
            }

            try
            {
                var destinations = await storage.Outgoing.FindAllDestinations();

                var count = 0;
                foreach (var destination in destinations)
                {
                    var found = await recoverFrom(destination, storage);

                    count += found;
                }

                var wasMaxedOut = count >= _settings.RecoveryBatchSize;

                if (wasMaxedOut)
                {
                    agent.RescheduleOutgoingRecovery();
                }
            }
            finally
            {
                await storage.Session.ReleaseGlobalLock(TransportConstants.OutgoingMessageLockId);
            }
        }
Beispiel #3
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();
            }
        }
            public async Task Execute(IDurabilityAgentStorage storage, IDurabilityAgent agent)
            {
                try
                {
                    await _inner.Execute(storage, agent);

                    _completion.SetResult(true);
                }
                catch (Exception e)
                {
                    _completion.SetException(e);
                }
            }
Beispiel #5
0
        public async Task Execute(IDurabilityAgentStorage storage, IDurabilityAgent agent)
        {
            await storage.Session.Begin();

            var gotLock = await storage.Session.TryGetGlobalLock(TransportConstants.ReassignmentLockId);

            if (!gotLock)
            {
                await storage.Session.Rollback();

                return;
            }

            try
            {
                var owners = await storage.Nodes.FindUniqueOwners(_settings.UniqueNodeId);

                foreach (var owner in owners.Where(x => x != TransportConstants.AnyNode))
                {
                    if (owner == _settings.UniqueNodeId)
                    {
                        continue;
                    }

                    if (await storage.Session.TryGetGlobalTxLock(owner))
                    {
                        await storage.Nodes.ReassignDormantNodeToAnyNode(owner);
                    }
                }
            }
            catch (Exception)
            {
                await storage.Session.Rollback();

                throw;
            }
            finally
            {
                await storage.Session.ReleaseGlobalLock(TransportConstants.ReassignmentLockId);
            }

            await storage.Session.Commit();
        }
Beispiel #6
0
        public async Task <Envelope[]> ExecuteAtTime(IDurabilityAgentStorage storage, IDurabilityAgent agent, DateTimeOffset utcNow)
        {
            var hasLock = await storage.Session.TryGetGlobalLock(TransportConstants.ScheduledJobLockId);

            if (!hasLock)
            {
                return(null);
            }

            await storage.Session.Begin();

            try
            {
                Envelope[] readyToExecute = null;

                try
                {
                    readyToExecute = await storage.LoadScheduledToExecute(utcNow);

                    if (!readyToExecute.Any())
                    {
                        await storage.Session.Rollback();

                        return(readyToExecute);
                    }

                    await storage.Incoming.Reassign(_settings.UniqueNodeId, readyToExecute);

                    await storage.Session.Commit();
                }
                catch (Exception)
                {
                    await storage.Session.Rollback();

                    throw;
                }

                _logger.ScheduledJobsQueuedForExecution(readyToExecute);

                foreach (var envelope in readyToExecute)
                {
                    await agent.EnqueueLocally(envelope);
                }

                return(readyToExecute);
            }
            finally
            {
                await storage.Session.ReleaseGlobalLock(TransportConstants.ScheduledJobLockId);
            }
        }
Beispiel #7
0
        public Task Execute(IDurabilityAgentStorage storage, IDurabilityAgent agent)
        {
            var utcNow = DateTimeOffset.UtcNow;

            return(ExecuteAtTime(storage, agent, utcNow));
        }