Skip to content

Commit 6a6989a

Browse files
authored
Merge pull request #2552 from BinarCode/garbage
Optimize garbage and serialize actions.
2 parents 77b8c60 + aad522d commit 6a6989a

27 files changed

+827
-225
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
All notable changes to `laravel-mailator` will be documented in this file
44

5+
## 3.0.0 - 2021-06-08
6+
7+
- `actionClass` from MailatorScheduler now accept an instance of `Binarcode\LaravelMailator\Actions\Action`
8+
- `toDays()` helper added to MailatorScheduler
9+
- `tags()` added to MailatorScheduler
10+
511
## 2.0.0 - 2021-08-03
612

713
- The `before` and `after` methods now accept only an instance of Carbon

config/mailator.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@
2626
> The email sender class. It will be executed from the sender job.
2727
*/
2828
'send_mail_action' => Binarcode\LaravelMailator\Actions\SendMailAction::class,
29+
30+
/**
31+
* Class that will mark the scheduled action as being completed so the action will do not be counted into the next iteration.
32+
*/
33+
'garbage_resolver' => Binarcode\LaravelMailator\Actions\ResolveGarbageAction::class,
2934
],
3035

3136
'log_model' => Binarcode\LaravelMailator\Models\MailatorLog::class,

database/migrations/create_mailator_tables.php.stub

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class CreateMailatorTables extends Migration
3131

3232
$table->timestamp('last_sent_at')->nullable();
3333
$table->timestamp('last_failed_at')->nullable();
34+
$table->timestamp('completed_at')->nullable();
3435
$table->text('failure_reason')->nullable();
3536
$table->timestamps();
3637
});
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
namespace Binarcode\LaravelMailator\Actions;
4+
5+
use Binarcode\LaravelMailator\Models\MailatorSchedule;
6+
7+
class ResolveGarbageAction implements Action
8+
{
9+
public function handle(MailatorSchedule $schedule)
10+
{
11+
if ($this->shouldMarkComplete($schedule)) {
12+
$schedule->markComplete();
13+
}
14+
}
15+
16+
public function shouldMarkComplete(MailatorSchedule $schedule): bool
17+
{
18+
if ($schedule->isOnce() && $schedule->fresh()->last_sent_at) {
19+
return true;
20+
}
21+
22+
if ($schedule->isManual()) {
23+
return true;
24+
}
25+
26+
if ($schedule->isNever()) {
27+
return true;
28+
}
29+
30+
if ($schedule->isMany()) {
31+
return false;
32+
}
33+
34+
if (! $schedule->nextTrigger()) {
35+
return true;
36+
}
37+
38+
return false;
39+
}
40+
}

src/Actions/SendMailAction.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,20 @@
44

55
use Binarcode\LaravelMailator\Events\ScheduleMailSentEvent;
66
use Binarcode\LaravelMailator\Models\MailatorSchedule;
7+
use Binarcode\LaravelMailator\Support\ClassResolver;
78
use Exception;
89
use Illuminate\Support\Facades\Mail;
910

