public IFetchedJob Dequeue([NotNull] string[] queues, CancellationToken cancellationToken) { if (queues is null) { throw new ArgumentNullException(nameof(queues)); } if (queues.Length == 0) { throw new ArgumentException(CoreStrings.ArgumentExceptionCollectionCannotBeEmpty, nameof(queues)); } var waitHandles = new[] { cancellationToken.WaitHandle, NewItemInQueueEvent, }; while (true) { cancellationToken.ThrowIfCancellationRequested(); var expireAt = DateTime.UtcNow - _storage.SlidingInvisibilityTimeout; using (var context = _storage.CreateContext()) { var queueItem = DequeueFunc(context, queues, expireAt); if (queueItem != null) { queueItem.FetchedAt = DateTime.UtcNow; try { context.SaveChanges(); return(new EFCoreFetchedJob(_storage, queueItem)); } catch (DbUpdateConcurrencyException) { continue; } } } WaitHandle.WaitAny( waitHandles, _storage.QueuePollInterval); } }
public void Execute(CancellationToken cancellationToken) { _logger.Debug(CoreStrings.CountersAggregatorExecuteStarting(nameof(HangfireCounter))); int removedCount; do { removedCount = 0; using (var context = _storage.CreateContext()) { var lookup = GetCountersToRemoveFunc(context). ToLookup(x => x.Key); foreach (var items in lookup) { var count = items.Count(); if (count > 1) { context.RemoveRange(items); context.Add(new HangfireCounter { Key = items.Key, Value = items.Sum(x => x.Value), ExpireAt = items.Max(x => x.ExpireAt), }); removedCount += count; } } try { context.SaveChanges(); } catch (DbUpdateConcurrencyException) { // Someone else has removed at least one record. Database wins. continue; } } cancellationToken.ThrowIfCancellationRequested(); }while (removedCount > 0); _logger.Trace(CoreStrings.CountersAggregatorExecuteCompleted(nameof(HangfireCounter))); cancellationToken.WaitHandle.WaitOne(_storage.CountersAggregationInterval); }