11# Background Workers
22
33Background workers are long-running PHP scripts that run outside the HTTP request cycle.
4- They observe their environment and publish configuration that HTTP [ workers] ( worker.md ) can read in real time.
4+ They observe their environment and publish variables that HTTP [ workers] ( worker.md ) can read in real time.
55
66## How It Works
77
881 . A background worker runs its own event loop (subscribe to Redis, watch files, poll an API...)
9- 2 . It calls ` frankenphp_worker_set_vars ()` to publish a snapshot of key-value pairs
10- 3 . HTTP workers call ` frankenphp_worker_get_vars ()` to read the latest snapshot
9+ 2 . It calls ` frankenphp_set_vars ()` to publish a snapshot of key-value pairs
10+ 3 . HTTP workers call ` frankenphp_get_vars ()` to read the latest snapshot
11114 . The first ` get_vars() ` call blocks until the background worker has published - no startup race condition
1212
1313## Configuration
@@ -42,15 +42,15 @@ example.com {
4242
4343## PHP API
4444
45- ### ` frankenphp_worker_get_vars (string|array $name, float $timeout = 30.0): array`
45+ ### ` frankenphp_get_vars (string|array $name, float $timeout = 30.0): array`
4646
47- Starts a background worker (at-most-once) and returns its published variables .
47+ Starts a background worker (at-most-once) and returns its published vars .
4848
4949``` php
50- $redis = frankenphp_worker_get_vars ('redis-watcher');
50+ $redis = frankenphp_get_vars ('redis-watcher');
5151// ['MASTER_HOST' => '10.0.0.1', 'MASTER_PORT' => 6379]
5252
53- $all = frankenphp_worker_get_vars (['redis-watcher', 'feature-flags']);
53+ $all = frankenphp_get_vars (['redis-watcher', 'feature-flags']);
5454// ['redis-watcher' => [...], 'feature-flags' => [...]]
5555```
5656
@@ -60,18 +60,19 @@ $all = frankenphp_worker_get_vars(['redis-watcher', 'feature-flags']);
6060- Throws ` RuntimeException ` on timeout, missing entrypoint, or background worker crash
6161- Works in both worker and non-worker mode
6262
63- ### ` frankenphp_worker_set_vars (array $vars): void`
63+ ### ` frankenphp_set_vars (array $vars): void`
6464
65- Publishes a snapshot of key-value pairs from inside a background worker.
66- Each call ** replaces** the entire snapshot atomically.
65+ Publishes vars from inside a background worker.
66+ Each call ** replaces** the entire vars array atomically.
6767If the new value is identical (` === ` ) to the previous one, the call is a no-op.
6868
69- Supported types: ` null ` , ` bool ` , ` int ` , ` float ` , ` string ` , ` array ` (nested), and ** enums** .
69+ Values can be ` null ` , scalars (` bool ` , ` int ` , ` float ` , ` string ` ), nested ` array ` s, or ** enum** s.
70+ Objects, resources, and references are rejected.
7071
7172- Throws ` RuntimeException ` if not called from a background worker context
7273- Throws ` ValueError ` if values contain objects, resources, or references
7374
74- ### ` frankenphp_worker_get_signaling_stream (): resource`
75+ ### ` frankenphp_get_worker_handle (): resource`
7576
7677Returns a readable stream for receiving signals from FrankenPHP.
7778On shutdown or restart, the stream is closed - ` fgets() ` returns ` false ` (EOF).
@@ -81,7 +82,7 @@ Use `stream_select()` to wait between iterations instead of `sleep()`:
8182function background_worker_should_stop(float $timeout = 0): bool
8283{
8384 static $stream;
84- $stream ??= frankenphp_worker_get_signaling_stream ();
85+ $stream ??= frankenphp_get_worker_handle ();
8586 $s = (int) $timeout;
8687
8788 return match (@stream_select(...[[$stream], [], [], $s, (int) (($timeout - $s) * 1e6)])) {
@@ -118,7 +119,7 @@ function run_config_watcher(): void
118119 $redis->pconnect('127.0.0.1');
119120
120121 do {
121- frankenphp_worker_set_vars ([
122+ frankenphp_set_vars ([
122123 'maintenance' => (bool) $redis->get('maintenance_mode'),
123124 'feature_flags' => json_decode($redis->get('features'), true),
124125 ]);
@@ -134,23 +135,23 @@ to integrate the signaling stream into the event loop:
134135``` php
135136function run_redis_watcher(): void
136137{
137- $signalingStream = frankenphp_worker_get_signaling_stream ();
138+ $signalingStream = frankenphp_get_worker_handle ();
138139 $sentinel = Amp\Redis\createRedisClient('tcp://sentinel-host:26379');
139140
140141 $subscription = $sentinel->subscribe('+switch-master');
141142
142143 Amp\async(function () use ($subscription) {
143144 foreach ($subscription as $message) {
144145 [$name, $oldIp, $oldPort, $newIp, $newPort] = explode(' ', $message);
145- frankenphp_worker_set_vars ([
146+ frankenphp_set_vars ([
146147 'MASTER_HOST' => $newIp,
147148 'MASTER_PORT' => (int) $newPort,
148149 ]);
149150 }
150151 });
151152
152153 $master = $sentinel->rawCommand('SENTINEL', 'get-master-addr-by-name', 'mymaster');
153- frankenphp_worker_set_vars ([
154+ frankenphp_set_vars ([
154155 'MASTER_HOST' => $master[0],
155156 'MASTER_PORT' => (int) $master[1],
156157 ]);
@@ -174,7 +175,7 @@ $app = new App();
174175$app->boot();
175176
176177while (frankenphp_handle_request(function () use ($app) {
177- $config = frankenphp_worker_get_vars ('config-watcher');
178+ $config = frankenphp_get_vars ('config-watcher');
178179
179180 $_SERVER += ['APP_REDIS_HOST' => $config['MASTER_HOST'], 'APP_REDIS_PORT' => $config['MASTER_PORT']];
180181 $app->handle($_GET, $_POST, $_COOKIE, $_FILES, $_SERVER);
@@ -186,8 +187,8 @@ while (frankenphp_handle_request(function () use ($app) {
186187### Graceful Degradation
187188
188189``` php
189- if (function_exists('frankenphp_worker_get_vars ')) {
190- $config = frankenphp_worker_get_vars ('config-watcher');
190+ if (function_exists('frankenphp_get_vars ')) {
191+ $config = frankenphp_get_vars ('config-watcher');
191192} else {
192193 $config = ['MASTER_HOST' => getenv('REDIS_HOST') ?: '127.0.0.1'];
193194}
0 commit comments