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); } }
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); } }
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); }