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"); JobQueueDto fetchedJob; var fetchConditions = new[] { Builders<JobQueueDto>.Filter.Eq(_ => _.FetchedAt, null), Builders<JobQueueDto>.Filter.Lt(_ => _.FetchedAt, _connection.GetServerTimeUtc().AddSeconds(_options.InvisibilityTimeout.Negate().TotalSeconds)) }; var currentQueryIndex = 0; do { cancellationToken.ThrowIfCancellationRequested(); FilterDefinition<JobQueueDto> fetchCondition = fetchConditions[currentQueryIndex]; fetchedJob = AsyncHelper.RunSync(() => _connection.JobQueue.FindOneAndUpdateAsync( fetchCondition & Builders<JobQueueDto>.Filter.In(_ => _.Queue, queues), Builders<JobQueueDto>.Update.Set(_ => _.FetchedAt, _connection.GetServerTimeUtc()), new FindOneAndUpdateOptions<JobQueueDto> { IsUpsert = false, ReturnDocument = ReturnDocument.After }, cancellationToken )); if (fetchedJob == null) { if (currentQueryIndex == fetchConditions.Length - 1) { cancellationToken.WaitHandle.WaitOne(_options.QueuePollInterval); cancellationToken.ThrowIfCancellationRequested(); } } currentQueryIndex = (currentQueryIndex + 1) % fetchConditions.Length; } while (fetchedJob == null); return new MongoFetchedJob(_connection, fetchedJob.Id, fetchedJob.JobId.ToString(CultureInfo.InvariantCulture), 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"); JobQueueDto fetchedJob; var fetchConditions = new[] { Query<JobQueueDto>.EQ(_ => _.FetchedAt, null), Query<JobQueueDto>.LT(_ => _.FetchedAt, _connection.GetServerTimeUtc().AddSeconds(_options.InvisibilityTimeout.Negate().TotalSeconds)) }; var currentQueryIndex = 0; do { cancellationToken.ThrowIfCancellationRequested(); fetchedJob = _connection.JobQueue .FindAndModify(new FindAndModifyArgs { Query = Query.And(fetchConditions[currentQueryIndex], Query<JobQueueDto>.In(_ => _.Queue, queues)), Update = Update<JobQueueDto>.Set(_ => _.FetchedAt, _connection.GetServerTimeUtc()), VersionReturned = FindAndModifyDocumentVersion.Modified, Upsert = false }) .GetModifiedDocumentAs<JobQueueDto>(); if (fetchedJob == null) { if (currentQueryIndex == fetchConditions.Length - 1) { cancellationToken.WaitHandle.WaitOne(_options.QueuePollInterval); cancellationToken.ThrowIfCancellationRequested(); } } currentQueryIndex = (currentQueryIndex + 1) % fetchConditions.Length; } while (fetchedJob == null); return new MongoFetchedJob(_connection, fetchedJob.Id, fetchedJob.JobId.ToString(CultureInfo.InvariantCulture), fetchedJob.Queue); }