leocavalcante / coroutine-context-api
Using Coroutines Contexts as Hierarchic Service Locators and Dependency Injection Containers.
v0.1.0
2021-10-11 18:59 UTC
Requires
- php: >=7.4 || >=8.0
- ext-swoole: ^4.6
Requires (Dev)
- pestphp/pest: ^1.1
- swoole/ide-helper: ^4.6
- vimeo/psalm: ^4.7
README
Using Coroutines Contexts as Hierarchic Service Locators and Dependency Injection Containers.
Inspired by https://reactjs.org/docs/context.html
Install
composer require leocavalcante/coroutine-context-api
Usage
Provide
\Swoole\Coroutine\Context\provide(string $key, mixed $value): void
Sets a value to be consumed from children Coroutines based on a string.
use function Swoole\Coroutine\{run, Context\provide}; run(static function(): void { provide('message', 'Hello, World!'); });
Consume
\Swoole\Coroutine\Context\consume(string $key, [mixed $default]): mixed
Consumes the value from the given key.
use function Swoole\Coroutine\{run, Context\provide, Context\consume}; run(static function(): void { provide('message', 'Hello, World!'); go(static fn() => print(consume('message') . PHP_EOL)); });
But, but...
Why is this different from passing parameters to function arguments?
The consume
function can lookup through the nearest provided key in the Coroutine tree.
use function Swoole\Coroutine\{run, Context\provide, Context\consume}; run(static function(): void { provide('message', 'Hello, World!'); go(static fn() => go(static fn() => go(static fn() => print(consume('message') . PHP_EOL) ) ) ); });
Why is this different from globals?
It is not about global space being polluted, it is based on parent-child "Coroutine tree".
run(static function(): void { provide('message', 'Hello, World!'); go(static fn() => print(consume('message') . PHP_EOL)); }); run(static function(): void { provide('message', 'Olá, Mundo!'); go(static fn() => print(consume('message') . PHP_EOL)); }); run(static function(): void { go(static fn() => print(consume('message', $default = '你好, 世界!') . PHP_EOL)); });