Exemple #1
0
 public void Track(SqlServerTimeoutJob item)
 {
     _items.TryAdd(item, null);
 }
Exemple #2
0
 public void Untrack(SqlServerTimeoutJob item)
 {
     _items.TryRemove(item, out _);
 }
Exemple #3
0
        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);
        }