(int)config('archive.max_chain', 500)) { exit; // runaway guard; the next page view starts a fresh chain } $wait = archive_queue_wait(); if ($wait === null) { // Queue empty: the chain ends here, and its counter resets with it. json_update(archive_queue_file(), function (array $queue): array { $queue['chain'] = 0; return $queue; }); exit; } if ($wait > 0) { // Nothing has settled yet. Waiting here rather than exiting is what lets a // gallery nobody is looking at still rebuild on its own. // // Kept short: this holds both a PHP process and the worker lock, and an // admin clicking "Rebuild now" has to wait it out. A settle window is // bridged by a chain of these short waits instead of one long one. sleep(min($wait, 15)); } else { $slug = archive_next_due(); if ($slug !== null) { archive_run_slice($slug); } } // Release before handing off, so the successor can start immediately. flock($lock, LOCK_UN); fclose($lock); if (archive_queue_wait() !== null) { archive_dispatch(2000); }