From c99c8d4c38311207eb6b452374eb5e113f48544a Mon Sep 17 00:00:00 2001 From: Chris Huber Date: Sun, 5 Jul 2026 14:59:19 -0400 Subject: [PATCH 1/2] Handle HybridStore missing group claims --- .../class-wp-agent-workflow-scoped-drain.php | 29 +++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/src/Workflows/class-wp-agent-workflow-scoped-drain.php b/src/Workflows/class-wp-agent-workflow-scoped-drain.php index 8275238..8404727 100644 --- a/src/Workflows/class-wp-agent-workflow-scoped-drain.php +++ b/src/Workflows/class-wp-agent-workflow-scoped-drain.php @@ -356,8 +356,10 @@ private function run_batch( int $batch_size, array $hooks, string $group, float $this->reset_stale_timeouts( $store ); // stake_claim( $max, $before_date, $hooks, $group ). Claiming over the // scoped hooks + group means we only ever run THIS caller's scope — never - // an unrelated AS workload sharing the queue. - $claim = $store->stake_claim( $batch_size, null, $hooks, $group ); + // an unrelated AS workload sharing the queue. HybridStore can transiently + // throw "group does not exist" while actions for that group are readable; + // in that case retry hook-scoped only rather than failing the foreground pump. + $claim = $this->stake_claim( $store, $batch_size, $hooks, $group ); } catch ( \Throwable $throwable ) { unset( $throwable ); return array( @@ -408,6 +410,29 @@ private function run_batch( int $batch_size, array $hooks, string $group, float ); } + /** + * Stake a scoped claim, falling back to hook-only scope when HybridStore cannot + * resolve an otherwise-readable group. + * + * @since 0.5.2 + * + * @param object $store Action Scheduler store. + * @param int $batch_size Maximum actions to claim. + * @param array $hooks Hook scope. + * @param string $group Group scope. + * @return object Action Scheduler claim. + */ + private function stake_claim( object $store, int $batch_size, array $hooks, string $group ): object { + try { + return $store->stake_claim( $batch_size, null, $hooks, $group ); + } catch ( \InvalidArgumentException $error ) { + if ( '' === $group || false === stripos( $error->getMessage(), 'group' ) ) { + throw $error; + } + return $store->stake_claim( $batch_size, null, $hooks, '' ); + } + } + /** * Refuse the drain when it is invoked from a claimed-action or re-entrant * context. Returns a non-empty refusal reason string when the drain must NOT From 117b551e33845bbb8702011b981ca52b0f16e82d Mon Sep 17 00:00:00 2001 From: Chris Huber Date: Sun, 5 Jul 2026 15:01:05 -0400 Subject: [PATCH 2/2] Type scoped drain HybridStore claims --- src/Workflows/class-wp-agent-workflow-scoped-drain.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Workflows/class-wp-agent-workflow-scoped-drain.php b/src/Workflows/class-wp-agent-workflow-scoped-drain.php index 8404727..7d9ebba 100644 --- a/src/Workflows/class-wp-agent-workflow-scoped-drain.php +++ b/src/Workflows/class-wp-agent-workflow-scoped-drain.php @@ -345,6 +345,7 @@ static function ( $hook ): bool { * @return array{processed:int,warnings:int,stop_reason:string} Batch result. */ private function run_batch( int $batch_size, array $hooks, string $group, float $deadline_at, string $execution_context ): array { + /** @var \ActionScheduler_Store $store */ $store = \ActionScheduler_Store::instance(); $runner = \ActionScheduler::runner(); $processed = 0; @@ -416,13 +417,13 @@ private function run_batch( int $batch_size, array $hooks, string $group, float * * @since 0.5.2 * - * @param object $store Action Scheduler store. + * @param \ActionScheduler_Store $store Action Scheduler store. * @param int $batch_size Maximum actions to claim. * @param array $hooks Hook scope. * @param string $group Group scope. - * @return object Action Scheduler claim. + * @return \ActionScheduler_ActionClaim Action Scheduler claim. */ - private function stake_claim( object $store, int $batch_size, array $hooks, string $group ): object { + private function stake_claim( \ActionScheduler_Store $store, int $batch_size, array $hooks, string $group ): \ActionScheduler_ActionClaim { try { return $store->stake_claim( $batch_size, null, $hooks, $group ); } catch ( \InvalidArgumentException $error ) {