Search code examples
laravellumenlaravel-queue

How to dispatch chained jobs to a queue in Lumen 6?


In Laravel, it is possible to specify a list of queued jobs that should be run in sequence after the primary job has executed successfully. If one job in the sequence fails, the rest of the jobs will not be run. The Laravel documentation shows that this is accomplished by using the withChain method on a dispatchable job, as in this example:

ProcessPodcast::withChain([
    new OptimizePodcast,
    new ReleasePodcast
])->dispatch();

This works well for me in Laravel, however I am using Lumen (a lightweight subset of Laravel).
According to Lumen's documentation on queues, "Like many other parts of the framework, Lumen's queued jobs function identically to Laravel's queued jobs. So, to learn more about queuing jobs in Lumen, please review the full Laravel queue documentation."

The Lumen docs do mention some minor differences with Laravel, including a difference in the way that jobs are dispatched to a queue. It explains that jobs in Lumen can be dispatched using either the dispatch function or the Queue facade:

dispatch(new ExampleJob);

Queue::push(new ExampleJob);

With that as background, is there any way to dispatch chained jobs in Lumen? I have scoured Google for days, and the closest matches to my issue are these two links:

  • This Stack Overflow post, which exactly describes my issue but does not offer any solutions
  • This Laracast thread, which suggests a syntax of $this->dispatch( (new FillBruteFec($import))->chain(new FillRaiFec()) ); that also doesn't work for me.

The Stack Overflow link above explains that the reason the Laravel syntax won't work is that Lumen is missing the Illuminate\Foundation\Bus\Dispatchable trait.

Further complicating matters is that I need to pass a different set of parameters to each of my jobs - something that is apparently challenging to do even in the full Laravel framework.

Here is how I am currently submitting my jobs in my Lumen app (without chaining):

Queue::push(new CreateUser($username,$password));
Queue::push(new SetForwarding($username,$forwardTo));
Queue::push(new EnableIncomingEmail($username));
Queue::push(new EnableOutgoingEmail($username));
Queue::push(new EnableImap($username));

The main reason I want to chain these is to make sure the user record gets created successfully before any of the subsequent jobs that modify that user.

So, with all of that in mind... how about it? Is it at all possible to chain jobs in Lumen? If so, what syntax would I use?


Solution

  • illuminate/bus/Queueable trait which is used in App\Jobs\Job class provides a chain method that should be invoked with an array of Job instances to make a job chain.

    You can run a chain of jobs by writing:

    $this->dispatch(
        (new CreateUser($username,$password))
        ->chain([
            new SetForwarding($username,$forwardTo),
            new EnableIncomingEmail($username),
            new EnableOutgoingEmail($username),
            new EnableImap($username)
        ])
    );