public MongoJobQueueMonitoringApi(HangfireDbContext connection) { if (connection == null) throw new ArgumentNullException("connection"); _connection = connection; }
private static void RecreateDatabaseAndInstallObjects() { using (HangfireDbContext context = new HangfireDbContext(ConnectionUtils.GetConnectionString(), ConnectionUtils.GetDatabaseName())) { try { context.Init(); List<Task> tasks = new List<Task>(); tasks.Add(context.Identifiers.DeleteManyAsync(new BsonDocument())); tasks.Add(context.DistributedLock.DeleteManyAsync(new BsonDocument())); tasks.Add(context.AggregatedCounter.DeleteManyAsync(new BsonDocument())); tasks.Add(context.Counter.DeleteManyAsync(new BsonDocument())); tasks.Add(context.Hash.DeleteManyAsync(new BsonDocument())); tasks.Add(context.Job.DeleteManyAsync(new BsonDocument())); tasks.Add(context.JobParameter.DeleteManyAsync(new BsonDocument())); tasks.Add(context.JobQueue.DeleteManyAsync(new BsonDocument())); tasks.Add(context.List.DeleteManyAsync(new BsonDocument())); tasks.Add(context.Server.DeleteManyAsync(new BsonDocument())); tasks.Add(context.Set.DeleteManyAsync(new BsonDocument())); tasks.Add(context.State.DeleteManyAsync(new BsonDocument())); Task.WaitAll(tasks.ToArray()); } catch (MongoException ex) { throw new InvalidOperationException("Unable to cleanup database.", ex); } } }
private static void RecreateDatabaseAndInstallObjects() { using (HangfireDbContext context = new HangfireDbContext(ConnectionUtils.GetConnectionString(), ConnectionUtils.GetDatabaseName())) { context.Init(); MongoCollection[] collections = { context.DistributedLock, context.Counter, context.Hash, context.Job, context.JobParameter, context.JobQueue, context.List, context.Server, context.Set, context.State }; foreach (MongoCollection collection in collections) { WriteConcernResult result = collection.RemoveAll(); if (result.Ok == false) throw new InvalidOperationException("Unable to cleanup database."); } } }
public MongoJobQueue(HangfireDbContext connection, MongoStorageOptions options) { if (options == null) throw new ArgumentNullException("options"); if (connection == null) throw new ArgumentNullException("connection"); _options = options; _connection = connection; }
public MongoWriteOnlyTransaction(HangfireDbContext connection, PersistentJobQueueProviderCollection queueProviders) { if (connection == null) throw new ArgumentNullException("connection"); if (queueProviders == null) throw new ArgumentNullException("queueProviders"); _connection = connection; _queueProviders = queueProviders; }
/// <summary> /// Constructs fetched job by database connection, identifier, job ID and queue /// </summary> /// <param name="connection">Database connection</param> /// <param name="id">Identifier</param> /// <param name="jobId">Job ID</param> /// <param name="queue">Queue name</param> public MongoFetchedJob(HangfireDbContext connection, int id, string jobId, string queue) { if (connection == null) throw new ArgumentNullException("connection"); if (jobId == null) throw new ArgumentNullException("jobId"); if (queue == null) throw new ArgumentNullException("queue"); _connection = connection; Id = id; JobId = jobId; Queue = queue; }
public MongoConnection(HangfireDbContext database, MongoStorageOptions options, PersistentJobQueueProviderCollection queueProviders) { if (database == null) throw new ArgumentNullException("database"); if (queueProviders == null) throw new ArgumentNullException("queueProviders"); if (options == null) throw new ArgumentNullException("options"); _database = database; _options = options; _queueProviders = queueProviders; }
/// <summary> /// Constructs Job Storage by database connection string, name andoptions /// </summary> /// <param name="connectionString">MongoDB connection string</param> /// <param name="databaseName">Database name</param> /// <param name="options">Storage options</param> public MongoStorage(string connectionString, string databaseName, MongoStorageOptions options) { if (String.IsNullOrWhiteSpace(connectionString) == true) throw new ArgumentNullException("connectionString"); if (String.IsNullOrWhiteSpace(databaseName) == true) throw new ArgumentNullException("databaseName"); if (options == null) throw new ArgumentNullException("options"); _connectionString = connectionString; _databaseName = databaseName; _options = options; Connection = new HangfireDbContext(connectionString, databaseName, options.Prefix); var defaultQueueProvider = new MongoJobQueueProvider(options); QueueProviders = new PersistentJobQueueProviderCollection(defaultQueueProvider); }
public static HangfireDbContext CreateConnection() { HangfireDbContext connection = new HangfireDbContext(GetConnectionString(), GetDatabaseName()); return connection; }
private static MongoJobQueue CreateJobQueue(HangfireDbContext connection) { return new MongoJobQueue(connection, new MongoStorageOptions()); }
private static dynamic GetTestHash(HangfireDbContext database, string key) { return database.Hash.Find(Builders<HashDto>.Filter.Eq(_ => _.Key, key)).FirstOrDefault(); }
private static MongoJobQueueMonitoringApi CreateMongoJobQueueMonitoringApi(HangfireDbContext connection) { return new MongoJobQueueMonitoringApi(connection); }
private static JobQueueDto CreateJobQueueDto(HangfireDbContext connection, string queue, bool isFetched) { var state = new StateDto(); AsyncHelper.RunSync(() => connection.State.InsertOneAsync(state)); var job = new JobDto { CreatedAt = connection.GetServerTimeUtc(), StateId = state.Id }; AsyncHelper.RunSync(() => connection.Job.InsertOneAsync(job)); var jobQueue = new JobQueueDto { Queue = queue, JobId = job.Id }; if (isFetched) { jobQueue.FetchedAt = connection.GetServerTimeUtc().AddDays(-1); } AsyncHelper.RunSync(() => connection.JobQueue.InsertOneAsync(jobQueue)); return jobQueue; }
private JobDto CreateJobInState(HangfireDbContext database, int jobId, string stateName) { var job = Job.FromExpression(() => SampleMethod("wrong")); var jobState = new StateDto { CreatedAt = database.GetServerTimeUtc(), Data = stateName == EnqueuedState.StateName ? string.Format(" {{ 'EnqueuedAt': '{0}' }}", database.GetServerTimeUtc().ToString("o")) : "{}", JobId = jobId }; database.State.InsertOne(jobState); var jobDto = new JobDto { Id = jobId, InvocationData = JobHelper.ToJson(InvocationData.Serialize(job)), Arguments = "['Arguments']", StateName = stateName, CreatedAt = database.GetServerTimeUtc(), StateId = jobState.Id }; database.Job.InsertOne(jobDto); var jobQueueDto = new JobQueueDto { FetchedAt = null, Id = jobId * 10, JobId = jobId, Queue = DefaultQueue }; if (stateName == FetchedStateName) { jobQueueDto.FetchedAt = database.GetServerTimeUtc(); } database.JobQueue.InsertOne(jobQueueDto); return jobDto; }
private static dynamic GetTestJob(HangfireDbContext database, int jobId) { return database.Job.FindOneById(jobId); }
private static dynamic GetTestJob(HangfireDbContext database, int jobId) { return AsyncHelper.RunSync(() => database.Job.Find(Builders<JobDto>.Filter.Eq(_ => _.Id, jobId)).FirstOrDefaultAsync()); }
private static bool IsEntryExpired(HangfireDbContext connection, ObjectId entryId) { var count = connection.Counter.Count(Query<CounterDto>.EQ(_ => _.Id, entryId)); return count == 0; }
private static int CreateJobQueueRecord(HangfireDbContext connection, string jobId, string queue) { var jobQueue = new JobQueueDto { JobId = int.Parse(jobId), Queue = queue, FetchedAt = connection.GetServerTimeUtc() }; connection.JobQueue.Insert(jobQueue); return jobQueue.Id; }
public MongoConnection(HangfireDbContext database, PersistentJobQueueProviderCollection queueProviders) : this(database, new MongoStorageOptions(), queueProviders) { }
private static ObjectId CreateExpirationEntry(HangfireDbContext connection, DateTime? expireAt) { var counter = new AggregatedCounterDto { Id = ObjectId.GenerateNewId(), Key = "key", Value = 1, ExpireAt = expireAt }; connection.AggregatedCounter.InsertOne(counter); var id = counter.Id; return id; }
public MongoDistributedLock(string resource, TimeSpan timeout, HangfireDbContext database, MongoStorageOptions options) { if (String.IsNullOrEmpty(resource) == true) throw new ArgumentNullException("resource"); if (database == null) throw new ArgumentNullException("database"); if (options == null) throw new ArgumentNullException("options"); _resource = resource; _database = database; _options = options; try { // Remove dead locks database.DistributedLock.Remove(Query.And(Query<DistributedLockDto>.EQ(_ => _.Resource, resource), Query<DistributedLockDto>.LT(_ => _.Heartbeat, database.GetServerTimeUtc().Subtract(options.DistributedLockLifetime)))); // Check lock DateTime lockTimeoutTime = DateTime.Now.Add(timeout); bool isLockedBySomeoneElse; bool isFirstAttempt = true; do { isLockedBySomeoneElse = database .DistributedLock .FindOne(Query.And(Query<DistributedLockDto>.EQ(_ => _.Resource, resource), Query<DistributedLockDto>.NE(_ => _.ClientId, _options.ClientId))) != null; if (isFirstAttempt == true) isFirstAttempt = false; else Thread.Sleep((int)timeout.TotalMilliseconds / 10); } while ((isLockedBySomeoneElse == true) && (lockTimeoutTime >= DateTime.Now)); // Set lock if (isLockedBySomeoneElse == false) { database.DistributedLock.FindAndModify(new FindAndModifyArgs { Query = Query<DistributedLockDto>.EQ(_ => _.Resource, resource), Update = Update.Combine( Update<DistributedLockDto>.Set(_ => _.ClientId, _options.ClientId), Update<DistributedLockDto>.Inc(_ => _.LockCount, 1), Update<DistributedLockDto>.Set(_ => _.Heartbeat, database.GetServerTimeUtc()) ), Upsert = true }); StartHeartBeat(); } else { throw new MongoDistributedLockException(String.Format("Could not place a lock on the resource '{0}': {1}.", _resource, "The lock request timed out")); } } catch (Exception ex) { if (ex is MongoDistributedLockException) throw; else throw new MongoDistributedLockException(String.Format("Could not place a lock on the resource '{0}': {1}.", _resource, "Check inner exception for details"), ex); } }
private static IList<SetDto> GetTestSet(HangfireDbContext database, string key) { return database.Set.Find(Builders<SetDto>.Filter.Eq(_ => _.Key, key)).ToList(); }
public IPersistentJobQueue GetJobQueue(HangfireDbContext connection) { return new MongoJobQueue(connection, _options); }
/// <summary> /// Creates MongoDB distributed lock /// </summary> /// <param name="resource">Lock resource</param> /// <param name="timeout">Lock timeout</param> /// <param name="database">Lock database</param> /// <param name="options">Database options</param> public MongoDistributedLock(string resource, TimeSpan timeout, HangfireDbContext database, MongoStorageOptions options) { if (String.IsNullOrEmpty(resource) == true) throw new ArgumentNullException("resource"); if (database == null) throw new ArgumentNullException("database"); if (options == null) throw new ArgumentNullException("options"); _resource = resource; _database = database; _options = options; try { // Remove dead locks database.DistributedLock.DeleteManyAsync( Builders<DistributedLockDto>.Filter.Eq(_ => _.Resource, resource) & Builders<DistributedLockDto>.Filter.Lt(_ => _.Heartbeat, database.GetServerTimeUtc().Subtract(options.DistributedLockLifetime))); // Check lock DateTime lockTimeoutTime = DateTime.Now.Add(timeout); bool isLockedBySomeoneElse; bool isFirstAttempt = true; do { isLockedBySomeoneElse = AsyncHelper.RunSync(() => database.DistributedLock .Find(Builders<DistributedLockDto>.Filter.Eq(_ => _.Resource, resource) & Builders<DistributedLockDto>.Filter.Ne(_ => _.ClientId, _options.ClientId)) .FirstOrDefaultAsync()) != null; if (isFirstAttempt == true) isFirstAttempt = false; else Thread.Sleep((int)timeout.TotalMilliseconds / 10); } while ((isLockedBySomeoneElse == true) && (lockTimeoutTime >= DateTime.Now)); // Set lock if (isLockedBySomeoneElse == false) { AsyncHelper.RunSync(() => database.DistributedLock.FindOneAndUpdateAsync( Builders<DistributedLockDto>.Filter.Eq(_ => _.Resource, resource), Builders<DistributedLockDto>.Update.Combine( Builders<DistributedLockDto>.Update.Set(_ => _.ClientId, _options.ClientId), Builders<DistributedLockDto>.Update.Inc(_ => _.LockCount, 1), Builders<DistributedLockDto>.Update.Set(_ => _.Heartbeat, database.GetServerTimeUtc()) ), new FindOneAndUpdateOptions<DistributedLockDto> { IsUpsert = true })); StartHeartBeat(); } else { throw new MongoDistributedLockException(String.Format("Could not place a lock on the resource '{0}': {1}.", _resource, "The lock request timed out")); } } catch (Exception ex) { if (ex is MongoDistributedLockException) throw; else throw new MongoDistributedLockException(String.Format("Could not place a lock on the resource '{0}': {1}.", _resource, "Check inner exception for details"), ex); } }
private void Commit(HangfireDbContext connection, Action<MongoWriteOnlyTransaction> action) { using (MongoWriteOnlyTransaction transaction = new MongoWriteOnlyTransaction(connection, _queueProviders)) { action(transaction); transaction.Commit(); } }
public IPersistentJobQueueMonitoringApi GetJobQueueMonitoringApi(HangfireDbContext connection) { return new MongoJobQueueMonitoringApi(connection); }
private static bool IsEntryExpired(HangfireDbContext connection, ObjectId entryId) { var count = connection.AggregatedCounter.Find(Builders<AggregatedCounterDto>.Filter.Eq(_ => _.Id, entryId)).Count(); return count == 0; }
private static dynamic GetTestJob(HangfireDbContext database, int jobId) { return database.Job.Find(Builders<JobDto>.Filter.Eq(_ => _.Id, jobId)).FirstOrDefault(); }