Skip to content

Commit f22859b

Browse files
committed
Force mark as completed.
1 parent 5d7a0c3 commit f22859b

File tree

6 files changed

+88
-29
lines changed

6 files changed

+88
-29
lines changed

src/Actions/ResolveGarbageAction.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,11 @@ public function shouldMarkComplete(MailatorSchedule $schedule): bool
3131
return false;
3232
}
3333

34-
if (! $schedule->nextTrigger()) {
34+
if (!$schedule->nextTrigger()) {
35+
return true;
36+
}
37+
38+
if ($schedule->failedLastTimes(3)) {
3539
return true;
3640
}
3741

src/Constraints/OnceConstraint.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ class OnceConstraint implements SendScheduleConstraint
1010
public function canSend(MailatorSchedule $schedule, Collection $logs): bool
1111
{
1212
return $schedule->isOnce()
13-
? $logs->count() === 0
13+
? is_null($schedule->last_sent_at)
1414
: true;
1515
}
1616
}

src/Models/MailatorLog.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,9 @@ public function isSent(): bool
4343
{
4444
return $this->status === static::STATUS_SENT;
4545
}
46+
47+
public function isFailed(): bool
48+
{
49+
return $this->status === static::STATUS_FAILED;
50+
}
4651
}

src/Models/MailatorSchedule.php

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,22 @@
33
namespace Binarcode\LaravelMailator\Models;
44

55
use Binarcode\LaravelMailator\Actions\Action;
6+
use Binarcode\LaravelMailator\Actions\ResolveGarbageAction;
67
use Binarcode\LaravelMailator\Constraints\SendScheduleConstraint;
78
use Binarcode\LaravelMailator\Jobs\SendMailJob;
89
use Binarcode\LaravelMailator\Models\Builders\MailatorSchedulerBuilder;
910
use Binarcode\LaravelMailator\Models\Concerns\ConstraintsResolver;
1011
use Binarcode\LaravelMailator\Models\Concerns\HasFuture;
1112
use Binarcode\LaravelMailator\Models\Concerns\HasTarget;
1213
use Binarcode\LaravelMailator\Support\ClassResolver;
14+
use Binarcode\LaravelMailator\Support\ConverterEnum;
1315
use Carbon\Carbon;
1416
use Carbon\CarbonInterface;
1517
use Closure;
1618
use Exception;
1719
use Illuminate\Contracts\Mail\Mailable;
1820
use Illuminate\Database\Eloquent\Model;
21+
use Illuminate\Database\Eloquent\Relations\HasMany;
1922
use Illuminate\Support\Arr;
2023
use Illuminate\Support\Facades\Validator;
2124
use Illuminate\Support\Str;
@@ -55,24 +58,6 @@ public function getTable()
5558
return config('mailator.schedulers_table_name', 'mailator_schedulers');
5659
}
5760

58-
public const MINUTES_IN_HOUR = 60;
59-
public const MINUTES_IN_DAY = 60 * 60;
60-
public const MINUTES_IN_WEEK = 168 * 60;
61-
public const HOURS_IN_DAY = 24;
62-
public const HOURS_IN_WEEK = 168;
63-
64-
public const FREQUENCY_IN_HOURS = [
65-
'single' => PHP_INT_MAX,
66-
'hourly' => 1,
67-
'daily' => self::HOURS_IN_DAY,
68-
'weekly' => self::HOURS_IN_WEEK,
69-
];
70-
71-
const DELAY_OPTIONS = [
72-
'24' => 'Days',
73-
'168' => 'Weeks',
74-
];
75-
7661
public const TIME_FRAME_ORIGIN_BEFORE = 'before';
7762
public const TIME_FRAME_ORIGIN_AFTER = 'after';
7863

@@ -169,14 +154,14 @@ public function hourly(): self
169154
return $this;
170155
}
171156

172-
public function daily()
157+
public function daily(): static
173158
{
174159
$this->frequency_option = static::FREQUENCY_OPTIONS_DAILY;
175160

176161
return $this;
177162
}
178163