1011
class SendMailAction implements Action
1112
{
13+
use ClassResolver;
14+
1215
public function handle(MailatorSchedule $schedule)
1316
{
1417
try {
1518
$this->sendMail($schedule);
19+
20+
static::garbageResolver()->handle($schedule);
1621
} catch (Exception $exception) {
1722
$schedule->markAsFailed($exception->getMessage());
1823

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
namespace Binarcode\LaravelMailator\Console\Commands;
4+
5+
use Binarcode\LaravelMailator\Models\MailatorSchedule;
6+
use Binarcode\LaravelMailator\Support\ClassResolver;
7+
use Illuminate\Console\Command;
8+
9+
class GarbageCollectorCommand extends Command
10+
{
11+
use ClassResolver;
12+
13+
protected $signature = 'mailator:garbage
14+
{--dry : Update items completed_at column}
15+
';
16+
17+
protected $description = 'Will mark as complete all executed mails.';
18+
19+
public function handle()
20+
{
21+
$this->info('----- Starting garbage cleaning -----');
22+
$ids = collect();
23+
24+
MailatorSchedule::query()
25+
->ready()
26+
->cursor()
27+
->each(function (MailatorSchedule $mailatorSchedule) use ($ids) {
28+
if ($this->option('dry')) {
29+
static::garbageResolver()->handle($mailatorSchedule);
30+
} elseif (static::garbageResolver()->shouldMarkComplete($mailatorSchedule)) {
31+
$ids->push($mailatorSchedule->id);
32+
}
33+
});
34+
35+
if (! $dry = $this->option('dry')) {
36+
$ids->each(fn ($i) => $this->info('Scheduler id to complete: '.$i));
37+
}
38+
39+
$this->info("[".$ids->count()."] items matched.");
40+
$this->info('All done.');
41+
}
42+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
namespace Binarcode\LaravelMailator\Console\Commands;
4+
5+
use Binarcode\LaravelMailator\Models\MailatorSchedule;
6+
use Binarcode\LaravelMailator\Support\ClassResolver;
7+
use Illuminate\Console\Command;
8+
9+
class MailatorSchedulerCommand extends Command
10+
{
11+
use ClassResolver;
12+
13+
protected $signature = 'mailator:run';
14+
15+
protected $description = 'Run the mailator scheduler in Kernel.';
16+
17+
public function handle(): int
18+
{
19+
MailatorSchedule::run();
20+
21+
return 0;
22+
}
23+
}

src/Constraints/AfterConstraint.php

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,34 @@ public function canSend(MailatorSchedule $schedule, Collection $logs): bool
1717
return true;
1818
}
1919

20-
// it's in the future
21-
if (now()->lt($schedule->timestamp_target)) {
20+
if ($schedule->toDays() > 0) {
21+
if (now()->lt($schedule->timestamp_target->clone()->addDays($schedule->toDays()))) {
22+
return false;
23+
}
24+
25+
return $schedule->isOnce()
26+
? $schedule->timestamp_target->diffInDays(now()) === $schedule->toDays()
27+
: $schedule->timestamp_target->diffInDays(now()) > $schedule->toDays();
28+
}
29+
30+
if ($schedule->toHours() > 0) {
31+
if (now()->lt($schedule->timestamp_target->clone()->addHours($schedule->toHours()))) {
32+
return false;
33+
}
34+
35+
//till ends we should have at least toDays days
36+
return $schedule->isOnce()
37+
? $schedule->timestamp_target->diffInHours(now()) === $schedule->toHours()
38+
: $schedule->timestamp_target->diffInHours(now()) > $schedule->toHours();
39+
}
40+
41+
if (now()->lt($schedule->timestamp_target->clone()->addMinutes($schedule->delay_minutes))) {
2242
return false;
2343
}
2444

2545
//till ends we should have at least toDays days
2646
return $schedule->isOnce()
27-
? $schedule->timestamp_target->diffInDays(now()) === $schedule->toDays()
28-
: $schedule->timestamp_target->diffInDays(now()) > $schedule->toDays();
47+
? $schedule->timestamp_target->diffInHours(now()) === $schedule->delay_minutes
48+
: $schedule->timestamp_target->diffInHours(now()) > $schedule->delay_minutes;
2949
}
3050
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
3+
namespace Binarcode\LaravelMailator\Constraints;
4+
5+
interface Descriptionable
6+
{
7+
public static function conditions(): array;
8+
}

src/LaravelMailatorServiceProvider.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
namespace Binarcode\LaravelMailator;
44

5+
use Binarcode\LaravelMailator\Console\Commands\GarbageCollectorCommand;
6+
use Binarcode\LaravelMailator\Console\Commands\MailatorSchedulerCommand;
57
use Binarcode\LaravelMailator\Models\MailatorLog;
68
use Binarcode\LaravelMailator\Models\MailatorSchedule;
79
use Binarcode\LaravelMailator\Models\MailTemplate;
@@ -65,7 +67,10 @@ public function boot()
6567
], 'lang');*/
6668

6769
// Registering package commands.
68-
// $this->commands([]);
70+
$this->commands([
71+
GarbageCollectorCommand::class,
72+
MailatorSchedulerCommand::class,
73+
]);
6974
}
7075
}
7176

0 commit comments

Comments
 (0)