public FluentNHibernateFetchedJob( FluentNHibernateJobStorage storage, FetchedJob fetchedJob) { _storage = storage ?? throw new ArgumentNullException(nameof(storage)); _id = fetchedJob?.Id ?? throw new ArgumentNullException(nameof(fetchedJob)); JobId = fetchedJob.JobId.ToString(CultureInfo.InvariantCulture); Queue = fetchedJob.Queue; }
public IFetchedJob Dequeue(string[] queues, CancellationToken cancellationToken) { if (queues == null) { throw new ArgumentNullException("queues"); } if (queues.Length == 0) { throw new ArgumentException("Queue array must be non-empty.", "queues"); } queues = queues.Select(x => x.ToLower()).ToArray(); Logger.Debug("Attempting to dequeue"); while (true) { cancellationToken.ThrowIfCancellationRequested(); try { using (new FluentNHibernateDistributedLock(_storage, "JobQueue", TimeSpan.FromSeconds(60)) .Acquire()) { var fluentNHibernateFetchedJob = SqlUtil.WrapForTransaction(() => { var token = Guid.NewGuid().ToString(); if (queues.Any()) { using (var session = _storage.GetSession()) { using (var transaction = session.BeginTransaction(IsolationLevel.Serializable)) { var jobQueueFetchedAt = _storage.UtcNow; var next = jobQueueFetchedAt.AddSeconds( _options.InvisibilityTimeout.Negate().TotalSeconds); var jobQueue = session.Query <_JobQueue>() .FirstOrDefault(i => (i.FetchedAt == null || i.FetchedAt < next) && queues.Contains(i.Queue.ToLower())); if (jobQueue != null) { jobQueue.FetchedAt = jobQueueFetchedAt; jobQueue.FetchToken = token; session.Update(jobQueue); session.Flush(); transaction.Commit(); Logger.DebugFormat("Dequeued job id {0} from queue {1}", jobQueue.Job.Id, jobQueue.Queue); var fetchedJob = new FetchedJob { Id = jobQueue.Id, JobId = jobQueue.Job.Id, Queue = jobQueue.Queue }; return(new FluentNHibernateFetchedJob(_storage, fetchedJob)); } } } } return(null); }); if (fluentNHibernateFetchedJob != null) { return(fluentNHibernateFetchedJob); } } } catch (FluentNHibernateDistributedLockException) { // do nothing } catch (Exception ex) { Logger.ErrorException(ex.Message, ex); throw; } cancellationToken.WaitHandle.WaitOne(_options.QueuePollInterval); cancellationToken.ThrowIfCancellationRequested(); } }
public IFetchedJob Dequeue(string[] queues, CancellationToken cancellationToken) { if (queues == null) { throw new ArgumentNullException(nameof(queues)); } if (queues.Length == 0) { throw new ArgumentException("Queue array must be non-empty.", "queues"); } Logger.Debug("Attempting to dequeue"); var timeoutSeconds = _storage.Options.InvisibilityTimeout.Negate().TotalSeconds; while (!cancellationToken.IsCancellationRequested) { var fluentNHibernateDistributedLock = new FluentNHibernateDistributedLock(_storage, "JobQueue", _storage.Options.JobQueueDistributedLockTimeout) .Acquire(); if (fluentNHibernateDistributedLock == null) { if (cancellationToken.IsCancellationRequested) { return(null); } cancellationToken.WaitHandle.WaitOne(_storage.Options.QueuePollInterval); } else { using (fluentNHibernateDistributedLock) { var fluentNHibernateFetchedJob = SqlUtil.WrapForTransaction(() => { var token = Guid.NewGuid().ToString(); using (var session = _storage.GetStatelessSession()) { using (var transaction = session.BeginTransaction(IsolationLevel.Serializable)) { var jobQueueFetchedAt = _storage.UtcNow; var cutoff = jobQueueFetchedAt.AddSeconds(timeoutSeconds); if (Logger.IsDebugEnabled()) { Logger.Debug(string.Format("Getting jobs where {0}=null or {0}<{1}", nameof(_JobQueue.FetchedAt), cutoff)); } var jobQueue = session.Query <_JobQueue>() .FirstOrDefault(i => (i.FetchedAt == null || i.FetchedAt < cutoff) && queues.Contains(i.Queue)); if (jobQueue != null) { jobQueue.FetchToken = token; jobQueue.FetchedAt = jobQueueFetchedAt; session.Update(jobQueue); transaction.Commit(); Logger.DebugFormat("Dequeued job id {0} from queue {1}", jobQueue.Job.Id, jobQueue.Queue); var fetchedJob = new FetchedJob { Id = jobQueue.Id, JobId = jobQueue.Job.Id, Queue = jobQueue.Queue }; return(new FluentNHibernateFetchedJob(_storage, fetchedJob)); } } } return(null); }); if (fluentNHibernateFetchedJob != null) { return(fluentNHibernateFetchedJob); } } } } return(null); }