-
Declare the global with type hint at the top of the function or method:
global $global;
Verify $global is a \GlobalData\Client connected to GLOBALDATA_IP:2207 (set in start_task.php:41).
-
Choose a lock key using the pattern '<noun>_<id>' for per-service locks or a bare noun for global locks:
- Per-service:
$var = 'vps_host_' . $service_id; (see async_hyperv_queue_runner.php:16)
- Global singleton:
$var = 'processsing_queue'; or 'queuein' (see memcached_queue_task.php:40)
-
Add a request-state tracking variable for per-service locks (omit for simple boolean locks):
$requestVar = $var . '_request';
This step uses the $var from Step 2.
-
Initialize the lock key if not set:
if (!isset($global->$var)) {
$global->$var = 0;
}
Required before the first cas() in any code path that may run before the key exists.
-
Acquire with CAS — use time() as the held value for per-service locks (enables staleness detection); use 1 for simple boolean locks:
if ($global->cas($var, 0, time())) {
$global->$requestVar = 'initial_operation';
$global->$var = 0;
} else {
$delay = (int)time() - (int)$global->$var;
Worker::safeEcho("couldnt get lock for {$var} (running {$global->$requestVar} for {$delay} seconds)\n");
}
if (!$global->cas('queuein', 0, 1)) {
Worker::safeEcho('Cannot get global queuein lock, returning' . PHP_EOL);
return;
}
$global->queuein = 0;
-
Update $requestVar at each sub-step (per-service locks only) to track progress:
$global->$var = time();
$global->$requestVar = 'next_operation';
$global->$var = 0;
See async_hyperv_queue_runner.php:26-35 for this multi-phase pattern.
-
Release inside every async callback that terminates the work chain:
$task_connection->onMessage = function ($connection, $task_result) use ($task_connection, $var) {
$task_connection->close();
global $global;
$global->$var = 0;
};
Also add an onClose handler that releases the lock for connection-drop safety.