Laravel event asynchronous example

It was sorted out yesterday Event mechanism of Laravel Today, I want to verify its asynchronous operation.

1, preparation

1.1 create Event and Listener respectively,

\App\Events\Test::class => [
            \App\Listeners\TestA::class
        ],

app\Events\Test:

<?php

namespace App\Events;

use Illuminate\Broadcasting\Channel;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;

class Test
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public $str;

    /**
     * Create a new event instance.
     *
     * @return void
     */
    public function __construct($str)
    {
        $this->str = $str;
    }

    /**
     * Get the channels the event should broadcast on.
     *
     * @return \Illuminate\Broadcasting\Channel|array
     */
    public function broadcastOn()
    {
        return new PrivateChannel('channel-name');
    }
}

App\Listeners\TestA:

<?php

namespace App\Listeners;

use App\Events\Test as TestEvent;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;

class TestA implements ShouldQueue
{

    /**
     * Create the event listener.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Handle the event.
     *
     * @param  TestEvent  $event
     * @return void
     */
    public function handle(TestEvent $event)
    {
        logger()->channel('erp')->info('I got msg:'.$event->str.' at:'.date('Y-m-d H:i:s'));
        sleep(5);
    }
}

As shown above, our listener implements ShouldQueue and uses event queue. At the same time, we put the

<?php

return [

    /*
    |--------------------------------------------------------------------------
    | Default Queue Connection Name
    |--------------------------------------------------------------------------
    |
    | Laravel's queue API supports an assortment of back-ends via a single
    | API, giving you convenient access to each back-end using the same
    | syntax for every one. Here you may define a default connection.
    |
    */

//    'default' => env('QUEUE_CONNECTION', 'redis'),
    'default' => 'redis',
    .
    .
    .

];

Then clear the configuration cache and start the queue

php artisan config:clear

php artisan queue:work

Then we write a random interface to distribute events in the interface, such as

<?php

namespace App\Http\ApiControllers;

use App\Events\Test as EventTest;

class TestController extends Controller
{

    public function goods(DetailRequest $request)
    {
         event(new EventTest('123'));
         var_dump('456 at:'.date('Y-m-d H:i:s'));exit;
    }

}

As you can see, I passed in a string in the time event, then in the listener, I wrote the string to the log with a time stamp, then sleep(5), and then printed out the current time stamp in the local method.

In this way, when I call the interface, if it is A synchronous event, I will first print A timestamp A in the log, and then after 5 seconds, I will print another timestamp B in the interface. The two timestamps are 5 seconds apart.

If it is an asynchronous event, the sleep(5) after the printing timestamp A of the log does not delay the printing timestamp B in the interface log, that is, if the queue is not crowded, the interval between the two timestamps will be less than 5 seconds.

We open the log, then call the interface and find it.

Interface return:

string(26) "456 at:2020-03-17 12:14:42"

Logging:

[2020-03-17 12:14:45] dev.INFO: I got msg:123 at:2020-03-17 12:14:45

Queue records:

[2020-03-17 12:14:45][JWStHEjScMFNiOqUwRPL0syVko5d2v16] Processing: App\Listeners\TestA
[2020-03-17 12:14:50][JWStHEjScMFNiOqUwRPL0syVko5d2v16] Processed:  App\Listeners\TestA

It can be seen that the event is listened to and entered the queue at 12:14:45, but the interface has finished executing at 12:14:42. That is to say, after the event is distributed, the request process will not block waiting and directly execute the next code.

In this way, we implement a simple event queue.

Tags: Programming PHP Laravel Redis less

Posted on Mon, 16 Mar 2020 22:10:07 -0700 by ud2008