Skip to content

Instantly share code, notes, and snippets.

@4lun
Last active May 16, 2024 16:40
Show Gist options
  • Save 4lun/c4d96160f13c3f20b6bbc551c4193ca2 to your computer and use it in GitHub Desktop.
Save 4lun/c4d96160f13c3f20b6bbc551c4193ca2 to your computer and use it in GitHub Desktop.
Laravel faux scheduler (i.e. faux cron), if running in an environment that lacks a decent scheduler/cron option (e.g. DigitalOcean App Platform). Primarily designed to be triggered via uptime checker, e.g. can hook into health check endpoint `Event::listen(function (DiagnosingHealth $event) { FauxScheduler::dispatch(); });`
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('system_meta', function (Blueprint $table) {
$table->string('key')->primary();
$table->string('value');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('system_meta');
}
};
<?php
namespace App\Jobs;
use App\Models\SystemMeta;
use Artisan;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Log;
class FauxScheduler implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
const KEY_CHECK = 'FauxScheduler::LAST_CHECK';
const KEY_RUN = 'FauxScheduler::LAST_RUN';
public function handle(): void
{
$now = now();
$prev = new Carbon(SystemMeta::get(self::KEY_RUN, now()->subDays(7)));
SystemMeta::set(self::KEY_CHECK, $now);
if ($prev->diffInMinutes($now) < 1) {
return;
}
try {
Artisan::call('schedule:run');
SystemMeta::set(self::KEY_RUN, $now);
} catch (\Exception $e) {
Log::error('Error running FauxScheduler', ['exception' => $e]);
}
}
}
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class SystemMeta extends Model
{
use HasFactory;
protected $primaryKey = 'key';
protected $table = 'system_meta';
protected $fillable = ['key', 'value'];
public static function get($key, $default = null)
{
$meta = self::where('key', $key)->first();
return $meta ? $meta->value : $default;
}
public static function set($key, $value)
{
$meta = self::firstOrNew(['key' => $key]);
$meta->value = $value;
$meta->save();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment