public void Dequeue_ShouldFetchATimedOutJobs_FromTheSpecifiedQueue() { // Arrange UseConnection(connection => { var job = new HangfireJob() { InvocationData = "", Arguments = "", CreatedAt = DateTime.UtcNow }; connection.Database.Insert(job); var jobQueue = new JobQueue { JobId = job.Id, Queue = "default", FetchedAt = DateTime.UtcNow.AddDays(-1) }; connection.Database.Insert(jobQueue); var queue = CreateJobQueue(connection); // Act var payload = queue.Dequeue(DefaultQueues, CreateTimingOutCancellationToken()); // Assert Assert.NotEmpty(payload.JobId); }); }
public void QueueHangfire_WaitForJobToComplete_ZeroTimeout() { using (var server = new TestBackgroundJobServer(FileSystem, ServiceHost.HangfireTest)) { server.Should().NotBeNull(); const string testValue = "TestValue"; var hangFireJob = new HangfireJob(testValue); var jobIdString = BackgroundJob.Enqueue <IHangFireTestService>(service => service.ExecuteHangfireInfiniteJobAsync(hangFireJob)); CancellationTokenSource cts = new CancellationTokenSource(); jobIdString.Should().NotBeNull(); int.TryParse(jobIdString, out var jobId).Should().BeTrue(); jobId.Should().BeGreaterThan(0); cts.CancelAfter(1000); var monitoringApi = server.MonitoringApi; Func <Task <JobStatus> > fx = async() => await JobQueueClient.WaitForJobToComplete(monitoringApi, jobIdString, 500, cts.Token); fx.Should().Throw <TaskCanceledException>(); BackgroundJob.Delete(jobIdString).Should().BeTrue(); } }
public void Dequeue_FetchesJob_FromTheSpecifiedQueue() { var instance = new EFCoreJobQueue(Storage); string queue = "queue"; var job = new HangfireJob { InvocationData = InvocationDataStub, QueuedJobs = new List <HangfireQueuedJob> { new HangfireQueuedJob { Queue = queue, }, }, }; UseContextSavingChanges(context => context.Add(job)); var result = instance.Dequeue(new[] { queue }, CancellationToken.None); Assert.NotNull(result); var fetchedJob = Assert.IsType <EFCoreFetchedJob>(result); Assert.Equal(job.QueuedJobs.First().Id, fetchedJob.Id); Assert.Equal(queue, fetchedJob.Queue); Assert.Equal(job.Id, fetchedJob.JobId); UseContext(context => { var queueItem = Assert.Single(context.Set <HangfireQueuedJob>()); Assert.Equal(fetchedJob.Id, queueItem.Id); Assert.Equal(fetchedJob.Queue, queueItem.Queue); Assert.Equal(fetchedJob.JobId, queueItem.JobId); Assert.NotNull(queueItem.FetchedAt); }); }
public void Dequeue_ShouldLeaveJobInTheQueue_ButSetItsFetchedAtValue() { // Arrange UseConnection(connection => { var job = new HangfireJob() { InvocationData = "", Arguments = "", CreatedAt = DateTime.UtcNow }; connection.Database.Insert(job); var jobQueue = new JobQueue { JobId = job.Id, Queue = "default" }; connection.Database.Insert(jobQueue); var queue = CreateJobQueue(connection); // Act var payload = queue.Dequeue(DefaultQueues, CreateTimingOutCancellationToken()); var payloadJobId = int.Parse(payload.JobId); // Assert Assert.NotNull(payload); var fetchedAt = connection.JobQueueRepository.FirstOrDefault(_ => _.JobId == payloadJobId).FetchedAt; Assert.NotEqual(fetchedAt, DateTime.MinValue); Assert.True(fetchedAt > DateTime.UtcNow.AddMinutes(-1)); }); }
public void ScheduledJobs_ReturnsCorrectResult() { var now = DateTime.UtcNow; var data = new Dictionary <string, string> { ["EnqueueAt"] = JobHelper.SerializeDateTime(now), ["ScheduledAt"] = JobHelper.SerializeDateTime(now.AddSeconds(1)), }; var invocationData = CreateInvocationData(() => SampleMethod("Arguments")); var jobs = Enumerable.Range(0, 5). Select(x => { var job = new HangfireJob { CreatedAt = now + new TimeSpan(0, 0, x), InvocationData = invocationData, }; var state = new HangfireState { CreatedAt = DateTime.UtcNow, Name = ScheduledState.StateName, Data = SerializationHelper.Serialize(data), }; job.States.Add(state); return(job); }). ToArray(); UseContextSavingChanges(context => { foreach (var job in jobs) { context.Add(job); } context.SaveChanges(); foreach (var job in jobs) { var state = job.States.Single(); job.State = state; job.StateName = state.Name; } }); var result = UseMonitoringApi(instance => instance.ScheduledJobs(1, 2)); Assert.NotNull(result); Assert.Equal(2, result.Count); Assert.All(result, item => { Assert.NotNull(item.Key); var value = item.Value; Assert.NotNull(value); Assert.Equal(now, value.EnqueueAt); Assert.Equal(now.AddSeconds(1), value.ScheduledAt); }); Assert.Equal(jobs[2].Id.ToString(CultureInfo.InvariantCulture), result[1].Key); Assert.Equal(jobs[3].Id.ToString(CultureInfo.InvariantCulture), result[0].Key); }
public async Task QueueHangfire_Run_WaitForJobToComplete_Cancelled() { var webHost = BuildWebHost <StartupHangfireTest>(new string[0]); webHost.Should().NotBeNull().And.Subject.Should().BeAssignableTo <IWebHost>(); var jobQueueClient = webHost.Services.GetService(typeof(IJobQueueClient)).As <IJobQueueClient>(); jobQueueClient.Should().NotBeNull().And.Subject.Should().BeAssignableTo <IJobQueueClient>(); const string testValue = "TestValue"; var hangFireJob = new HangfireJob(testValue); var cts = new CancellationTokenSource(); var jobId = await jobQueueClient.EnqueueAsync <IHangFireTestService>( service => service.ExecuteHangfireTestJobAsync(hangFireJob)); var jobState = await jobQueueClient.GetJobStatusAsync(jobId); jobState.Should().NotBeNull().And.Subject.As <JobStatus>().State.Should().Be(JobState.NotStarted); cts.CancelAfter(5000); Func <Task <JobStatus> > fx = async() => await jobQueueClient.WaitForJobToComplete(jobId, 50 * 1000, cts.Token); fx.Should().Throw <TaskCanceledException>(); }
public void RemoveFromQueue_WhenItemExists() { var job = new HangfireJob { InvocationData = InvocationDataStub, QueuedJobs = new List <HangfireQueuedJob> { new HangfireQueuedJob { Queue = "queue", FetchedAt = DateTime.UtcNow, }, }, }; UseContextSavingChanges(context => context.Add(job)); using var instance = new EFCoreFetchedJob(Storage, job.QueuedJobs.Single()); instance.RemoveFromQueue(); UseContext(context => { Assert.Single(context.Set <HangfireJob>()); Assert.Empty(context.Set <HangfireQueuedJob>()); }); Assert.True(Assert.IsType <bool>( instance.GetFieldValue("_completed"))); Assert.False(Assert.IsType <bool>( instance.GetFieldValue("_disposed"))); }
public void ExpireJob_SetsJobExpirationData() { UseConnection(database => { HangfireJob job = new HangfireJob { InvocationData = "", Arguments = "", CreatedAt = DateTime.UtcNow }; database.Database.Insert(job); HangfireJob anotherJob = new HangfireJob { InvocationData = "", Arguments = "", CreatedAt = DateTime.UtcNow }; database.Database.Insert(anotherJob); var jobId = job.Id.ToString(); var anotherJobId = anotherJob.Id; Commit(database, x => x.ExpireJob(jobId, TimeSpan.FromDays(1))); var testJob = GetTestJob(database, job.Id); Assert.True(DateTime.UtcNow.AddMinutes(-1) < testJob.ExpireAt && testJob.ExpireAt <= DateTime.UtcNow.AddDays(1)); var anotherTestJob = GetTestJob(database, anotherJobId); Assert.Equal(DateTime.MinValue, anotherTestJob.ExpireAt); }); }
public void PersistJob_ClearsTheJobExpirationData() { UseConnection(database => { HangfireJob job = new HangfireJob { InvocationData = "", Arguments = "", CreatedAt = DateTime.UtcNow, ExpireAt = DateTime.UtcNow }; database.Database.Insert(job); HangfireJob anotherJob = new HangfireJob { InvocationData = "", Arguments = "", CreatedAt = DateTime.UtcNow, ExpireAt = DateTime.UtcNow }; database.Database.Insert(anotherJob); var jobId = job.Id.ToString(); var anotherJobId = anotherJob.Id; Commit(database, x => x.PersistJob(jobId)); var testjob = GetTestJob(database, job.Id); Assert.Equal(DateTime.MinValue, testjob.ExpireAt); var anotherTestJob = GetTestJob(database, anotherJobId); Assert.NotEqual(DateTime.MinValue, anotherTestJob.ExpireAt); }); }
public async Task QueueHangfire_Run_Enqueue() { var webHost = BuildWebHost <StartupHangfireTest>(new string[0]); webHost.Should().NotBeNull().And.Subject.Should().BeAssignableTo <IWebHost>(); var jobQueueClient = webHost.Services.GetService(typeof(IJobQueueClient)).As <IJobQueueClient>(); jobQueueClient.Should().NotBeNull().And.Subject.Should().BeAssignableTo <IJobQueueClient>(); const string testValue = "TestValue"; var hangFireJob = new HangfireJob(testValue); var cts = new CancellationTokenSource(); var runTask = webHost.RunAsync(cts.Token); var jobId = await jobQueueClient.EnqueueAsync <IHangFireTestService>( service => service.ExecuteHangfireTestJobAsync(hangFireJob)); var jobState = await jobQueueClient.GetJobStatusAsync(jobId); jobState.Should().NotBeNull().And.Subject.As <JobStatus>().State.Should().Be(JobState.NotStarted); cts.CancelAfter(5000); await runTask; }
private static void AddJobWithStateToContext( HangfireContext context, string stateName, IDictionary <string, string> data = null) { data ??= new Dictionary <string, string>(); var state = new HangfireState { CreatedAt = DateTime.UtcNow, Name = stateName, Data = SerializationHelper.Serialize(data), }; var job = new HangfireJob { CreatedAt = DateTime.UtcNow, InvocationData = CreateInvocationData(() => SampleMethod(null)), States = new[] { state, }, }; context.Add(job); context.SaveChanges(); job.State = state; job.StateName = state.Name; context.SaveChanges(); }
public void JobDetails_ReturnsCorrectResult() { var createdAt = DateTime.UtcNow; var stateCreatedAt = createdAt.AddSeconds(1); var data = new Dictionary <string, string> { ["Name"] = "Value", }; var parameters = new Dictionary <string, string> { ["Key1"] = "Value1", ["Key2"] = "Value2", }; var state = new HangfireState { Name = "State", Reason = "Reason", CreatedAt = stateCreatedAt, Data = SerializationHelper.Serialize(data), }; var job = new HangfireJob { CreatedAt = createdAt, InvocationData = CreateInvocationData(() => SampleMethod("argument")), ExpireAt = createdAt + new TimeSpan(1, 0, 0, 0), States = new[] { state, }, Parameters = parameters. Select(x => new HangfireJobParameter { Name = x.Key, Value = x.Value, }). ToList(), }; UseContextSavingChanges(context => context.Add(job)); var jobId = job.Id.ToString(CultureInfo.InvariantCulture); var result = UseMonitoringApi(instance => instance.JobDetails(jobId)); Assert.NotNull(result); Assert.Equal(createdAt, result.CreatedAt); Assert.Equal(createdAt.AddDays(1), result.ExpireAt); Assert.Equal(typeof(EFCoreStorageTest), result.Job.Type); Assert.Equal(nameof(SampleMethod), result.Job.Method.Name); Assert.Equal(new[] { "argument" }, result.Job.Args); Assert.NotNull(result.History); var historyItem = result.History.Single(); Assert.Equal("State", historyItem.StateName); Assert.Equal("Reason", historyItem.Reason); Assert.Equal(stateCreatedAt, historyItem.CreatedAt); Assert.Equal(data, historyItem.Data); Assert.NotNull(result.Properties); Assert.Equal(parameters, result.Properties); }
public void Dequeue_ShouldFetchJobs_FromMultipleQueuesBasedOnQueuePriority() { UseConnection(connection => { var criticalJob = new HangfireJob() { InvocationData = "", Arguments = "", CreatedAt = DateTime.UtcNow }; connection.Database.Insert(criticalJob); var defaultJob = new HangfireJob() { InvocationData = "", Arguments = "", CreatedAt = DateTime.UtcNow }; connection.Database.Insert(defaultJob); connection.Database.Insert(new JobQueue { JobId = defaultJob.Id, Queue = "default" }); connection.Database.Insert(new JobQueue { JobId = criticalJob.Id, Queue = "critical" }); var queue = CreateJobQueue(connection); var critical = (SQLiteFetchedJob)queue.Dequeue( new[] { "critical", "default" }, CreateTimingOutCancellationToken()); Assert.NotNull(critical.JobId); Assert.Equal("critical", critical.Queue); var @default = (SQLiteFetchedJob)queue.Dequeue( new[] { "critical", "default" }, CreateTimingOutCancellationToken()); Assert.NotNull(@default.JobId); Assert.Equal("default", @default.Queue); }); }
public void SetJobState_AppendsAStateAndSetItToTheJob() { UseConnection(database => { HangfireJob job = new HangfireJob { InvocationData = "", Arguments = "", CreatedAt = DateTime.UtcNow }; database.Database.Insert(job); HangfireJob anotherJob = new HangfireJob { InvocationData = "", Arguments = "", CreatedAt = DateTime.UtcNow }; database.Database.Insert(anotherJob); var serializedData = new Dictionary <string, string> { { "Name", "Value" } }; 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(serializedData); Commit(database, x => x.SetJobState(Convert.ToString(job.Id), state.Object)); var testJob = GetTestJob(database, job.Id); Assert.Equal("State", testJob.StateName); Assert.Equal(1, database.StateRepository.Count(x => x.JobId == testJob.Id)); var anotherTestJob = GetTestJob(database, anotherJob.Id); Assert.Null(anotherTestJob.StateName); Assert.Equal(0, database.StateRepository.Count(x => x.JobId == anotherJob.Id)); var jobWithStates = database.HangfireJobRepository.ToList().FirstOrDefault(); var jobState = database.StateRepository.FirstOrDefault(x => x.JobId == jobWithStates.Id); Assert.Equal("State", jobState.Name); Assert.Equal("Reason", jobState.Reason); Assert.True(jobState.CreatedAt > DateTime.MinValue); Assert.Equal(JsonConvert.SerializeObject(serializedData), jobState.Data); }); }
private static void AddJobWithQueueItemToContext(HangfireContext context, string queue) { var job = new HangfireJob { CreatedAt = DateTime.UtcNow, InvocationData = CreateInvocationData(() => SampleMethod(null)), }; var queueItem = new HangfireQueuedJob { Job = job, Queue = queue, }; context.Add(job); context.Add(queueItem); }
public void Dequeue_ShouldSetFetchedAt_OnlyForTheFetchedJob() { // Arrange UseConnection(connection => { var job1 = new HangfireJob() { InvocationData = "", Arguments = "", CreatedAt = DateTime.UtcNow }; connection.Database.Insert(job1); var job2 = new HangfireJob() { InvocationData = "", Arguments = "", CreatedAt = DateTime.UtcNow }; connection.Database.Insert(job2); connection.Database.Insert(new JobQueue { JobId = job1.Id, Queue = "default" }); connection.Database.Insert(new JobQueue { JobId = job2.Id, Queue = "default" }); var queue = CreateJobQueue(connection); // Act var payload = queue.Dequeue(DefaultQueues, CreateTimingOutCancellationToken()); var payloadJobId = int.Parse(payload.JobId); // Assert var otherJobFetchedAt = connection.JobQueueRepository.FirstOrDefault(_ => _.JobId != payloadJobId).FetchedAt; Assert.Equal(otherJobFetchedAt, DateTime.MinValue); }); }
public override string CreateExpiredJob(Job job, IDictionary <string, string> parameters, DateTime createdAt, TimeSpan expireIn) { if (job == null) { throw new ArgumentNullException(nameof(job)); } if (parameters == null) { throw new ArgumentNullException(nameof(parameters)); } lock (_lock) { var invocationData = InvocationData.SerializeJob(job); var newJob = new HangfireJob() { InvocationData = SerializationHelper.Serialize(invocationData, SerializationOption.User), Arguments = invocationData.Arguments, CreatedAt = createdAt, ExpireAt = createdAt.Add(expireIn) }; DbContext.Database.Insert(newJob); var parametersArray = parameters.ToArray(); foreach (var parameter in parametersArray) { DbContext.Database.Insert(new JobParameter() { JobId = newJob.Id, Name = parameter.Key, Value = parameter.Value }); } var jobId = newJob.Id; return(Convert.ToString(jobId)); } }
public async Task QueueHangfire_BackgroundServer_Run() { using (var server = new TestBackgroundJobServer(FileSystem, ServiceHost.HangfireTest)) { const string testValue = "TestValue"; var hangFireJob = new HangfireJob(testValue); var jobIdString = BackgroundJob.Enqueue <IHangFireTestService>(service => service.ExecuteHangfireTestJobAsync(hangFireJob)); jobIdString.Should().NotBeNull(); var jobStatus = await JobQueueClient.WaitForJobToComplete(server.MonitoringApi, jobIdString, 30 * 1000, CancellationToken.None); jobStatus.State.Should().Be(JobState.Succeeded); server.DeleteBackgroundJob(jobIdString).Should().BeTrue(); } }
public void Enqueue_CompletesSuccessfully_WhenJobExists() { var job = new HangfireJob { InvocationData = InvocationDataStub, }; UseContextSavingChanges(context => context.Add(job)); var instance = new EFCoreJobQueue(Storage); var queue = "queue"; instance.Enqueue(queue, job.Id.ToString(CultureInfo.InvariantCulture)); UseContext(context => { var actual = Assert.Single(context.Set <HangfireQueuedJob>()); Assert.Equal(job.Id, actual.JobId); Assert.Equal(queue, actual.Queue); Assert.Null(actual.FetchedAt); }); }
public async Task QueueHangfire_BackgroundServer_Run() { var builder = new ContainerBuilder(); builder.RegisterType <HangFireTestService>().As <IHangFireTestService>().InstancePerLifetimeScope(); GlobalConfiguration.Configuration.UseAutofacActivator(builder.Build()); var storage = new SQLiteStorage(GetConnectionString(FileSystem, ServiceHost.HangfireTest)); GlobalConfiguration.Configuration.UseStorage(storage); using (var server = new BackgroundJobServer()) { server.Should().NotBeNull(); var monitoringApi = storage.GetMonitoringApi(); monitoringApi.Should().NotBeNull().And.Subject.Should().BeAssignableTo <IMonitoringApi>(); const string testValue = "TestValue"; var hangFireJob = new HangfireJob(testValue); var jobIdString = BackgroundJob.Enqueue <IHangFireTestService>(service => service.ExecuteHangfireTestJobAsync(hangFireJob)); jobIdString.Should().NotBeNull(); int.TryParse(jobIdString, out var jobId).Should().BeTrue(); jobId.Should().BeGreaterThan(0); var jobStatus = await JobQueueClient.WaitForJobToComplete(monitoringApi, jobIdString, 30 * 1000, CancellationToken.None); jobStatus.State.Should().Be(JobState.Succeeded); } }
public void AddJobState_JustAddsANewRecordInATable() { UseConnection(database => { HangfireJob job = new HangfireJob { InvocationData = "", Arguments = "", CreatedAt = DateTime.UtcNow }; database.Database.Insert(job); var jobId = Convert.ToString(job.Id); var serializedData = new Dictionary <string, string> { { "Name", "Value" } }; 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(serializedData); Commit(database, x => x.AddJobState(jobId, state.Object)); var testJob = GetTestJob(database, job.Id); Assert.Null(testJob.StateName); var jobWithStates = database.HangfireJobRepository.ToList().Single(); var jobState = database.StateRepository.Last(x => x.JobId == jobWithStates.Id); Assert.Equal("State", jobState.Name); Assert.Equal("Reason", jobState.Reason); Assert.True(jobState.CreatedAt > DateTime.MinValue); Assert.Equal(JsonConvert.SerializeObject(serializedData), jobState.Data); }); }
public void GetQueues_ReturnsAllGivenQueues() { var date = DateTime.UtcNow; var queues = Enumerable.Repeat(0, 5). Select(x => Guid.NewGuid().ToString()). ToArray(); var job = new HangfireJob { InvocationData = InvocationDataStub, QueuedJobs = queues. Select(x => new HangfireQueuedJob { Queue = x, }). ToList() }; UseContextSavingChanges(context => context.Add(job)); var instance = new EFCoreJobQueueMonitoringApi(Storage); var result = instance.GetQueues(); Assert.Equal(queues.OrderBy(x => x), result.OrderBy(x => x)); }
public void Dequeue_ShouldFetchJobs_OnlyFromSpecifiedQueues() { UseConnection(connection => { var job1 = new HangfireJob() { InvocationData = "", Arguments = "", CreatedAt = DateTime.UtcNow }; connection.Database.Insert(job1); connection.Database.Insert(new JobQueue { JobId = job1.Id, Queue = "critical" }); var queue = CreateJobQueue(connection); Assert.Throws <OperationCanceledException>(() => queue.Dequeue(DefaultQueues, CreateTimingOutCancellationToken())); }); }
/// <inheritdoc /> public Task ExecuteHangfireTestJobAsync(HangfireJob hangfireJob) { return(Task.Run(() => Console.WriteLine($"Job TestValue: {hangfireJob.TestValue}") )); }
public JobInformationViewComponent(HangfireJob hangfireJobs) { _monitor = JobStorage.Current.GetMonitoringApi(); _jobCache = hangfireJobs; }
public CrontabService(IHost host, ILogger <CrontabService> logger, IConfiguration configuration, IServiceProvider serviceProvider, HangfireJob hangfireJob) => (this.host, this.logger, this.configuration, this.serviceProvider, this.hangfireJob) = (host, logger, configuration, serviceProvider, hangfireJob);
public void FetchedJobs_ReturnsCorrectResult() { var now = DateTime.UtcNow; var queue = "queue";; var invocationData = CreateInvocationData(() => SampleMethod("Argument")); var jobs = Enumerable.Range(0, 3). Select(x => { var createdAt = now - new TimeSpan(0, 0, x); var data = new Dictionary <string, string> { ["EnqueuedAt"] = JobHelper.SerializeDateTime(createdAt), }; var state = new HangfireState { CreatedAt = createdAt, Name = EnqueuedState.StateName, Reason = "Reason", Data = SerializationHelper.Serialize(data), }; var job = new HangfireJob { CreatedAt = createdAt, InvocationData = invocationData, States = new[] { state, }, QueuedJobs = new[] { new HangfireQueuedJob { Queue = queue, FetchedAt = now, }, } }; return(job); }). ToArray(); UseContextSavingChanges(context => { foreach (var job in jobs) { context.Add(job); } context.SaveChanges(); foreach (var job in jobs) { var state = job.States.Single(); job.State = state; job.StateName = state.Name; } }); var result = UseMonitoringApi(instance => instance.FetchedJobs(queue, 1, 2)); Assert.NotNull(result); Assert.Equal(2, result.Count); Assert.All(result, item => { Assert.NotNull(item.Key); var id = long.Parse(item.Key, CultureInfo.InvariantCulture); var job = Assert.Single(jobs.Where(x => x.Id == id)); var value = item.Value; Assert.NotNull(value); Assert.Equal(now, value.FetchedAt); Assert.Equal(job.StateName, value.State); Assert.Equal(job.State.Name, value.State); }); }
/// <inheritdoc /> public Task ExecuteHangfireInfiniteJobAsync(HangfireJob hangfireJob) { return(Task.Delay(-1)); }
private HangfireJob CreateJobInState(HangfireDbContext database, string stateName, Func <HangfireJob, HangfireJob> visitor = null) { var job = Job.FromExpression(() => Console.WriteLine("TEST")); Dictionary <string, string> stateData; if (stateName == EnqueuedState.StateName) { stateData = new Dictionary <string, string> { ["EnqueuedAt"] = $"{DateTime.UtcNow:o}" }; } else if (stateName == ProcessingState.StateName) { stateData = new Dictionary <string, string> { ["ServerId"] = Guid.NewGuid().ToString(), ["StartedAt"] = JobHelper.SerializeDateTime(DateTime.UtcNow.Subtract(TimeSpan.FromMilliseconds(500))) }; } else { stateData = new Dictionary <string, string>(); } var hangfireJob = new HangfireJob { InvocationData = SerializationHelper.Serialize(InvocationData.SerializeJob(job)), Arguments = "[\"\\\"Arguments\\\"\"]", StateName = stateName, CreatedAt = DateTime.UtcNow }; database.Database.Insert(hangfireJob); var jobState = new State() { JobId = hangfireJob.Id, Name = stateName, Reason = null, CreatedAt = DateTime.UtcNow, Data = JsonConvert.SerializeObject(stateData) }; if (visitor != null) { hangfireJob = visitor(hangfireJob); } database.Database.Insert(jobState); var jobQueue = new JobQueue { FetchedAt = DateTime.MinValue, JobId = hangfireJob.Id, Queue = DefaultQueue }; if (stateName == FetchedStateName) { jobQueue.FetchedAt = DateTime.UtcNow; } database.Database.Insert(jobQueue); return(hangfireJob); }