From 6b688f72e08a2ebf5b9c2b64f8dcd8b309b4733d Mon Sep 17 00:00:00 2001 From: Daniel Stock Date: Sun, 7 Dec 2025 12:55:33 +0100 Subject: [PATCH] [Fix] Internal cron scheduler blocking view responses Internal cron is now triggered by an axios request from the frontend so it can truly run in a separate request. Fixes #167 --- app/Console/Commands/CaldavSyncCommand.php | 2 + app/Http/Middleware/HandleInertiaRequests.php | 7 +- app/Listeners/ScheduleListener.php | 48 --------- app/Providers/EventServiceProvider.php | 18 +--- database/seeders/SettingsTableSeeder.php | 2 +- resources/js/layouts/AppLayout.vue | 24 ++++- resources/js/layouts/AuthLayout.vue | 24 +++++ routes/web.php | 102 ++++++++++-------- 8 files changed, 108 insertions(+), 119 deletions(-) delete mode 100644 app/Listeners/ScheduleListener.php diff --git a/app/Console/Commands/CaldavSyncCommand.php b/app/Console/Commands/CaldavSyncCommand.php index 04b1823..8eb71c0 100644 --- a/app/Console/Commands/CaldavSyncCommand.php +++ b/app/Console/Commands/CaldavSyncCommand.php @@ -18,6 +18,7 @@ public function handle(CaldavService $service) // only run every 5 minutes although the task is called every minute $cacheKey = 'caldav_sync_last_run'; if (\Illuminate\Support\Facades\Cache::has($cacheKey)) { + Log::info('CalDAV sync Throttled'); return 0; } Cache::put($cacheKey, true, 300); @@ -33,6 +34,7 @@ public function handle(CaldavService $service) $count++; } + Log::info("Synced " . count($todos) . " todos."); $this->info("Synced " . count($todos) . " todos."); return 0; } diff --git a/app/Http/Middleware/HandleInertiaRequests.php b/app/Http/Middleware/HandleInertiaRequests.php index 0b51b8b..aee2b99 100644 --- a/app/Http/Middleware/HandleInertiaRequests.php +++ b/app/Http/Middleware/HandleInertiaRequests.php @@ -2,7 +2,7 @@ namespace App\Http\Middleware; -use Illuminate\Foundation\Inspiring; +use App\Models\Setting; use Illuminate\Http\Request; use Inertia\Middleware; @@ -39,10 +39,9 @@ public function share(Request $request): array return [ ...parent::share($request), 'name' => config('app.name'), - 'auth' => [ - 'user' => $request->user(), - ], + 'auth' => ['user' => $request->user(),], 'sidebarOpen' => ! $request->hasCookie('sidebar_state') || $request->cookie('sidebar_state') === 'true', + 'cron' => Setting::get('app.cron_method') === 'request' ]; } } diff --git a/app/Listeners/ScheduleListener.php b/app/Listeners/ScheduleListener.php deleted file mode 100644 index 9759219..0000000 --- a/app/Listeners/ScheduleListener.php +++ /dev/null @@ -1,48 +0,0 @@ -value('value') ?? 'internal'; - if ($method !== 'internal') { - return; - } - - // throttle key: run at most once every 55 seconds - $cacheKey = 'caramel_scheduler_last_run'; - $ttlSeconds = 55; - - if (Cache::has($cacheKey)) { - return; - } - - // mark as run - Cache::put($cacheKey, true, $ttlSeconds); - - try { - Log::info('Triggering scheduler via ScheduleListener'); - Artisan::call('schedule:run'); - } catch (\Throwable $e) { - Log::error('Error running scheduler: ' . $e->getMessage()); - } - } -} diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index 0df9e53..8246185 100644 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -4,11 +4,6 @@ use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider; use Illuminate\Support\Facades\Schedule; -use Illuminate\Support\Facades\Event; -use Illuminate\Support\Facades\Schema; -use Illuminate\Routing\Events\RouteMatched; -use App\Models\Setting; -use App\Listeners\ScheduleListener; use App\Jobs\CheckInvoiceDueDatesJob; class EventServiceProvider extends ServiceProvider @@ -22,16 +17,9 @@ public function boot(): void { parent::boot(); - if (Schema::hasTable('settings')) { - $method = Setting::where('key', 'app.schedule_method')->value('value') ?? 'internal'; - if ($method === 'internal') { - Event::listen(RouteMatched::class, [ScheduleListener::class, 'handle']); - } - } - - // TODO: read where to put these or ask in the forums - // it seems to work here, but where is the apropriate place? - // Kernel::schedule did not work + // // TODO: read where to put these or ask in the forums + // // it seems to work here, but where is the apropriate place? + // // Kernel::schedule did not work Schedule::command('caldav:sync') ->everyMinute() ->withoutOverlapping(); diff --git a/database/seeders/SettingsTableSeeder.php b/database/seeders/SettingsTableSeeder.php index 7c4a1ef..bbe0a91 100644 --- a/database/seeders/SettingsTableSeeder.php +++ b/database/seeders/SettingsTableSeeder.php @@ -11,6 +11,6 @@ public function run(): void { Setting::updateOrCreate(['key' => 'invoices.number_format'], ['value' => 'RE-{number}']); Setting::updateOrCreate(['key' => 'invoices.number_start'], ['value' => '1']); - Setting::updateOrCreate(['key' => 'app.schedule_method'], ['value' => '1']); + Setting::updateOrCreate(['key' => 'app.cron_method'], ['value' => 'request']); } } \ No newline at end of file diff --git a/resources/js/layouts/AppLayout.vue b/resources/js/layouts/AppLayout.vue index 5b76af4..0dd476d 100644 --- a/resources/js/layouts/AppLayout.vue +++ b/resources/js/layouts/AppLayout.vue @@ -1,5 +1,5 @@