Skip to content

Commit ac99cbb

Browse files
committed
Add scheduled task dispatcher
1 parent c1f4e05 commit ac99cbb

File tree

5 files changed

+126
-7
lines changed

5 files changed

+126
-7
lines changed

README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,24 @@ $user->tasks()->completed()->get();
4747

4848
// Get all tasks that are completed and have a due date in the future
4949
$user->tasks()->completed()->future()->get();
50+
51+
// Schedule a job for a task
52+
$user->addTask([
53+
'name' => 'Cleanup',
54+
'job' => \App\Jobs\CleanupJob::class,
55+
'job_data' => json_encode(['force' => true]),
56+
'due_date' => now()->addMinutes(10),
57+
]);
58+
```
59+
60+
Run the dispatcher command manually if needed:
61+
62+
```bash
63+
php artisan tasks:dispatch
5064
```
5165

66+
When `TASKS_AUTO_SCHEDULE` is enabled (the default), this command is automatically scheduled to run every minute.
67+
5268

5369
### Testing (Not implemented yet)
5470

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
3+
namespace Michal78\Tasks\Console\Commands;
4+
5+
use Illuminate\Console\Command;
6+
use Michal78\Tasks\Models\Task;
7+
use Illuminate\Support\Facades\Bus;
8+
9+
class DispatchDueTasksCommand extends Command
10+
{
11+
protected $signature = 'tasks:dispatch';
12+
protected $description = 'Dispatch all due tasks';
13+
14+
public function handle(): int
15+
{
16+
$tasks = Task::where('status', Task::STATUS_PENDING)
17+
->whereNotNull('job')
18+
->whereNotNull('due_date')
19+
->where('due_date', '<=', now())
20+
->get();
21+
22+
foreach ($tasks as $task) {
23+
$job = new $task->job($task->job_data);
24+
Bus::dispatch($job);
25+
26+
$task->status = Task::STATUS_RUNNING;
27+
$task->save();
28+
}
29+
30+
$this->info($tasks->count() . ' tasks dispatched.');
31+
32+
return Command::SUCCESS;
33+
}
34+
}

src/TasksServiceProvider.php

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
namespace Michal78\Tasks;
44

5+
use Illuminate\Console\Scheduling\Schedule;
56
use Illuminate\Support\ServiceProvider;
7+
use Michal78\Tasks\Console\Commands\DispatchDueTasksCommand;
68

79
class TasksServiceProvider extends ServiceProvider
810
{
@@ -22,13 +24,17 @@ public function boot(): void
2224
__DIR__.'/../config/config.php' => config_path('laravel-tasks.php'),
2325
], 'config');
2426

25-
// Publishing the translation files.
26-
/*$this->publishes([
27-
__DIR__.'/../resources/lang' => resource_path('lang/vendor/laravel-tasks'),
28-
], 'lang');*/
29-
30-
// Registering package commands.
31-
// $this->commands([]);
27+
// Register package command
28+
$this->commands([
29+
DispatchDueTasksCommand::class,
30+
]);
31+
32+
if (config('laravel-tasks.auto_schedule')) {
33+
$this->app->booted(function () {
34+
$schedule = $this->app->make(Schedule::class);
35+
$schedule->command('tasks:dispatch')->everyMinute();
36+
});
37+
}
3238
}
3339
}
3440

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
namespace Michal78\Tasks\Tests;
4+
5+
use Illuminate\Support\Facades\Artisan;
6+
use Illuminate\Support\Facades\Queue;
7+
use Michal78\Tasks\Models\Task;
8+
use Michal78\Tasks\Tests\Jobs\DummyJob;
9+
10+
class DispatchDueTasksCommandTest extends TestCase
11+
{
12+
public function test_command_dispatches_due_tasks()
13+
{
14+
Queue::fake();
15+
16+
$user = User::create(['name' => 'Test']);
17+
18+
$dueTask = $user->addTask([
19+
'name' => 'Due',
20+
'job' => DummyJob::class,
21+
'job_data' => json_encode(['foo' => 'bar']),
22+
'due_date' => now()->subMinute(),
23+
]);
24+
25+
$futureTask = $user->addTask([
26+
'name' => 'Future',
27+
'job' => DummyJob::class,
28+
'due_date' => now()->addHour(),
29+
]);
30+
31+
Artisan::call('tasks:dispatch');
32+
33+
Queue::assertPushed(DummyJob::class, 1);
34+
$this->assertEquals(Task::STATUS_RUNNING, $dueTask->fresh()->status);
35+
$this->assertEquals(Task::STATUS_PENDING, $futureTask->fresh()->status);
36+
}
37+
}

tests/Jobs/DummyJob.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
namespace Michal78\Tasks\Tests\Jobs;
4+
5+
use Illuminate\Bus\Queueable;
6+
use Illuminate\Contracts\Queue\ShouldQueue;
7+
use Illuminate\Foundation\Bus\Dispatchable;
8+
use Illuminate\Queue\InteractsWithQueue;
9+
use Illuminate\Queue\SerializesModels;
10+
11+
class DummyJob implements ShouldQueue
12+
{
13+
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
14+
15+
public $data;
16+
17+
public function __construct($data = null)
18+
{
19+
$this->data = $data;
20+
}
21+
22+
public function handle(): void
23+
{
24+
// no-op
25+
}
26+
}

0 commit comments

Comments
 (0)