예제 #1
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
                {
                    // TODO -- this needs to be paged to keep it from being too big
                    readyToExecute = await storage.LoadScheduledToExecute(utcNow);

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

                        return(readyToExecute);
                    }

                    await storage.Incoming.Reassign(_options.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);
            }
        }
예제 #2
0
        public async Task <List <Envelope> > ExecuteAtTime(SqlConnection conn, DateTimeOffset utcNow)
        {
            if (!await conn.TryGetGlobalLock(ScheduledJobLockId))
            {
                return(null);
            }

            var tx = conn.BeginTransaction();

            try
            {
                List <Envelope> readyToExecute = null;

                try
                {
                    readyToExecute = await conn
                                     .CreateCommand(tx, _findReadyToExecuteJobs)
                                     .With("time", utcNow, SqlDbType.DateTimeOffset)
                                     .ExecuteToEnvelopes(tx);

                    if (!readyToExecute.Any())
                    {
                        tx.Rollback();
                        return(readyToExecute);
                    }

                    await markOwnership(conn, tx, readyToExecute);

                    tx.Commit();
                }
                catch (Exception)
                {
                    tx.Rollback();
                    throw;
                }

                _logger.ScheduledJobsQueuedForExecution(readyToExecute);

                foreach (var envelope in readyToExecute)
                {
                    envelope.Callback = new DurableCallback(envelope, _workers, _persistor, _retries, _logger);

                    await _workers.Enqueue(envelope);
                }

                return(readyToExecute);
            }
            finally
            {
                await conn.ReleaseGlobalLock(ScheduledJobLockId);
            }
        }
예제 #3
0
        public async Task <List <Envelope> > ExecuteAtTime(IDocumentSession session, DateTimeOffset utcNow)
        {
            if (!await session.TryGetGlobalTxLock(ScheduledJobLockId))
            {
                return(null);
            }

            var readyToExecute = await session.Connection
                                 .CreateCommand(_findReadyToExecuteJobs)
                                 .With("time", utcNow, NpgsqlDbType.TimestampTZ)
                                 .ExecuteToEnvelopes();

            if (!readyToExecute.Any())
            {
                return(readyToExecute);
            }


            var identities = readyToExecute.Select(x => x.Id).ToArray();

            await session.Connection.CreateCommand()
            .Sql(_markOwnedIncomingSql)
            .With("idlist", identities, NpgsqlDbType.Array | NpgsqlDbType.Uuid)
            .With("owner", _marker.CurrentNodeId, NpgsqlDbType.Integer)
            .ExecuteNonQueryAsync();

            await session.SaveChangesAsync();

            _logger.ScheduledJobsQueuedForExecution(readyToExecute);

            foreach (var envelope in readyToExecute)
            {
                envelope.Callback = new DurableCallback(envelope, _workers, _persistor, _retries, _logger);

                await _workers.Enqueue(envelope);
            }

            return(readyToExecute);
        }