/// <summary> /// ctor /// </summary> /// <param name="dbContext"></param> /// <param name="jobQueueSemaphore"></param> /// <param name="distributedLockMutex"></param> public MongoNotificationObserver(HangfireDbContext dbContext, IJobQueueSemaphore jobQueueSemaphore, IDistributedLockMutex distributedLockMutex) { _dbContext = dbContext; _jobQueueSemaphore = jobQueueSemaphore; _distributedLockMutex = distributedLockMutex; }
/// <summary> /// Creates MongoDB distributed lock /// </summary> /// <param name="resource">Lock resource</param> /// <param name="timeout">Lock timeout</param> /// <param name="locks">Lock collection</param> /// <param name="notifications"></param> /// <param name="storageOptions">Database options</param> /// <param name="mutex"></param> /// <exception cref="DistributedLockTimeoutException">Thrown if lock is not acquired within the timeout</exception> /// <exception cref="MongoDistributedLockException">Thrown if other mongo specific issue prevented the lock to be acquired</exception> public MongoDistributedLock(string resource, TimeSpan timeout, IMongoCollection <DistributedLockDto> locks, IMongoCollection <NotificationDto> notifications, MongoStorageOptions storageOptions, IDistributedLockMutex mutex) { _resource = resource ?? throw new ArgumentNullException(nameof(resource)); _locks = locks ?? throw new ArgumentNullException(nameof(locks)); _notifications = notifications; _storageOptions = storageOptions ?? throw new ArgumentNullException(nameof(storageOptions)); _mutex = mutex; if (string.IsNullOrEmpty(resource)) { throw new ArgumentException($@"The {nameof(resource)} cannot be empty", nameof(resource)); } if (timeout.TotalSeconds > int.MaxValue) { throw new ArgumentException($"The timeout specified is too large. Please supply a timeout equal to or less than {int.MaxValue} seconds", nameof(timeout)); } if (!AcquiredLocks.Value.ContainsKey(_resource) || AcquiredLocks.Value[_resource] == 0) { Cleanup(); Acquire(timeout); AcquiredLocks.Value[_resource] = 1; StartHeartBeat(); } else { AcquiredLocks.Value[_resource]++; } }
/// <summary> /// Creates MongoDB distributed lock /// </summary> /// <param name="resource">Lock resource</param> /// <param name="timeout">Lock timeout</param> /// <param name="dbContext">Lock Database</param> /// <param name="storageOptions">Database options</param> /// <param name="mutex"></param> /// <exception cref="DistributedLockTimeoutException">Thrown if lock is not acquired within the timeout</exception> /// <exception cref="MongoDistributedLockException">Thrown if other mongo specific issue prevented the lock to be acquired</exception> public MongoDistributedLock(string resource, TimeSpan timeout, HangfireDbContext dbContext, MongoStorageOptions storageOptions, IDistributedLockMutex mutex) : this(resource, timeout, dbContext?.DistributedLock, dbContext?.Notifications, storageOptions, mutex) { }
private Task[] CreateWaitTasks(string resource, int count, IDistributedLockMutex mutex) { var tasks = new Task[count]; for (int i = 0; i < count; i++) { tasks[i] = Task.Factory.StartNew(() => { mutex.Wait(resource, TimeSpan.FromSeconds(2)); }, TaskCreationOptions.LongRunning); } do { // wait until all tasks are running Thread.Sleep(100); } while (tasks.Any(t => t.Status != TaskStatus.Running)); return(tasks); }
/// <summary> /// Creates MongoDB distributed lock /// </summary> /// <param name="resource">Lock resource</param> /// <param name="timeout">Lock timeout</param> /// <param name="dbContext"></param> /// <param name="storageOptions">Database options</param> /// <param name="mutex"></param> /// <exception cref="DistributedLockTimeoutException">Thrown if lock is not acquired within the timeout</exception> /// <exception cref="MongoDistributedLockException">Thrown if other mongo specific issue prevented the lock to be acquired</exception> public MongoDistributedLock(string resource, TimeSpan timeout, HangfireDbContext dbContext, MongoStorageOptions storageOptions, IDistributedLockMutex mutex) { _resource = resource ?? throw new ArgumentNullException(nameof(resource)); _timeout = timeout; _dbContext = dbContext ?? throw new ArgumentNullException(nameof(dbContext)); _storageOptions = storageOptions ?? throw new ArgumentNullException(nameof(storageOptions)); _mutex = mutex; if (string.IsNullOrEmpty(resource)) { throw new ArgumentException($@"The {nameof(resource)} cannot be empty", nameof(resource)); } if (timeout.TotalSeconds > int.MaxValue) { throw new ArgumentException($"The timeout specified is too large. Please supply a timeout equal to or less than {int.MaxValue} seconds", nameof(timeout)); } }