publicplan / parallel-bridge
Symfony Parallel Bridge
Installs: 15 047
Dependents: 0
Suggesters: 0
Security: 0
Stars: 3
Watchers: 2
Forks: 0
Open Issues: 0
Type:symfony-bundle
Requires
- php: >=7.3
- amphp/parallel-functions: ^1.0
- symfony/config: ^4.0 || ^5.0
- symfony/dependency-injection: ^4.0 || ^5.0
- symfony/http-kernel: ^4.0 || ^5.0
Requires (Dev)
- roave/security-advisories: dev-master
- symfony/phpunit-bridge: ^5.2
README
Provides utilities from AMPHP Parallel, especially parallel functions. This Bundle is developed and tested with php 7.3, 7.4 and 8.0 and Symfony 4.4 and 5.2. Other Versions might work but are not supported or tested.
SETUP
- Use composer to install Parallel-Bridge.
composer require publicplan/parallel-bridge
- Create
worker-bootstrap.php
in your application config folder.
// app/config/worker-bootstrap.php <?php declare(strict_types=1); use App\Kernel; use Symfony\Component\Dotenv\Dotenv; set_time_limit(0); if (class_exists(Dotenv::class)) { if (method_exists(Dotenv::class, 'bootenv')) { (new Dotenv())->bootEnv(dirname(__DIR__) . '/.env'); } else { require dirname(__DIR__) . '/config/bootstrap.php'; } } $kernel = new Kernel($_SERVER['APP_ENV'], (bool)$_SERVER['APP_DEBUG']); $kernel->boot(); $GLOBALS['kernel'] = $kernel;
- Create
parallel_bridge.yaml
in yourconfig/packages
dir.
# config/packages/parallel_bridge.yaml publicplan_parallel_bridge: amphp_max_worker: '%env(int:AMPHP_MAX_WORKERS)%' project_dir: '%kernel.project_dir%'
- Setup your maximal worker amount in your
.env.local
.
AMPHP_MAX_WORKERS=3
info: fill in a "0" for synchronous execution without workers. This can be handy for debugging and some rare Problems with Macs.
Usage
- Use PromiseWait in your class to remap async! You can use any callable you like but you should consider that closures must be serializable. When you need your projects context we recommend to use the following way: (also see https://amphp.org/parallel-functions/ for deeper information)
// src/Service/YourClass.php <?php declare(strict_types=1); namespace App\Service; use Amp\MultiReasonException; use Publicplan\ParallelBridge\PromiseWaitInterface; class YourClass { /** @var PromiseWaitInterface */ private $promiseWait; public function __construct(PromiseWaitInterface $promiseWait) { $this->promiseWait = $promiseWait; } public function yourFunction(): void { $unprocessDataArray = range(1, 100); try{ //If we want to use a container class it must be public and in the following format: $finalDataArray = $this->promiseWait->parallelMap($unprocessDataArray, [$this,'processSingleElement']); } //to get possible errors you have to catch MultiReasonException catch (MultiReasonException $exception ){ dd($exception); } print_r($finalDataArray); } //This Function will be called async from our processes after grabbing this service from service container public function processSingleElement(int $number): string { for ($i = 0; $i < 200000; $i++) { $hash = hash('SHA512', (string)$number); } return $hash; } }
- Make your service public! When using a service, like we do in the example above, you need to make your service public.
# config/services.yaml services: [...] App\Service\YourClass: public: true
Optional: Additional Arguments
Add additional arguments to the PromiseWait::parallelMap()
function as you like.
All arguments get passed through to your called function.
<?php declare(strict_types=1); namespace App\Service; use Publicplan\ParallelBridge\PromiseWaitInterface; class YourClass { /** @var PromiseWaitInterface */ private $promiseWait; public function __construct(PromiseWaitInterface $promiseWait) { $this->promiseWait = $promiseWait; } public function yourFunction(): void { $unprocessDataArray = range(1, 100); $additionalArg = 42; $result = $this->promiseWait->parallelMap( $unprocessDataArray, [$this,'processSingleElement'], $additionalArg, ); //Returns numbers from 43 to 143 print_r($result); } public function processSingleElement(int $number, int $additionalArg): int { return $number + $additionalArg; } }