fix: handle complete empty snapshots and match dropdown trigger width

This commit is contained in:
Andras Bacsai
2026-08-16 18:26:40 +02:00
parent 9729e765b4
commit e28d8ca0ff
4 changed files with 23 additions and 21 deletions
+1 -19
View File
@@ -188,7 +188,7 @@ class PushServerUpdateJob implements ShouldBeEncrypted, ShouldQueue, Silenced
Cache::forget($storageCacheKey);
}
if ($this->containers->isEmpty()) {
if ($this->containers->isEmpty() && ! $this->isCompleteSnapshot()) {
return;
}
@@ -625,12 +625,6 @@ class PushServerUpdateJob implements ShouldBeEncrypted, ShouldQueue, Silenced
return;
}
// Only protection: Verify we received any container data at all
// If containers collection is completely empty, Sentinel might have failed
if ($this->containers->isEmpty()) {
return;
}
// Batch update: mark all not-found applications as exited (excluding already exited ones)
Application::whereIn('id', $notFoundApplicationIds)
->where('status', 'not like', 'exited%')
@@ -644,12 +638,6 @@ class PushServerUpdateJob implements ShouldBeEncrypted, ShouldQueue, Silenced
return;
}
// Only protection: Verify we received any container data at all
// If containers collection is completely empty, Sentinel might have failed
if ($this->containers->isEmpty()) {
return;
}
// Collect IDs of previews that need to be marked as exited
$previewIdsToUpdate = collect();
foreach ($notFoundApplicationPreviewsIds as $previewKey) {
@@ -738,12 +726,6 @@ class PushServerUpdateJob implements ShouldBeEncrypted, ShouldQueue, Silenced
return;
}
// Only protection: Verify we received any container data at all
// If containers collection is completely empty, Sentinel might have failed
if ($this->containers->isEmpty()) {
return;
}
$notFoundDatabaseUuids->each(function ($databaseUuid) {
$database = $this->databasesByUuid->get($databaseUuid);
if ($database) {
@@ -35,7 +35,7 @@
const availableHeight = window.innerHeight - (edge * 2);
const triggerRect = trigger.getBoundingClientRect();
const desiredWidth = config.matchTriggerWidth
? Math.max(triggerRect.width, panel.offsetWidth)
? triggerRect.width
: panel.offsetWidth;
const panelWidth = Math.min(desiredWidth, availableWidth);
const panelHeight = Math.min(panel.scrollHeight, config.maxHeight ?? availableHeight);
@@ -77,7 +77,7 @@ test('database status is updated when container status changes', function () {
expect($database->status)->toBe('running:healthy');
});
test('database is not marked exited when containers list is empty', function () {
test('database is not marked exited when an incomplete containers snapshot is empty', function () {
$team = Team::factory()->create();
$database = createPushUpdatePostgresql($team, [
'status' => 'running:healthy',
@@ -88,6 +88,7 @@ test('database is not marked exited when containers list is empty', function ()
// Empty containers = Sentinel might have failed, should NOT mark as exited
$data = [
'containers' => [],
'snapshot' => ['complete' => false],
];
$job = new PushServerUpdateJob($server, $data);
@@ -99,6 +100,22 @@ test('database is not marked exited when containers list is empty', function ()
expect($database->status)->toBe('running:healthy');
});
test('database is marked exited when a complete containers snapshot is empty', function () {
$team = Team::factory()->create();
$database = createPushUpdatePostgresql($team, [
'status' => 'running:healthy',
]);
$data = [
'containers' => [],
'snapshot' => ['complete' => true],
];
(new PushServerUpdateJob($database->destination->server, $data))->handle();
expect($database->refresh()->status)->toBe('exited:unhealthy');
});
function createPushUpdatePostgresql(Team $team, array $attributes = []): StandalonePostgresql
{
$lastOnlineAt = $attributes['last_online_at'] ?? null;
@@ -46,6 +46,9 @@ it('centralizes floating dropdown positioning in an Alpine data provider', funct
->toContain('window.floatingDropdown = function floatingDropdown')
->toContain('window.requestAnimationFrame')
->toContain('positionPanel(panel = null)')
->toContain('const desiredWidth = config.matchTriggerWidth')
->toContain('? triggerRect.width')
->not->toContain('? Math.max(triggerRect.width, panel.offsetWidth)')
->toContain('window.innerWidth < 768');
});