Skip to content

Commit

Permalink
Store schedule monitoring configurations in its own singleton
Browse files Browse the repository at this point in the history
Instead of declaring runtime properties in the macros, we delegate storage of configuration properties to an extra class.
  • Loading branch information
m-bymike committed Aug 5, 2024
1 parent 7f96c75 commit 89d7af7
Show file tree
Hide file tree
Showing 6 changed files with 140 additions and 16 deletions.
28 changes: 18 additions & 10 deletions src/ScheduleMonitorServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -111,32 +111,40 @@ protected function registerEventHandlers(): self

protected function registerSchedulerEventMacros(): self
{
SchedulerEvent::macro('monitorName', function (string $monitorName) {
$this->monitorName = $monitorName;
$this->app->singleton(
Support\ScheduledTasks\ScheduleMonitoringConfigurationsRepository::class,
static fn () => new Support\ScheduledTasks\ScheduleMonitoringConfigurationsRepository(),
);

/** @var Support\ScheduledTasks\ScheduleMonitoringConfigurationsRepository $scheduleMonitoringConfigurationsRepository */
$scheduleMonitoringConfigurationsRepository = $this->app->make(Support\ScheduledTasks\ScheduleMonitoringConfigurationsRepository::class);

SchedulerEvent::macro('monitorName', function (string $monitorName) use ($scheduleMonitoringConfigurationsRepository) {
$scheduleMonitoringConfigurationsRepository->setMonitorName($this, $monitorName);

return $this;
});

SchedulerEvent::macro('graceTimeInMinutes', function (int $graceTimeInMinutes) {
$this->graceTimeInMinutes = $graceTimeInMinutes;
SchedulerEvent::macro('graceTimeInMinutes', function (int $graceTimeInMinutes) use ($scheduleMonitoringConfigurationsRepository) {
$scheduleMonitoringConfigurationsRepository->setGraceTimeInMinutes($this, $graceTimeInMinutes);

return $this;
});

SchedulerEvent::macro('doNotMonitor', function (bool $bool = true) {
$this->doNotMonitor = $bool;
SchedulerEvent::macro('doNotMonitor', function (bool $bool = true) use ($scheduleMonitoringConfigurationsRepository) {
$scheduleMonitoringConfigurationsRepository->setDoNotMonitor($this, $bool);

return $this;
});

SchedulerEvent::macro('doNotMonitorAtOhDear', function (bool $bool = true) {
$this->doNotMonitorAtOhDear = $bool;
SchedulerEvent::macro('doNotMonitorAtOhDear', function (bool $bool = true) use ($scheduleMonitoringConfigurationsRepository) {
$scheduleMonitoringConfigurationsRepository->setDoNotMonitorAtOhDear($this, $bool);

return $this;
});

SchedulerEvent::macro('storeOutputInDb', function () {
$this->storeOutputInDb = true;
SchedulerEvent::macro('storeOutputInDb', function () use ($scheduleMonitoringConfigurationsRepository) {
$scheduleMonitoringConfigurationsRepository->setStoreOutputInDb($this, true);
/** @psalm-suppress UndefinedMethod */
$this->ensureOutputIsBeingCaptured();

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace Spatie\ScheduleMonitor\Support\Concerns;

use Spatie\ScheduleMonitor\Support\ScheduledTasks\ScheduleMonitoringConfigurationsRepository;

trait UsesScheduleMonitoringConfigurationsRepository
{
public function getScheduleMonitoringConfigurationsRepository(): ScheduleMonitoringConfigurationsRepository
{
return app(ScheduleMonitoringConfigurationsRepository::class);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?php

namespace Spatie\ScheduleMonitor\Support\ScheduledTasks;

class ScheduleMonitoringConfigurationsRepository
{
private array $store = [];

public function setMonitorName(object $target, string $monitorName): void
{
$this->setProperty($target, 'monitorName', $monitorName);
}

public function getMonitorName(object $target): ?string
{
return $this->getProperty($target, 'monitorName');
}

public function setGraceTimeInMinutes(object $target, int $graceTimeInMinutes): void
{
$this->setProperty($target, 'graceTimeInMinutes', $graceTimeInMinutes);
}

public function getGraceTimeInMinutes(object $target): ?int
{
return $this->getProperty($target, 'graceTimeInMinutes');
}

public function setDoNotMonitor(object $target, bool $doNotMonitor = true): void
{
$this->setProperty($target, 'doNotMonitor', $doNotMonitor);
}

public function getDoNotMonitor(object $target): ?bool
{
return $this->getProperty($target, 'doNotMonitor');
}

public function setDoNotMonitorAtOhDear(object $target, bool $doNotMonitorAtOhDear = true): void
{
$this->setProperty($target, 'doNotMonitorAtOhDear', $doNotMonitorAtOhDear);
}

public function getDoNotMonitorAtOhDear(object $target): ?bool
{
return $this->getProperty($target, 'doNotMonitorAtOhDear');
}

public function setStoreOutputInDb(object $target, bool $storeOutputInDb = true): void
{
$this->setProperty($target, 'storeOutputInDb', $storeOutputInDb);
}

public function getStoreOutputInDb(object $target): ?bool
{
return $this->getProperty($target, 'storeOutputInDb');
}


private function setProperty(object $target, string $key, mixed $value): void
{
data_set($this->store, $this->makeKey($target, $key), $value);
}

private function getProperty(object $target, string $key): mixed
{
dump(__METHOD__, $this->store);

return data_get($this->store, $this->makeKey($target, $key));
}

private function makeKey(object $target, string $key): array
{
return [
$target::class,
spl_object_hash($target),
$key,
];
}
}
20 changes: 14 additions & 6 deletions src/Support/ScheduledTasks/Tasks/Task.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@
use Lorisleiva\CronTranslator\CronParsingException;
use Lorisleiva\CronTranslator\CronTranslator;
use Spatie\ScheduleMonitor\Models\MonitoredScheduledTask;
use Spatie\ScheduleMonitor\Support\Concerns\UsesScheduleMonitoringConfigurationsRepository;
use Spatie\ScheduleMonitor\Support\Concerns\UsesScheduleMonitoringModels;

abstract class Task
{
use UsesScheduleMonitoringModels;
use UsesScheduleMonitoringConfigurationsRepository;

protected Event $event;

Expand Down Expand Up @@ -46,16 +48,19 @@ public function uniqueId(): string

public function name(): ?string
{
return $this->event->monitorName ?? $this->defaultName();
return $this->getScheduleMonitoringConfigurationsRepository()->getMonitorName($this->event)
?? $this->defaultName();
}

public function shouldMonitor(): bool
{
if (! isset($this->event->doNotMonitor)) {
$doNotMonitor = $this->getScheduleMonitoringConfigurationsRepository()
->getDoNotMonitor($this->event);
if (! isset($doNotMonitor)) {
return true;
}

return ! $this->event->doNotMonitor;
return ! $doNotMonitor;
}

public function isBeingMonitored(): bool
Expand All @@ -65,11 +70,13 @@ public function isBeingMonitored(): bool

public function shouldMonitorAtOhDear(): bool
{
if (! isset($this->event->doNotMonitorAtOhDear)) {
$doNotMonitorAtOhDear = $this->getScheduleMonitoringConfigurationsRepository()
->getDoNotMonitorAtOhDear($this->event);
if (! isset($doNotMonitorAtOhDear)) {
return true;
}

return ! $this->event->doNotMonitorAtOhDear;
return ! $doNotMonitorAtOhDear;
}

public function isBeingMonitoredAtOhDear(): bool
Expand Down Expand Up @@ -163,7 +170,8 @@ public function lastRunFailed(): bool

public function graceTimeInMinutes()
{
return $this->event->graceTimeInMinutes ?? config('schedule-monitor.oh_dear.grace_time_in_minutes', 5);
return $this->getScheduleMonitoringConfigurationsRepository()->getGraceTimeInMinutes($this->event)
?? config('schedule-monitor.oh_dear.grace_time_in_minutes', 5);
}

public function cronExpression(): string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@
->monitorName('failing-task');
});


$this->artisan(SyncCommand::class)->assertExitCode(0);
$this->artisan('schedule:run')->assertExitCode(0);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

use Spatie\ScheduleMonitor\Support\Concerns\UsesScheduleMonitoringConfigurationsRepository;
use Spatie\ScheduleMonitor\Support\ScheduledTasks\ScheduleMonitoringConfigurationsRepository;

it('can resolve schedule monitoring configurations repository', function () {
$concern = new class() {
use UsesScheduleMonitoringConfigurationsRepository;
};

$repository = $concern->getScheduleMonitoringConfigurationsRepository();

expect($repository)->toBeInstanceOf(ScheduleMonitoringConfigurationsRepository::class);
});

0 comments on commit 89d7af7

Please sign in to comment.