Hello,
we are trying to setup a complex chain of batches and jobs but we can’t figure out how to make it work.
I will try to explain our situation:
Because of our business requirements our goal is to see this structure of batches and jobs in the hangfire GUI:
parentBatch
- job1 (this job gets the parentBatchId as a parameter and will attach all jobs and batches below to the parentbatch)
- job2
- nestedBatch1 (should start after job2 finished)
- nestedJob1
- nestedJob2
- nestedJob3
- ... thousands more nestedJobs
- job3 (should start after everything in nestedBatch1 is finished)
- job4 (should start after job3 is finished)
All these jobs belong together business-wise, so we would like to see them all in the same parentBatch.
We have tried to make this work, however, job3 and job4 are not waiting for everything in nestedBatch1 to finish.
The parentbatch is started like this:
BatchJob.StartNew(batch => batch
.Enqueue<Job1>(job => job
.Execute(batch.BatchId, null)));
Job1 receives the parentBatchId as a parameter. So it knows how to attach/enqueue all the rest to the parentBatch
BatchJob.Attach(parentBatchId, batch =>
{
var job2 = batch.Enqueue<SomeJobClass>(job => job.Execute());
//create empty nestedbatch and attach all jobs later (enqueueing them all at once during StartNew throws exceptions due to SQL transaction/timeout problems (too many jobs at once)
nestedBatch = batch.StartNew(b => EmptyMethod(), "childbatch");
continueWithId = batch.ContinueWith(job2, () => EnqueueManyJobsInNestedBatchUsingAttach(nestedBatch));
//all the jobs below should start only after everything in nestedBatch is finished. However they are enqueued too early
BatchJob.AwaitJob(continueWithId, b =>
{
BatchJob.AwaitBatch(nestedBatch, b2 =>
{
var job3 = batch.Enqueue(() => Job3());
var job4 = batch.ContinueWith<Job4Class>(job3, job => job.Execute());
});
});
});
We want to enqueue thousands of jobs within the nestedBatch.
We are running into SQL timeout and transaction problems if we Attach and enqueue them all at once.
Because of this we are slicing them in groups of 500
//method EnqueueManyJobsInNestedBatchUsingAttach (used in above configuration)
modelsForWichToEnqueueJob.Batch(500).ForEach(slice =>
{
BatchJob.Attach(nestedBatchId, batch =>
{
slice.ForEach(modelId =>
{
batch.Enqueue<SomeJob>(job => job.Execute(modelId);
});
});
});
The syntax for Hangfire Pro (attaching, awaiting, combining batches and jobs) is very confusing to us. It is very unclear to us what is executed when, and which methods create their own job (i.e. to wait or another job to complete).
We have read through the existing documentation but all the examples are very basic.
Questions:
- Is it possible to document some more complex use cases? Are there any courses available for hangfire pro?
- Do you have any pointers on how to correctly implement the above?
One solution could be to drop our requirement to have all these jobs grouped together under 1 parentbatch. However, given the amount of jobs we would absolutely prefer to have them grouped together and this is one of the reasons we chose to upgrade to hangfire pro.
Hope you can help us.
Thank you in advance!