Ship production optimization M1-M12.5A: queues, metrics, HTTP observability, and vector search reliability.

Keep similar-ai from tripping the global circuit on a lone URL 502, clamp Qdrant search to 100, and add Server-Timing plus slow-request logging. Studio shared props, Academy S3 exists caching, heat chunking, and Redis/scheduler hygiene stay in this rollout.
This commit is contained in:
2026-08-25 07:58:47 +02:00
parent f52879edbb
commit 8a80aae21e
114 changed files with 9293 additions and 284 deletions
@@ -16,6 +16,10 @@ class CollectionBackgroundJobService
{
public function dispatchQualityRefresh(Collection $collection, ?User $actor = null): array
{
if (! $this->dispatchEnabled()) {
return $this->disabledPayload('quality_refresh', $collection ? collect([$collection]) : collect());
}
RefreshCollectionQualityJob::dispatch((int) $collection->id, $actor?->id)->afterCommit();
return [
@@ -30,6 +34,10 @@ class CollectionBackgroundJobService
public function dispatchHealthRefresh(?Collection $collection = null, ?User $actor = null): array
{
if (! $this->dispatchEnabled()) {
return $this->disabledPayload('health_refresh', $collection ? collect([$collection]) : collect());
}
$targets = $collection ? collect([$collection]) : $this->healthTargets();
$targets->each(fn (Collection $item) => RefreshCollectionHealthJob::dispatch((int) $item->id, $actor?->id, 'programming-eligibility')->afterCommit());
@@ -39,6 +47,10 @@ class CollectionBackgroundJobService
public function dispatchRecommendationRefresh(?Collection $collection = null, ?User $actor = null, string $context = 'default'): array
{
if (! $this->dispatchEnabled()) {
return $this->disabledPayload('recommendation_refresh', $collection ? collect([$collection]) : collect());
}
$targets = $collection ? collect([$collection]) : $this->recommendationTargets();
$targets->each(fn (Collection $item) => RefreshCollectionRecommendationJob::dispatch((int) $item->id, $actor?->id, $context)->afterCommit());
@@ -48,6 +60,10 @@ class CollectionBackgroundJobService
public function dispatchDuplicateScan(?Collection $collection = null, ?User $actor = null): array
{
if (! $this->dispatchEnabled()) {
return $this->disabledPayload('duplicate_scan', $collection ? collect([$collection]) : collect());
}
$targets = $collection ? collect([$collection]) : $this->duplicateTargets();
$targets->each(fn (Collection $item) => ScanCollectionDuplicateCandidatesJob::dispatch((int) $item->id, $actor?->id)->afterCommit());
@@ -128,6 +144,29 @@ class CollectionBackgroundJobService
->get(['id']);
}
private function dispatchEnabled(): bool
{
return (bool) config('collections.v5.queue.dispatch_enabled', false);
}
/**
* @param SupportCollection<int, Collection> $targets
*/
private function disabledPayload(string $job, SupportCollection $targets): array
{
$ids = $targets->pluck('id')->map(static fn ($id): int => (int) $id)->values()->all();
return [
'status' => 'disabled',
'job' => $job,
'scope' => count($ids) === 1 ? 'single' : 'batch',
'count' => 0,
'collection_ids' => $ids,
'items' => [],
'message' => 'Collection queue dispatch is disabled until a Horizon consumer exists.',
];
}
/**
* @param SupportCollection<int, Collection> $targets
*/