public void Track(SqlServerTimeoutJob item) { _items.TryAdd(item, null); }
public void Untrack(SqlServerTimeoutJob item) { _items.TryRemove(item, out _); }
private SqlServerTimeoutJob DequeueUsingSlidingInvisibilityTimeout(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.", nameof(queues)); } var useLongPolling = false; var queuesString = String.Join("_", queues.OrderBy(x => x)); var resource = Tuple.Create(_storage, queuesString); var pollingDelayMs = Math.Min( Math.Max((int)_options.QueuePollInterval.TotalMilliseconds, MinPollingDelayMs), PollingQuantumMs); SqlServerTimeoutJob fetched = null; using (var cancellationEvent = cancellationToken.GetCancellationEvent()) { while (!cancellationToken.IsCancellationRequested) { var acquired = false; try { if (useLongPolling) { DynamicMutex.Wait(resource, cancellationToken, out acquired); } fetched = _storage.UseConnection(null, connection => { var parameters = new DynamicParameters(); parameters.Add("@queues", queues); parameters.Add("@timeoutSs", (int)_options.SlidingInvisibilityTimeout.Value.Negate().TotalSeconds); parameters.Add("@delayMs", pollingDelayMs); parameters.Add("@endMs", PollingQuantumMs); var query = useLongPolling ? GetBlockingFetchSql() : GetNonBlockingFetchSql(); using (var reader = connection.QueryMultiple(query, parameters, commandTimeout: _storage.CommandTimeout)) { while (!reader.IsConsumed) { var fetchedJob = reader.Read <FetchedJob>().SingleOrDefault(x => x != null); if (fetchedJob != null) { return(new SqlServerTimeoutJob(_storage, fetchedJob.Id, fetchedJob.JobId.ToString(CultureInfo.InvariantCulture), fetchedJob.Queue, fetchedJob.FetchedAt.Value)); } } } return(null); }); } finally { if (acquired) { DynamicMutex.Release(resource); } } if (fetched != null) { break; } if (_options.QueuePollInterval < LongPollingThreshold) { useLongPolling = true; } else { WaitHandle.WaitAny(new WaitHandle[] { cancellationEvent.WaitHandle, NewItemInQueueEvent }, _options.QueuePollInterval); } } cancellationToken.ThrowIfCancellationRequested(); } return(fetched); }