Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,24 @@ $user->tasks()->completed()->get();

// Get all tasks that are completed and have a due date in the future
$user->tasks()->completed()->future()->get();

// Schedule a job for a task
$user->addTask([
'name' => 'Cleanup',
'job' => \App\Jobs\CleanupJob::class,
'job_data' => json_encode(['force' => true]),
'due_date' => now()->addMinutes(10),
]);
```

Run the dispatcher command manually if needed:

```bash
php artisan tasks:dispatch
```

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


### Testing (Not implemented yet)

Expand Down
34 changes: 34 additions & 0 deletions src/Console/Commands/DispatchDueTasksCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

namespace Michal78\Tasks\Console\Commands;

use Illuminate\Console\Command;
use Michal78\Tasks\Models\Task;
use Illuminate\Support\Facades\Bus;

class DispatchDueTasksCommand extends Command
{
protected $signature = 'tasks:dispatch';
protected $description = 'Dispatch all due tasks';

public function handle(): int
{
$tasks = Task::where('status', Task::STATUS_PENDING)
->whereNotNull('job')
->whereNotNull('due_date')
->where('due_date', '<=', now())
->get();

foreach ($tasks as $task) {
$job = new $task->job($task->job_data);
Bus::dispatch($job);

$task->status = Task::STATUS_RUNNING;
$task->save();
}

$this->info($tasks->count() . ' tasks dispatched.');

return Command::SUCCESS;
}
}
20 changes: 13 additions & 7 deletions src/TasksServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

namespace Michal78\Tasks;

use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Support\ServiceProvider;
use Michal78\Tasks\Console\Commands\DispatchDueTasksCommand;

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

// Publishing the translation files.
/*$this->publishes([
__DIR__.'/../resources/lang' => resource_path('lang/vendor/laravel-tasks'),
], 'lang');*/

// Registering package commands.
// $this->commands([]);
// Register package command
$this->commands([
DispatchDueTasksCommand::class,
]);

if (config('laravel-tasks.auto_schedule')) {
$this->app->booted(function () {
$schedule = $this->app->make(Schedule::class);
$schedule->command('tasks:dispatch')->everyMinute();
});
}
}
}

Expand Down
37 changes: 37 additions & 0 deletions tests/DispatchDueTasksCommandTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

namespace Michal78\Tasks\Tests;

use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Queue;
use Michal78\Tasks\Models\Task;
use Michal78\Tasks\Tests\Jobs\DummyJob;

class DispatchDueTasksCommandTest extends TestCase
{
public function test_command_dispatches_due_tasks()
{
Queue::fake();

$user = User::create(['name' => 'Test']);

$dueTask = $user->addTask([
'name' => 'Due',
'job' => DummyJob::class,
'job_data' => json_encode(['foo' => 'bar']),
'due_date' => now()->subMinute(),
]);

$futureTask = $user->addTask([
'name' => 'Future',
'job' => DummyJob::class,
'due_date' => now()->addHour(),
]);

Artisan::call('tasks:dispatch');

Queue::assertPushed(DummyJob::class, 1);
$this->assertEquals(Task::STATUS_RUNNING, $dueTask->fresh()->status);
$this->assertEquals(Task::STATUS_PENDING, $futureTask->fresh()->status);
}
}
26 changes: 26 additions & 0 deletions tests/Jobs/DummyJob.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

namespace Michal78\Tasks\Tests\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;

class DummyJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

public $data;

public function __construct($data = null)
{
$this->data = $data;
}

public function handle(): void
{
// no-op
}
}
Loading