Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The events method of the Schedule class yields different results when running as HTTP request and on Console Command #51369

Closed
abishekrsrikaanth opened this issue May 10, 2024 · 7 comments

Comments

@abishekrsrikaanth
Copy link

abishekrsrikaanth commented May 10, 2024

Laravel Version

11.7.0

PHP Version

8.3.6

Database Driver & Version

No response

Description

When running the below code as HTTP Request and on then as a Console Command or tinker yields 2 different results.

use Illuminate\Support\Str;
use Illuminate\Console\Scheduling\Schedule;

$schedule = app()->make(Schedule::class);
$scheduledJobs = collect($schedule->events());
$scheduledJobs->count();
dd($scheduledJobs);

Steps To Reproduce

Please copy and paste the below code on a separate route on web.php and then create a new console command and use the same code. Both of them will return

use Illuminate\Support\Str;
use Illuminate\Console\Scheduling\Schedule;

$schedule = app()->make(Schedule::class);
$scheduledJobs = collect($schedule->events());
$scheduledJobs->count();
dd($scheduledJobs);

This used to work with Laravel 10 but not with Laravel 11 anymore.

@driesvints
Copy link
Member

Heya, thanks for reporting.

We'll need more info and/or code to debug this further. Can you please create a repository with the command below, commit the code that reproduces the issue as one separate commit on the main/master branch and share the repository here? Please make sure that you have the latest version of the Laravel installer in order to run this command. Please also make sure you have both Git & the GitHub CLI tool properly set up.

laravel new bug-report --github="--public"

Please do not amend and create a separate commit with your custom changes. After you've posted the repository, we'll try to reproduce the issue.

Thanks!

@abishekrsrikaanth
Copy link
Author

Here is the repository that can help reproduce this issue https://github.com/abishekrsrikaanth/bug-report

The idea is to get the same results of the command php artisan schedule:list when used in console as well as Http Request.

I have created a Console Command to List all the Scheduled Jobs on the app. You can run

php artisan app:list-scheduled-items

Here is the output.
CleanShot 2024-05-11 at 12 14 08

I have also added the same code to the root route of the app. Once you run php artisan serve and visit the root route, you should see the below result. If you notice, the $scheduledJobs collection is empty.

CleanShot 2024-05-11 at 12 13 49

Please let me know if you need any further details regarding the same.

@driesvints
Copy link
Member

@mbabker instead of downvoting me, you could have helped @abishekrsrikaanth and me by searching what causes this.

@abishekrsrikaanth thanks, that helped me to reproduce is. I dived deep into the console component but couldn't immediately figure out what's causing the scheduled events not to appear in a web context. I'm almost certain there's a good reason but it's eluding me at the moment. Would appreciate any help in figuring out what the reason is.

Copy link

Thank you for reporting this issue!

As Laravel is an open source project, we rely on the community to help us diagnose and fix issues as it is not possible to research and fix every issue reported to us via GitHub.

If possible, please make a pull request fixing the issue you have described, along with corresponding tests. All pull requests are promptly reviewed by the Laravel team.

Thank you!

@aldobarr
Copy link
Contributor

aldobarr commented May 18, 2024

@abishekrsrikaanth When you say this is a regression from laravel 10, do you mean because your scheduled commands in the src/app/Console/Kernel.php schedule method would appear when pulling your scheduled events via the web route?

Because I can reproduce the same behavior in Laravel 10 by scheduling jobs in the console route. They will not be visible outside of when Laravel is running in console. On the other hand, whether in Laravel 10 or 11 if I create a console Kernel like has been the norm for pretty much ever then your expected behavior works. For example, if you replace your bootstrap/app.php file in your bug report repository with:

<?php

use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;

$app = Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        web: __DIR__.'/../routes/web.php',
        commands: __DIR__.'/../routes/console.php',
        health: '/up',
    )
    ->withMiddleware(function (Middleware $middleware) {
        //
    })
    ->withExceptions(function (Exceptions $exceptions) {
        //
    })
    ->create();

$app->singleton(
    Illuminate\Contracts\Console\Kernel::class,
    App\Console\Kernel::class
);

return $app;

and then add the App\Console\Kernel class with this:

<?php

namespace App\Console;

use App\Console\Commands\ScheduleCommand1Command;
use App\Console\Commands\ScheduleCommand2Command;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;

class Kernel extends ConsoleKernel
{
    /**
     * The Artisan commands provided by your application.
     *
     * @var array
     */
    protected $commands = [
        //
    ];

    /**
     * Define the application's command schedule.
     *
     * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
     * @return void
     */
    protected function schedule(Schedule $schedule)
    {
        $schedule->command(ScheduleCommand1Command::class)->hourly();
        $schedule->command(ScheduleCommand2Command::class)->hourly();
    }

    /**
     * Register the commands for the application.
     *
     * @return void
     */
    protected function commands()
    {
        $this->load(__DIR__ . '/Commands');

        require base_path('routes/console.php');
    }
}

You'll see the expected behavior in your bug report project. Quite frankly, I have no idea why Laravel has decided to move away from defining commands and schedules this way and more towards the console.php route file. It's very strange and I've personally never really liked the idea of that file and have never used it. I pretty much don't ever intend to use it unless I'm forced to.

@iBotPeaches
Copy link
Contributor

This is the workaround I've been using to use events in an HTTP sense after I noticed this same behavior from L10 -> L11.

        // We must load the Console Kernel, as it contains information about our Scheduled Jobs
        // Then we hydrate our Schedule class, which will parse out the cron information.
        // Laravel 11 optimized this, so we explicitly have to bootstrap the class.
        // as we are not running this in the context of a console command.
        $app = app()->make(Illuminate\Contracts\Console\Kernel::class);
        $app->bootstrap();
        $schedule = app(Illuminate\Console\Scheduling\Schedule::class);

        collect($schedule->events())->each(function (Event $event) {
          //
        });

@driesvints
Copy link
Member

Thanks everyone. I'm gonna close this now because I don't see a huge issue and there's a simple workaround. Right now we don't have plans to take action here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants