sanmai/later
Later is a tiny PHP library for scheduling delayed callbacks and lightweight task execution. Queue functions to run after a given time, manage timers, and build simple background jobs without a full framework. Useful for CLI daemons and event loops.
Architecture fit:
$deferred->method()) improves developer ergonomics and IDE autocompletion.after_response() hacks.Integration feasibility:
after_response(), register_shutdown_function).app()->make().Deferred interface and iterable support.Technical risk:
later()->afterResponse() wrapper).yield throws). Requires wrapper try-catch blocks.get() is called on a already-executed generator.Key questions:
after_response().sleep() or ReactPHP for async.throttle middleware or rate-limiting package.Stack fit:
artisan migrate --force with deferred cleanup).later()->throttle() for external API calls).after_response() or register_shutdown_function.AppServiceProvider:
$this->app->singleton(Deferred::class, fn() => new Later\Deferred());
// config/app.php
'aliases' => [
'Later' => Later\Facades\Later::class,
];
Migration path:
sleep() delays with later()->delay().// Before
sleep(5);
$this->processBatch();
// After
later()->delay(fn() => $this->processBatch(), 5);
trait UsesDeferredTasks {
protected function afterResponseDeferred(callable $task) {
later()->afterResponse($task);
}
}
public function store(Request $request) {
$this->afterResponseDeferred(fn() => $this->logAnalytics($request));
}
Deferred interface for unit tests:
$mock = $this->createMock(Deferred::class);
$mock->method('get')->willReturn($expectedResult);
$this->app->afterResponse(function () {
later()->delay(fn() => $this->assertTrue(false)); // Should not run
});
Compatibility:
laravel-queue, spatie/laravel-activitylog).$this in closures) to prevent memory leaks.Sequencing:
afterResponseDeferred).Maintenance:
later()->delay(
fn() => $this->log->info('Task executed', ['task' => 'example']),
5
);
Support:
get() on failed generators return undefined behavior.$deferred = later(fn() => $this->riskyOperation());
try {
$result = $deferred->get();
} catch (Throwable $e) {
$this->log->error('Deferred task failed', ['error' => $e]);
$result = $deferred->get(); // Retry (if idempotent)
}
now() for known results to avoid generator overhead in tests.Scaling:
How can I help you explore Laravel packages today?