13

I am developing a website in Laravel 5.0 and hosted in Windows Server2012.

I am stuck at a problem which is I am calling a function B in controller from another function A and I want that the function A which calls the another function B does not wait for the completion of function B . And Function B gets completes in the background and independent form user termination of page and function A return .

I have searched this and found that this can be implemented through cron like jobs in windows, pcntl_fork() and Queue functionality in laravel. I am beginner in all this.

Please help! thanks in advance.

Nilesh
  • 884
  • 3
  • 11
  • 22

1 Answers1

19

as the documentation states http://laravel.com/docs/5.1/queues, first you need to setup the driver - i would go for database in the beginning :

php artisan queue:table

php artisan migrate

then create the Job that you want to add to the queue

<?php

namespace App\Jobs;

use App\User;
use App\Jobs\Job;
use Illuminate\Contracts\Mail\Mailer;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Bus\SelfHandling;
use Illuminate\Contracts\Queue\ShouldQueue;

class SendEmail extends Job implements SelfHandling, ShouldQueue
{
    use InteractsWithQueue, SerializesModels;

    protected $user;

    public function __construct(User $user)
    {
        $this->user = $user;
    }

    public function handle(Mailer $mailer)
    {
        $mailer->send('emails.hello', ['user' => $this->user], function ($m) {
            //
        });
    }
}

then in the Controller dispatch the job

<?php

namespace App\Http\Controllers;

use App\User;
use Illuminate\Http\Request;
use App\Jobs\SendReminderEmail;
use App\Http\Controllers\Controller;

class UserController extends Controller
{
    /**
     * Send a reminder e-mail to a given user.
     *
     * @param  Request  $request
     * @param  int  $id
     * @return Response
     */
    public function sendReminderEmail(Request $request, $id)
    {
        $user = User::findOrFail($id);

        $sendEmailJob = new SendEmail($user);

        // or if you want a specific queue

        $sendEmailJob = (new SendEmail($user))->onQueue('emails');

        // or if you want to delay it

        $sendEmailJob = (new SendEmail($user))->delay(30); // seconds

        $this->dispatch($sendEmailJob);
    }
}

For that to work, you need to be running the Queue Listener:

php artisan queue:listen

Does that answer?

UX Labs
  • 1,481
  • 14
  • 29
  • what if I want to do process other than mail?? – Nilesh Jul 16 '15 at 12:16
  • 1
    You can do what ever you want in the handle section, the email is just an example – UX Labs Jul 16 '15 at 12:34
  • Do I need Queue driver or just this code will work?? – Nilesh Jul 16 '15 at 12:40
  • 1
    Done!! But new problem!! My Queue drive is database!! Job is added in database but not running!! should I have to do extra functionality to run those jobs?? – Nilesh Jul 16 '15 at 15:12
  • Done!! this problem also Solved!! your Solution helped a lot!! Thanks man!! – Nilesh Jul 16 '15 at 15:24
  • 2
    Great im glad to help sorry couldnt reply earlier, one recommendation is to actually take your time reading the docs. It can be difficult in the beginning but later it becomes easier, and i can prove it to you by telling you i have never used the queues before but taylor otwell was very artistic while designing the docs, so try not to rush so fast, take your time with the docs – UX Labs Jul 16 '15 at 19:46
  • Old question. However its important to note that in the `QUEUE_DRIVER` variable should be set to database within the `.env` if using the database for queuing. – thisiskelvin Mar 20 '18 at 11:12
  • Also, check here on how you can keep jobs runing in background after a system restart or shutdown: https://stackoverflow.com/a/44501632/1425040 – davefrassoni Sep 18 '19 at 15:29