public void ExpireJob_SetsJobExpirationData() { UseConnection(database => { JobDto job = new JobDto { Id = 1, InvocationData = "", Arguments = "", CreatedAt = database.GetServerTimeUtc() }; database.Job.Insert(job); JobDto anotherJob = new JobDto { Id = 2, InvocationData = "", Arguments = "", CreatedAt = database.GetServerTimeUtc() }; database.Job.Insert(anotherJob); var jobId = job.Id; var anotherJobId = anotherJob.Id; Commit(database, x => x.ExpireJob(jobId.ToString(), TimeSpan.FromDays(1))); var testJob = GetTestJob(database, jobId); Assert.True(database.GetServerTimeUtc().AddMinutes(-1) < testJob.ExpireAt && testJob.ExpireAt <= database.GetServerTimeUtc().AddDays(1)); var anotherTestJob = GetTestJob(database, anotherJobId); Assert.Null(anotherTestJob.ExpireAt); }); }
public override string CreateExpiredJob(Job job, IDictionary<string, string> parameters, DateTime createdAt, TimeSpan expireIn) { if (job == null) throw new ArgumentNullException("job"); if (parameters == null) throw new ArgumentNullException("parameters"); var invocationData = InvocationData.Serialize(job); var jobDto = new JobDto { InvocationData = JobHelper.ToJson(invocationData), Arguments = invocationData.Arguments, CreatedAt = createdAt, ExpireAt = createdAt.Add(expireIn) }; AsyncHelper.RunSync(() => _database.Job.InsertOneAsync(jobDto)); var jobId = jobDto.Id; if (parameters.Count > 0) { Task.WaitAll(parameters .Select(parameter => _database .JobParameter .InsertOneAsync(new JobParameterDto { JobId = jobId, Name = parameter.Key, Value = parameter.Value })) .ToArray()); } return jobId.ToString(); }
public string CreateExpiredJob(Job job, IDictionary<string, string> parameters, DateTime createdAt, TimeSpan expireIn) { if (job == null) throw new ArgumentNullException("job"); if (parameters == null) throw new ArgumentNullException("parameters"); var invocationData = InvocationData.Serialize(job); var jobDto = new JobDto { InvocationData = JobHelper.ToJson(invocationData), Arguments = invocationData.Arguments, CreatedAt = createdAt, ExpireAt = createdAt.Add(expireIn) }; _database.Job.Insert(jobDto); var jobId = jobDto.Id; if (parameters.Count > 0) { foreach (var parameter in parameters) { _database.JobParameter.Insert(new JobParameterDto { JobId = jobId, Name = parameter.Key, Value = parameter.Value }); } } return jobId.ToString(); }
public void Dequeue_ShouldSetFetchedAt_OnlyForTheFetchedJob() { // Arrange UseConnection(connection => { var job1 = new JobDto { InvocationData = "", Arguments = "", CreatedAt = connection.GetServerTimeUtc() }; connection.Job.InsertOne(job1); var job2 = new JobDto { InvocationData = "", Arguments = "", CreatedAt = connection.GetServerTimeUtc() }; connection.Job.InsertOne(job2); connection.JobQueue.InsertOne(new JobQueueDto { JobId = job1.Id, Queue = "default" }); connection.JobQueue.InsertOne(new JobQueueDto { JobId = job2.Id, Queue = "default" }); var queue = CreateJobQueue(connection); // Act var payload = queue.Dequeue(DefaultQueues, CreateTimingOutCancellationToken()); // Assert var otherJobFetchedAt = connection.JobQueue.Find(Builders<JobQueueDto>.Filter.Ne(_ => _.JobId, int.Parse(payload.JobId))).FirstOrDefault().FetchedAt; Assert.Null(otherJobFetchedAt); }); }
public void Dequeue_ShouldFetchATimedOutJobs_FromTheSpecifiedQueue() { // Arrange UseConnection(connection => { var job = new JobDto { InvocationData = "", Arguments = "", CreatedAt = connection.GetServerTimeUtc() }; connection.Job.InsertOne(job); var jobQueue = new JobQueueDto { JobId = job.Id, Queue = "default", FetchedAt = connection.GetServerTimeUtc().AddDays(-1) }; connection.JobQueue.InsertOne(jobQueue); var queue = CreateJobQueue(connection); // Act var payload = queue.Dequeue(DefaultQueues, CreateTimingOutCancellationToken()); // Assert Assert.NotEmpty(payload.JobId); }); }
public void Dequeue_ShouldLeaveJobInTheQueue_ButSetItsFetchedAtValue() { // Arrange UseConnection(connection => { var job = new JobDto { InvocationData = "", Arguments = "", CreatedAt = connection.GetServerTimeUtc() }; connection.Job.InsertOne(job); var jobQueue = new JobQueueDto { JobId = job.Id, Queue = "default" }; connection.JobQueue.InsertOne(jobQueue); var queue = CreateJobQueue(connection); // Act var payload = queue.Dequeue(DefaultQueues, CreateTimingOutCancellationToken()); // Assert Assert.NotNull(payload); var fetchedAt = connection.JobQueue.Find(Builders<JobQueueDto>.Filter.Eq(_ => _.JobId, int.Parse(payload.JobId))).FirstOrDefault().FetchedAt; Assert.NotNull(fetchedAt); Assert.True(fetchedAt > DateTime.UtcNow.AddMinutes(-1)); }); }
public void Dequeue_ShouldFetchJobs_FromMultipleQueues() { UseConnection(connection => { var job1 = new JobDto { InvocationData = "", Arguments = "", CreatedAt = connection.GetServerTimeUtc() }; AsyncHelper.RunSync(() => connection.Job.InsertOneAsync(job1)); var job2 = new JobDto { InvocationData = "", Arguments = "", CreatedAt = connection.GetServerTimeUtc() }; AsyncHelper.RunSync(() => connection.Job.InsertOneAsync(job2)); AsyncHelper.RunSync(() => connection.JobQueue.InsertOneAsync(new JobQueueDto { JobId = job1.Id, Queue = "critical" })); AsyncHelper.RunSync(() => connection.JobQueue.InsertOneAsync(new JobQueueDto { JobId = job2.Id, Queue = "default" })); var queue = CreateJobQueue(connection); var critical = (MongoFetchedJob)queue.Dequeue( new[] { "critical", "default" }, CreateTimingOutCancellationToken()); Assert.NotNull(critical.JobId); Assert.Equal("critical", critical.Queue); var @default = (MongoFetchedJob)queue.Dequeue( new[] { "critical", "default" }, CreateTimingOutCancellationToken()); Assert.NotNull(@default.JobId); Assert.Equal("default", @default.Queue); }); }
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; }
public void SetParameter_UpdatesValue_WhenParameterWithTheGivenName_AlreadyExists() { UseConnection((database, connection) => { var jobDto = new JobDto { Id = 1, InvocationData = "", Arguments = "", CreatedAt = database.GetServerTimeUtc() }; AsyncHelper.RunSync(() => database.Job.InsertOneAsync(jobDto)); string jobId = jobDto.Id.ToString(); connection.SetJobParameter(jobId, "Name", "Value"); connection.SetJobParameter(jobId, "Name", "AnotherValue"); var parameter = AsyncHelper.RunSync(() => database.JobParameter.Find(Builders<JobParameterDto>.Filter.Eq(_ => _.JobId, int.Parse(jobId)) & Builders<JobParameterDto>.Filter.Eq(_ => _.Name, "Name")).FirstOrDefaultAsync()); Assert.Equal("AnotherValue", parameter.Value); }); }
public void GetJobData_ReturnsJobLoadException_IfThereWasADeserializationException() { UseConnection((database, connection) => { var jobDto = new JobDto { Id = 1, InvocationData = JobHelper.ToJson(new InvocationData(null, null, null, null)), Arguments = "['Arguments']", StateName = "Succeeded", CreatedAt = database.GetServerTimeUtc() }; AsyncHelper.RunSync(() => database.Job.InsertOneAsync(jobDto)); var jobId = jobDto.Id; var result = connection.GetJobData(jobId.ToString()); Assert.NotNull(result.LoadException); }); }
public void GetStateData_ReturnsCorrectData() { UseConnection((database, connection) => { var data = new Dictionary<string, string> { { "Key", "Value" } }; var jobDto = new JobDto { Id = 1, InvocationData = "", Arguments = "", StateName = "", CreatedAt = database.GetServerTimeUtc() }; AsyncHelper.RunSync(() => database.Job.InsertOneAsync(jobDto)); var jobId = jobDto.Id; AsyncHelper.RunSync(() => database.State.InsertOneAsync(new StateDto { Id = ObjectId.GenerateNewId(), JobId = jobId, Name = "old-state", CreatedAt = database.GetServerTimeUtc() })); var stateDto = new StateDto { Id = ObjectId.GenerateNewId(), JobId = jobId, Name = "Name", Reason = "Reason", Data = JobHelper.ToJson(data), CreatedAt = database.GetServerTimeUtc() }; AsyncHelper.RunSync(() => database.State.InsertOneAsync(stateDto)); jobDto.StateId = stateDto.Id; AsyncHelper.RunSync(() => database.Job.ReplaceOneAsync(_ => _.Id == jobDto.Id, jobDto, new UpdateOptions())); var result = connection.GetStateData(jobId.ToString()); Assert.NotNull(result); Assert.Equal("Name", result.Name); Assert.Equal("Reason", result.Reason); Assert.Equal("Value", result.Data["Key"]); }); }
public void GetJobData_ReturnsResult_WhenJobExists() { UseConnection((database, connection) => { var job = Job.FromExpression(() => SampleMethod("wrong")); var jobDto = new JobDto { Id = 1, InvocationData = JobHelper.ToJson(InvocationData.Serialize(job)), Arguments = "['Arguments']", StateName = "Succeeded", CreatedAt = database.GetServerTimeUtc() }; AsyncHelper.RunSync(() => database.Job.InsertOneAsync(jobDto)); var result = connection.GetJobData(jobDto.Id.ToString()); Assert.NotNull(result); Assert.NotNull(result.Job); Assert.Equal("Succeeded", result.State); Assert.Equal("Arguments", result.Job.Args[0]); Assert.Null(result.LoadException); Assert.True(database.GetServerTimeUtc().AddMinutes(-1) < result.CreatedAt); Assert.True(result.CreatedAt < DateTime.UtcNow.AddMinutes(1)); }); }
public void SetParameters_CreatesNewParameter_WhenParameterWithTheGivenNameDoesNotExists() { UseConnection((database, connection) => { var jobDto = new JobDto { Id = 1, InvocationData = "", Arguments = "", CreatedAt = database.GetServerTimeUtc() }; database.Job.InsertOne(jobDto); string jobId = jobDto.Id.ToString(); connection.SetJobParameter(jobId, "Name", "Value"); var parameter = database.JobParameter.Find(Builders<JobParameterDto>.Filter.Eq(_ => _.JobId, int.Parse(jobId)) & Builders<JobParameterDto>.Filter.Eq(_ => _.Name, "Name")).FirstOrDefault(); Assert.Equal("Value", parameter.Value); }); }
public void Dequeue_ShouldFetchJobs_OnlyFromSpecifiedQueues() { UseConnection(connection => { var job1 = new JobDto { InvocationData = "", Arguments = "", CreatedAt = connection.GetServerTimeUtc() }; connection.Job.InsertOne(job1); connection.JobQueue.InsertOne(new JobQueueDto { JobId = job1.Id, Queue = "critical" }); var queue = CreateJobQueue(connection); Assert.Throws<OperationCanceledException>(() => queue.Dequeue(DefaultQueues, CreateTimingOutCancellationToken())); }); }
public void SetParameter_CanAcceptNulls_AsValues() { UseConnection((database, connection) => { var jobDto = new JobDto { Id = 1, InvocationData = "", Arguments = "", CreatedAt = database.GetServerTimeUtc() }; AsyncHelper.RunSync(() => database.Job.InsertOneAsync(jobDto)); string jobId = jobDto.Id.ToString(); connection.SetJobParameter(jobId, "Name", null); var parameter = AsyncHelper.RunSync(() => database.JobParameter.Find(Builders<JobParameterDto>.Filter.Eq(_ => _.JobId, int.Parse(jobId)) & Builders<JobParameterDto>.Filter.Eq(_ => _.Name, "Name")).FirstOrDefaultAsync()); Assert.Equal(null, parameter.Value); }); }
public void Dequeue_ShouldFetchJobs_FromMultipleQueuesBasedOnQueuePriority() { UseConnection(connection => { var criticalJob = new JobDto { InvocationData = "", Arguments = "", CreatedAt = connection.GetServerTimeUtc() }; connection.Job.InsertOne(criticalJob); var defaultJob = new JobDto { InvocationData = "", Arguments = "", CreatedAt = connection.GetServerTimeUtc() }; connection.Job.InsertOne(defaultJob); connection.JobQueue.InsertOne(new JobQueueDto { JobId = defaultJob.Id, Queue = "default" }); connection.JobQueue.InsertOne(new JobQueueDto { JobId = criticalJob.Id, Queue = "critical" }); var queue = CreateJobQueue(connection); var critical = (MongoFetchedJob)queue.Dequeue( new[] { "critical", "default" }, CreateTimingOutCancellationToken()); Assert.NotNull(critical.JobId); Assert.Equal("critical", critical.Queue); var @default = (MongoFetchedJob)queue.Dequeue( new[] { "critical", "default" }, CreateTimingOutCancellationToken()); Assert.NotNull(@default.JobId); Assert.Equal("default", @default.Queue); }); }
public void GetParameter_ReturnsParameterValue_WhenJobExists() { UseConnection((database, connection) => { var jobDto = new JobDto { Id = 1, InvocationData = "", Arguments = "", CreatedAt = database.GetServerTimeUtc() }; AsyncHelper.RunSync(() => database.Job.InsertOneAsync(jobDto)); string jobId = jobDto.Id.ToString(); AsyncHelper.RunSync(() => database.JobParameter.InsertOneAsync(new JobParameterDto { Id = ObjectId.GenerateNewId(), JobId = int.Parse(jobId), Name = "name", Value = "value" })); var value = connection.GetJobParameter(jobId, "name"); Assert.Equal("value", value); }); }
public void AddJobState_JustAddsANewRecordInATable() { UseConnection(database => { JobDto job = new JobDto { Id = 1, InvocationData = "", Arguments = "", CreatedAt = database.GetServerTimeUtc() }; database.Job.Insert(job); var jobId = job.Id; var state = new Mock<IState>(); state.Setup(x => x.Name).Returns("State"); state.Setup(x => x.Reason).Returns("Reason"); state.Setup(x => x.SerializeData()) .Returns(new Dictionary<string, string> { { "Name", "Value" } }); Commit(database, x => x.AddJobState(jobId.ToString(), state.Object)); var testJob = GetTestJob(database, jobId); Assert.Null(testJob.StateName); Assert.Equal(ObjectId.Empty, testJob.StateId); StateDto jobState = database.State.FindAll().Single(); Assert.Equal(jobId, jobState.JobId); Assert.Equal("State", jobState.Name); Assert.Equal("Reason", jobState.Reason); Assert.NotNull(jobState.CreatedAt); Assert.Equal("{\"Name\":\"Value\"}", jobState.Data); }); }
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; }
public void PersistJob_ClearsTheJobExpirationData() { UseConnection(database => { JobDto job = new JobDto { Id = 1, InvocationData = "", Arguments = "", CreatedAt = database.GetServerTimeUtc(), ExpireAt = database.GetServerTimeUtc() }; database.Job.Insert(job); JobDto anotherJob = new JobDto { Id = 2, InvocationData = "", Arguments = "", CreatedAt = database.GetServerTimeUtc(), ExpireAt = database.GetServerTimeUtc() }; database.Job.Insert(anotherJob); var jobId = job.Id; var anotherJobId = anotherJob.Id; Commit(database, x => x.PersistJob(jobId.ToString())); var testjob = GetTestJob(database, jobId); Assert.Null(testjob.ExpireAt); var anotherTestJob = GetTestJob(database, anotherJobId); Assert.NotNull(anotherTestJob.ExpireAt); }); }
public void SetJobState_AppendsAStateAndSetItToTheJob() { UseConnection(database => { JobDto job = new JobDto { Id = 1, InvocationData = "", Arguments = "", CreatedAt = database.GetServerTimeUtc() }; AsyncHelper.RunSync(() => database.Job.InsertOneAsync(job)); JobDto anotherJob = new JobDto { Id = 2, InvocationData = "", Arguments = "", CreatedAt = database.GetServerTimeUtc() }; AsyncHelper.RunSync(() => database.Job.InsertOneAsync(anotherJob)); var jobId = job.Id; var anotherJobId = anotherJob.Id; var state = new Mock<IState>(); state.Setup(x => x.Name).Returns("State"); state.Setup(x => x.Reason).Returns("Reason"); state.Setup(x => x.SerializeData()) .Returns(new Dictionary<string, string> { { "Name", "Value" } }); Commit(database, x => x.SetJobState(jobId.ToString(), state.Object)); var testJob = GetTestJob(database, jobId); Assert.Equal("State", testJob.StateName); Assert.NotNull(testJob.StateId); var anotherTestJob = GetTestJob(database, anotherJobId); Assert.Null(anotherTestJob.StateName); Assert.Equal(ObjectId.Empty, anotherTestJob.StateId); StateDto jobState = AsyncHelper.RunSync(() => database.State.Find(new BsonDocument()).ToListAsync()).Single(); Assert.Equal(jobId, jobState.JobId); Assert.Equal("State", jobState.Name); Assert.Equal("Reason", jobState.Reason); Assert.NotNull(jobState.CreatedAt); Assert.Equal("{\"Name\":\"Value\"}", jobState.Data); }); }