Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[1.x] Ignore offline servers (continued) #355

Merged
merged 11 commits into from
May 1, 2024
29 changes: 29 additions & 0 deletions src/Livewire/Servers.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
namespace Laravel\Pulse\Livewire;

use Carbon\CarbonImmutable;
use Carbon\CarbonInterval;
use Illuminate\Contracts\Support\Renderable;
use Illuminate\Support\Facades\View;
use Illuminate\Support\InteractsWithTime;
use Livewire\Attributes\Lazy;
use Livewire\Livewire;

Expand All @@ -14,6 +16,10 @@
#[Lazy]
class Servers extends Card
{
use InteractsWithTime;

public int|string|null $ignoreAfter = null;

Comment on lines +19 to +22
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Livewire does not support DateInterval as a prop value, so I've excluded it from the type here.

Due to the way Livewire serializes values, we also cannot use now()->addSeconds(60) in the prop value.

/**
* Render the component.
*/
Expand All @@ -24,6 +30,10 @@ public function render(): Renderable

return $this->values('system')
->map(function ($system, $slug) use ($graphs) {
if ($this->ignoreSystem($system)) {
return null;
}

$values = json_decode($system->value, flags: JSON_THROW_ON_ERROR);

return (object) [
Expand All @@ -38,6 +48,7 @@ public function render(): Renderable
'recently_reported' => $updatedAt->isAfter(now()->subSeconds(30)),
];
})
->filter()
->sortBy('name');
});

Expand All @@ -59,4 +70,22 @@ public function placeholder(): Renderable
{
return View::make('pulse::components.servers-placeholder', ['cols' => $this->cols, 'rows' => $this->rows, 'class' => $this->class]);
}

/**
* Determine if the system should be ignored.
*
* @param object{ timestamp: int, key: string, value: string } $system
*/
protected function ignoreSystem(object $system): bool
{
if ($this->ignoreAfter === null) {
return false;
}

$ignoreAfter = is_numeric($this->ignoreAfter)
? (int) $this->ignoreAfter
: CarbonInterval::createFromDateString($this->ignoreAfter)->totalSeconds;

return CarbonImmutable::createFromTimestamp($system->timestamp)->addSeconds($ignoreAfter)->isPast();
}
Comment on lines +74 to +90
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've called this ignoreSystem to differentiate it from our shared ignore method on the Ignores trait.

}
48 changes: 48 additions & 0 deletions tests/Feature/Livewire/ServersTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,51 @@
Livewire::test(Servers::class, ['lazy' => false])
->assertSeeInOrder(['A Web', 'B Web', 'C Web']);
});

it('can ignore servers that have stopped reporting', function ($ignoreAfter, $see, $dontSee) {
Carbon::setTestNow(now()->startOfSecond());

$data = [
'memory_used' => 1234,
'memory_total' => 2468,
'cpu' => 99,
'storage' => [
['directory' => '/', 'used' => 123, 'total' => 456],
],
];

Pulse::set('system', 'server-1', json_encode([
'name' => 'Server 1',
...$data,
]), now()->subSeconds(599));

Pulse::set('system', 'server-2', json_encode([
'name' => 'Server 2',
...$data,
]), now()->subSeconds(600));

Pulse::set('system', 'server-3', json_encode([
'name' => 'Server 3',
...$data,
]), now()->subSeconds(601));

Pulse::ingest();

Livewire::test(Servers::class, ['lazy' => false, 'ignoreAfter' => value($ignoreAfter)])
->assertSeeInOrder($see)
->assertDontSeeText($dontSee);
})->with([
[null, ['Server 1', 'Server 2', 'Server 3'], []],
[588, [], ['Server 1', 'Server 2', 'Server 3']],
[599, ['Server 1'], ['Server 2', 'Server 3']],
[600, ['Server 1', 'Server 2'], ['Server 3']],
[601, ['Server 1', 'Server 2', 'Server 3'], []],
['588', [], ['Server 1', 'Server 2', 'Server 3']],
['599', ['Server 1'], ['Server 2', 'Server 3']],
['600', ['Server 1', 'Server 2'], ['Server 3']],
['601', ['Server 1', 'Server 2', 'Server 3'], []],
['588 seconds', [], ['Server 1', 'Server 2', 'Server 3']],
['599 seconds', ['Server 1'], ['Server 2', 'Server 3']],
['600 seconds', ['Server 1', 'Server 2'], ['Server 3']],
['601 seconds', ['Server 1', 'Server 2', 'Server 3'], []],
]);