0) { $callback(); return; } $exception = null; \Swoole\Coroutine\run(static function () use ($callback, &$exception): void { try { $callback(); } catch (\Throwable $e) { $exception = $e; } }); if ($exception) { throw $exception; } } /** * 调用 protected enqueueAffectedDates 方法 */ protected function invokeEnqueue(array $payloads): void { $consumer = new OrderConsumer(); $method = new ReflectionMethod($consumer, 'enqueueAffectedDates'); $method->setAccessible(true); $method->invoke($consumer, $payloads); } /** * 清理指定日期的队列条目(前置 + 后置双保险) */ protected function cleanupQueue(string $date): void { AggregateRefreshQueue::query() ->where('refresh_date', $date) ->where('aggregate_view', 'orders_daily_by_created') ->delete(); } /** * 当日订单不应入队(在自动刷新策略覆盖窗口内) */ public function test_today_payload_does_not_enqueue(): void { $this->runInCoroutine(function (): void { $today = Carbon::now()->toDateString(); $payloads = [['created_date' => Carbon::now()->format('Y-m-d H:i:sP')]]; $this->cleanupQueue($today); try { $this->invokeEnqueue($payloads); $row = AggregateRefreshQueue::query() ->where('refresh_date', $today) ->where('aggregate_view', 'orders_daily_by_created') ->first(); $this->assertNull($row); } finally { $this->cleanupQueue($today); } }); } /** * 2 天前订单不应入队(仍在自动刷新策略 [now-3d, now-1h] 窗口内) */ public function test_two_days_ago_payload_does_not_enqueue(): void { $this->runInCoroutine(function (): void { $two_days_ago = Carbon::now()->subDays(2)->toDateString(); $payloads = [['created_date' => Carbon::now()->subDays(2)->format('Y-m-d H:i:sP')]]; $this->cleanupQueue($two_days_ago); try { $this->invokeEnqueue($payloads); $row = AggregateRefreshQueue::query() ->where('refresh_date', $two_days_ago) ->where('aggregate_view', 'orders_daily_by_created') ->first(); $this->assertNull($row); } finally { $this->cleanupQueue($two_days_ago); } }); } /** * 30 天前订单应入队 by_created(自动策略未覆盖,需补刷) */ public function test_old_payload_enqueues_by_created(): void { $this->runInCoroutine(function (): void { $old_date = Carbon::now()->subDays(30)->toDateString(); $payloads = [['created_date' => Carbon::now()->subDays(30)->format('Y-m-d H:i:sP')]]; $this->cleanupQueue($old_date); try { $this->invokeEnqueue($payloads); $row = AggregateRefreshQueue::query() ->where('refresh_date', $old_date) ->where('aggregate_view', 'orders_daily_by_created') ->first(); $this->assertNotNull($row); $this->assertSame($old_date, $row->refresh_date); $this->assertSame('orders_daily_by_created', $row->aggregate_view); } finally { $this->cleanupQueue($old_date); } }); } /** * 同日期重复入队由复合主键 + insertOrIgnore 防重 */ public function test_dedup_via_insert_or_ignore(): void { $this->runInCoroutine(function (): void { $old_date = Carbon::now()->subDays(45)->toDateString(); $payloads = [ ['created_date' => Carbon::now()->subDays(45)->format('Y-m-d H:i:sP')], ['created_date' => Carbon::now()->subDays(45)->format('Y-m-d H:i:sP')], ]; $this->cleanupQueue($old_date); try { // 单批次内同日期 → $unique_dates map 去重 $this->invokeEnqueue($payloads); // 跨批次同日期 → 复合主键 insertOrIgnore 防重 $this->invokeEnqueue($payloads); $count = AggregateRefreshQueue::query() ->where('refresh_date', $old_date) ->where('aggregate_view', 'orders_daily_by_created') ->count(); $this->assertSame(1, $count); } finally { $this->cleanupQueue($old_date); } }); } }