179-
public function weekly()
164+
public function weekly(): static
180165
{
181166
$this->frequency_option = static::FREQUENCY_OPTIONS_WEEKLY;
182167

@@ -256,12 +241,12 @@ public function toDays(): int
256241
{
257242
//let's say we have 1 day and 2 hours till day job ends
258243
//so we will floor it to 1, and will send the reminder in time
259-
return (int) floor($this->delay_minutes / static::MINUTES_IN_DAY);
244+
return (int) floor($this->delay_minutes / ConverterEnum::MINUTES_IN_DAY);
260245
}
261246

262247
public function toHours(): int
263248
{
264-
return (int) floor($this->delay_minutes / static::MINUTES_IN_HOUR);
249+
return (int) floor($this->delay_minutes / ConverterEnum::MINUTES_IN_HOUR);
265250
}
266251

267252
public function minutes(int $number): self
@@ -273,21 +258,21 @@ public function minutes(int $number): self
273258

274259
public function hours(int $number): self
275260
{
276-
$this->delay_minutes = $number * static::MINUTES_IN_HOUR;
261+
$this->delay_minutes = $number * ConverterEnum::MINUTES_IN_HOUR;
277262

278263
return $this;
279264
}
280265

281266
public function days(int $number): self
282267
{
283-
$this->delay_minutes = $number * static::MINUTES_IN_DAY;
268+
$this->delay_minutes = $number * ConverterEnum::MINUTES_IN_DAY;
284269

285270
return $this;
286271
}
287272

288-
public function weeks(int $number)
273+
public function weeks(int $number): static
289274
{
290-
$this->delay_minutes = $number * static::MINUTES_IN_WEEK;
275+
$this->delay_minutes = $number * ConverterEnum::MINUTES_IN_WEEK;
291276

292277
return $this;
293278
}
@@ -319,7 +304,7 @@ public function when(Closure $closure): self
319304
return $this;
320305
}
321306

322-
public function logs()
307+
public function logs(): HasMany
323308
{
324309
return $this->hasMany(MailatorLog::class, 'mailator_schedule_id');
325310
}
@@ -329,10 +314,13 @@ public function shouldSend(): bool
329314
try {
330315
$this->load('logs');
331316

317+
332318
return $this->configurationsPasses() && $this->whenPasses() && $this->eventsPasses();
333319
} catch (Exception | Throwable $e) {
334320
$this->markAsFailed($e->getMessage());
335321

322+
app(ResolveGarbageAction::class)->handle($this);
323+
336324
return false;
337325
}
338326
}
@@ -480,4 +468,16 @@ public function markComplete(): self
480468

481469
return $this;
482470
}
471+
472+
public function failedLastTimes(int $times): bool
473+
{
474+
return $this
475+
->logs()
476+
->latest()
477+
->take($times)
478+
->get()
479+
->filter
480+
->isFailed()
481+
->count() === $times;
482+
}
483483
}

src/Support/ConverterEnum.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
namespace Binarcode\LaravelMailator\Support;
4+
5+
class ConverterEnum
6+
{
7+
public const MINUTES_IN_HOUR = 60;
8+
public const MINUTES_IN_DAY = 60 * 60;
9+
public const MINUTES_IN_WEEK = 168 * 60;
10+
public const HOURS_IN_DAY = 24;
11+
public const HOURS_IN_WEEK = 168;
12+
13+
14+
15+
}

tests/Feature/SchedulerGarbageTest.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
namespace Binarcode\LaravelMailator\Tests\Feature;
44

55
use Binarcode\LaravelMailator\Models\MailatorSchedule;
6+
use Binarcode\LaravelMailator\Tests\Fixtures\Actions\NoopAction;
7+
use Binarcode\LaravelMailator\Tests\Fixtures\Constraints\FailingConstraint;
68
use Binarcode\LaravelMailator\Tests\Fixtures\CustomAction;
79
use Binarcode\LaravelMailator\Tests\Fixtures\User;
810
use Binarcode\LaravelMailator\Tests\TestCase;
@@ -44,4 +46,37 @@ public function test_executed_schedulers_filtered_out(): void
4446
->get()
4547
);
4648
}
49+
50+
public function test_three_failed_is_considered_completed(): void
51+
{
52+
Mail::fake();
53+
Mail::assertNothingSent();
54+
55+
$schedule = MailatorSchedule::init('Invoice reminder.')
56+
->days(1)
57+
->before(now()->addDays(2))
58+
->constraint(new FailingConstraint)
59+
->actionClass(new NoopAction);
60+
61+
$schedule->save();
62+
63+
self::assertCount(
64+
1,
65+
MailatorSchedule::query()
66+
->ready()
67+
->get()
68+
);
69+
70+
$this->travel(1)->days();
71+
MailatorSchedule::run();
72+
MailatorSchedule::run();
73+
MailatorSchedule::run();
74+
75+
self::assertCount(
76+
0,
77+
MailatorSchedule::query()
78+
->ready()
79+
->get()
80+
);
81+
}
4782
}

0 commit comments

Comments
 (0)