laravel / ideas

Issues board used for Laravel internals discussions.
938 stars 31 forks source link

Pass previous job in a chain to the next job #2641

Open tobz-nz opened 3 years ago

tobz-nz commented 3 years ago

Queued job chains are super useful for processing in stages. What I think is missing is a way of each job in the chain knowing something from the previous job.

In my current use case I have a pipeline of file processing:

Passing each file down the stages of the chain would be really useful. Receiving the returned result form one job in the handle() method of the next maybe? Something like:

// controller
Bus::chain([
    new ProcessPodcast($file),
    new OptimizePodcast,
    new ReleasePodcast,
])->dispatch();

// ProcessPodcast.php
public function handle() 
{
    ...
    return $file;
}

// OptimizePodcast.php
public function handle($file) 
{
   // do something  with $file
}

Another option would be receiving the previous job instance itself? Maybe on $this->getPreviousJob() or something (this a terrible method name but you know what I mean)

rognales commented 3 years ago

How bout this package by Spatie https://github.com/spatie/laravel-queueable-action#chaining-actions

tobz-nz commented 3 years ago

@rognales It might just be too early in the morning, but I don't understand how that package adds over normal queueable jobs. I'd still need to dispatch each job in the chain from within the current job (i.e. not really using a chain as such, but dispatching jobs within jobs - not what I want).

In my use case the number and type of jobs in the chain change depending on the type of file (e.g some do no need decoding, they use different coding or processing API's etc..) so having each job independent is important. Just passing the result of each job onto the next in the chain would be ideal.

tobz-nz commented 3 years ago

Another option would be to have access to the entire chain from within each job, and be able to update them. Something like:

function handle( )
{
    // do some work

   $nextJobInChain = $this->getChain()->next();
   $nextJobInChain->setFile($file)->save();
}