ruth / async-service-call-bundle
Symfony bundle for asynchronous service methods calls
Installs: 32
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 5
Type:symfony-bundle
Requires
- php: >=7.3
- symfony/console: ~5.0
- symfony/framework-bundle: ~5.0
- symfony/monolog-bundle: ^3.5
- symfony/process: ^5.0
Requires (Dev)
- symfony/phpunit-bridge: >=5.0
README
This bundle allows you to execute methods of your services asynchronously in a background process.
It is a fork on krlove/async-service-call-bundle, updated to run in Symfony 4 or 5.
Installation
Install using composer:
composer require ruth/async-service-call-bundle
It should enable the bundle at config/bundles.php
return [
...
new Krlove\AsyncServiceCallBundle\KrloveAsyncServiceCallBundle(),
]
If not, you now know what to do.
Configuration
Options:
console_path
- path toconsole
script. Can be absolute or relative tokernel.project_dir
parameter's value. Defaults tobin/console
Symfony 4.* and Symfony 5.*.php_path
- path to php executable. If no option provided in configuration,Symfony\Component\Process\PhpExecutableFinder::find
will be used to set it up.
Example:
# config/packages/krlove_async_service_call.yaml
krlove_async_service_call:
console_path: bin/console
php_path: /usr/local/bin/php
Usage
Define any service:
<?php
namespace App\Service;
class AwesomeService
{
public function doSomething($int, $string, $array)
{
// do something heavy
sleep(10);
}
}
Register service:
# services.yml
services:
app.service.awesome:
class: App\Service\AwesomeService
public: true
make sure your service is configured with
public: true
Execute doSomething
method asynchronously:
$this->get('krlove.async')
->call('app.service.awesome', 'doSomething', [1, 'string', ['array']);
Line above will execute App\Service\AwesomeService::doSomething
method by running krlove:service:call
command on background.
You can follow it's execution by calling top
on your console.
Original approach with symfony process Symfony\Component\Process\Process
was abandoned
in favor of a more traditional exec
php function. The reason is this (that you can find in upper page):
If a Response is sent before a child process had a chance to complete, the server process will be killed (depending on your OS).
It means that your task will be stopped right away.
Running an asynchronous process is not the same as running a process that survives its parent process.
Usage with Symfony Process Component
It is also possible to run your service with Symfony Process Component, and with that having an asynchronous service with a response (or exception) during request / response context.
For that you just have to call method getProcessInstance
like this:
// 1. Standard way:
$process = $this->get('krlove.async')
->getProcessInstance('app.service.awesome', 'doSomething', [1, 'string', ['array']);
// and to run asynchronously
$process->start();
// ... do other things
$process->wait();
// ... do things after the process has finished
$result = $process->getOutput();
// 2. With callback function after service finishes:
$process = $this->get('krlove.async')
->getProcessInstance('app.service.awesome', 'doSomething', [1, 'string', ['array']);
// and to run asynchronously
$result = null;
$process->start(function ($res) use($process, &$result) {
$result = $process->getOutput();
});
// ... do other things
$process->wait();
// you now have result from async service call available at $result variable.
You have more information about Symfony Process Component here