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);
			});
		}
Пример #2
0
        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();
        }
Пример #3
0
		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();
		}
Пример #4
0
        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);
            });
        }
Пример #5
0
        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);
            });
        }
Пример #6
0
        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));
            });
        }
Пример #13
0
        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);
            });
        }
Пример #14
0
        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);
            });
        }
Пример #16
0
        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);
            });
        }