What happens to the model's eager-loaded relationship when the model is passed to another Job's dispatch method?
Context:
There is a job that retrieves all ongoing games and this job should create an entry for users who forgot to create one when the entry registration was still open.
Current implementation:
There is only one Job that handles the retrieval of ongoing games and creation of entries. Basically, in this single job, thousands of entries are being created for our users. This is a problem since it's very prone to Timeout Exception.
And what's more concerning is, relationship are being lazy-loaded inside the function that creates the entry for each user. So that is already N+1.
Optimization Attempt:
Instead of doing all of these work in a single job, I have created two jobs:
PrepareOngoingGamesJob- retrieves allongoing games.CreateEntryJob- gets dispatched from the loop in thePrepareOngoingGamesJob.
This way, each entry creation will be treated as a single job.
Problem/Confusion:
To omit the N+1 problem, I eager-loaded the necessary relationships from the PrepareOngoingGamesJob, for example, $games = Games::with(['related_1', 'related_2', 'related_3']).
But what happens when I do this:
$games->each(fn ($game) => CreateEntryJob::dispatch($game))
If I access related_1, related_2, related_3 in CreateEntryJob's handle() method, will it be queried from the database again? or is it already there?
toArraywill convert the model and relationships to arrays and you can probably dispatch a job with the array instead to prevent re-retriveving. However keep in mind queue services like SQS have a limit on message sizeSerializesModelstrait keeps only the primary keys of each model. The other option would be to pass the entire model, but in this case when you run the job you don't know if the models in have been updated/deleted since the job was dispatched.