Search code examples
phplaravelsimultaneous-calls

Laravel simultaneous launch functions


I have such function in my trait:

public function cupPlayMatch(Season $season, $round_id)
{

    foreach($season->cups as $cup)
    {
        $this->cupPlay($cup, $round_id);
    }

}

And second cup isstarting playing when first cup finished. How I can start playing all my cups simultaneous?


Solution

  • For the most part, PHP is "synchronous", that means that you theoretically can't make "simultaneous calls" to any function.

    However, some workarounds exist to make this work.

    PHP is a script language. So when you launch this in your console:

    php -r "echo 'Hello World';"
    

    A PHP process is launched, and anything that happen in this process is executed synchronously.

    So the solution here, is to launch various PHP processes in order to be able to run functions simultaneously.

    Imagine an SQL table where you put all the functions that you want to execute simultaneously. You could then run 10 php processes that would actually work "at the same time".

    Laravel provides a solution to this problem out of the box. And as @Anton Gildebrand mentioned it in the comments, it's called "Queues".

    You can find the documentation here: https://laravel.com/docs/5.5/queues

    The laravel way of doing it, is to create "jobs". Each Job represents a function that you want to execute. Here, your Job would be cupPlay.

    Here is the basic example of a job copy pasted from the documentation:

    <?php
    
    namespace App\Jobs;
    
    use App\Podcast;
    use App\AudioProcessor;
    use Illuminate\Bus\Queueable;
    use Illuminate\Queue\SerializesModels;
    use Illuminate\Queue\InteractsWithQueue;
    use Illuminate\Contracts\Queue\ShouldQueue;
    use Illuminate\Foundation\Bus\Dispatchable;
    
    class ProcessPodcast implements ShouldQueue
    {
        use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
    
        protected $podcast;
    
        /**
         * Create a new job instance.
         *
         * @param  Podcast  $podcast
         * @return void
         */
        public function __construct(Podcast $podcast)
        {
            $this->podcast = $podcast;
        }
    
        /**
         * Execute the job.
         *
         * @param  AudioProcessor  $processor
         * @return void
         */
        public function handle(AudioProcessor $processor)
        {
            // Process uploaded podcast...
        }
    }
    

    When you'll have configured your worker driver to run your queues, you'll just need to launch:

    php artisan queue:work --queue=high,default
    

    from the command line and it will execute your tasks.

    And you can execute as many workers as you want, depending on your needs...

    I hope this helps!