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
@@ -0,0 +1,96 @@
<?php
use App\Jobs\IndexUserJob;
use App\Support\Redis\OrphanQueueCleanup;
use Illuminate\Support\Facades\Redis;
function orphanRedisMock(int $llen, array $payloads, int $reserved = 0, int $delayed = 0)
{
$redis = Mockery::mock();
$redis->shouldReceive('llen')->with(Mockery::on(fn ($k) => str_ends_with((string) $k, ':notify')))->andReturn($llen);
$redis->shouldReceive('llen')->andReturn($llen);
$redis->shouldReceive('zcard')->andReturnUsing(function ($key) use ($reserved, $delayed) {
return str_contains((string) $key, 'reserved') ? $reserved : $delayed;
});
$redis->shouldReceive('lindex')->andReturnUsing(function ($key, $i) use ($payloads) {
return $payloads[$i % max(1, count($payloads))] ?? null;
});
Redis::shouldReceive('connection')->andReturn($redis);
return $redis;
}
it('dry-run inspects forum-moderation without unlinking', function () {
config(['skinbase_ai_moderation.queue.dispatch_enabled' => false]);
$payload = json_encode(['displayName' => 'cPad\\Plugins\\Forum\\Jobs\\AnalyzeForumPostJob']);
$redis = orphanRedisMock(5, [$payload]);
$redis->shouldReceive('unlink')->never();
$plan = app(OrphanQueueCleanup::class)->plan('forum-moderation');
expect($plan['can_execute'])->toBeTrue()
->and($plan['llen'])->toBe(5)
->and($plan['classes'])->toHaveKey('cPad\\Plugins\\Forum\\Jobs\\AnalyzeForumPostJob');
});
it('refuses forum cleanup when producer dispatch is enabled', function () {
config(['skinbase_ai_moderation.queue.dispatch_enabled' => true]);
$payload = json_encode(['displayName' => 'cPad\\Plugins\\Forum\\Jobs\\AnalyzeForumPostJob']);
orphanRedisMock(2, [$payload]);
$plan = app(OrphanQueueCleanup::class)->plan('forum-moderation');
expect($plan['can_execute'])->toBeFalse()
->and($plan['errors'])->toContain('producer_dispatch_enabled');
});
it('refuses protected default/search/mail queues', function () {
expect(fn () => app(OrphanQueueCleanup::class)->plan('default'))
->toThrow(\RuntimeException::class);
});
it('refuses unexpected job classes unless force is set', function () {
config(['skinbase_ai_moderation.queue.dispatch_enabled' => false]);
$payload = json_encode(['displayName' => IndexUserJob::class]);
orphanRedisMock(2, [$payload]);
$plan = app(OrphanQueueCleanup::class)->plan('forum-moderation');
expect($plan['errors'])->toContain('unexpected_job_classes');
$forced = app(OrphanQueueCleanup::class)->plan('forum-moderation', true);
expect($forced['errors'])->not->toContain('unexpected_job_classes');
});
it('execute unlinks only the intended orphan queue keys', function () {
config(['skinbase_ai_moderation.queue.dispatch_enabled' => false]);
$payload = json_encode(['displayName' => 'cPad\\Plugins\\Forum\\Jobs\\AnalyzeForumPostJob']);
$redis = orphanRedisMock(3, [$payload]);
$redis->shouldReceive('unlink')->once()->with('queues:forum-moderation')->andReturn(1);
$redis->shouldReceive('unlink')->once()->with('queues:forum-moderation:notify')->andReturn(1);
$result = app(OrphanQueueCleanup::class)->execute('forum-moderation');
expect($result['unlinked'])->toBe(2)
->and($result['unlinked_keys'])->toBe(['queues:forum-moderation', 'queues:forum-moderation:notify']);
});
it('plans forum-security cleanup for monitor jobs', function () {
config(['forum_security.queues.dispatch_enabled' => false]);
$payload = json_encode(['displayName' => 'cPad\\Plugins\\Forum\\Jobs\\FirewallActivityMonitor']);
orphanRedisMock(4, [$payload]);
$plan = app(OrphanQueueCleanup::class)->plan('forum-security');
expect($plan['can_execute'])->toBeTrue();
});
it('artisan dry-run does not unlink', function () {
config(['skinbase_ai_moderation.queue.dispatch_enabled' => false]);
$payload = json_encode(['displayName' => 'cPad\\Plugins\\Forum\\Jobs\\AnalyzeForumPostJob']);
$redis = orphanRedisMock(1, [$payload]);
$redis->shouldReceive('unlink')->never();
Redis::shouldReceive('connection')->andReturn($redis);
$this->artisan('skinbase:redis-cleanup-orphans forum-moderation --dry-run')
->assertSuccessful();
});