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

[11.x] Add environmentSchedule method to the Scheduling Event #51126

Closed
wants to merge 1 commit into from

Conversation

modernben
Copy link

This PR introduces the ability to set different schedules for a job based on the environment.

Scenario:
You have a site in production and a dev site where you are making calls to a 3rd-party provider. This provider may have API quotas for how often it can be hit so you set different schedules for production and staging.

Current Solution:
Currently, you can use the ->environments() method to specify which environment to run it in. This works great but also leads to duplicate code.

$schedule->job(ProcessInvoices::class)
    ->name('process_invoices')
    ->onOneServer()
    ->runInBackground()
    ->environments(['production'])
    ->daily();

$schedule->job(ProcessInvoices::class)
    ->name('process_invoices')
    ->onOneServer()
    ->runInBackground()
    ->environments(['staging', 'development'])
    ->weekly();

The Solution:
I'd like to introduce the environmentSchedule method to simplify the scheduling

$schedule->job(ProcessInvoices::class)
    ->name('process_invoices')
    ->onOneServer()
    ->runInBackground()
    ->environmentSchedule(function(Event $schedule, string $environment) {
        return match($environment) {
            'production' => $schedule->daily(),
            default => $schedule->weekly(),
        };
    });

This reduces code duplication by simply accounting for both schedules in the same definition. I am passing in the current environment to the callback but users could use whatever they like.

@taylorotwell
Copy link
Member

I would just add Tappable trait to the scheduling event then you could tap the schedule and do any conditional checks you want, not just environment.

@modernben modernben deleted the patch-3 branch April 19, 2024 15:23
@modernben
Copy link
Author

Yep I added a macro on my project. Thanks for the review.

Event::macro('environmentSchedule', function (Closure $callback) {
    // Retrieve the current application environment
    $environment = config('app.env');

    // Execute the closure with the schedule instance and environment
    return $callback($this, $environment);
});

@taylorotwell
Copy link
Member

I just pushed Tappable.

@modernben
Copy link
Author

Thanks! Can you provide a quick example of what you mean?

I think you're talking about wrapping it in tap()?

@joshmanders
Copy link
Contributor

Thanks! Can you provide a quick example of what you mean?

I think you're talking about wrapping it in tap()?

I'm assuming like this

$schedule->job(ProcessInvoices::class)
    ->name('process_invoices')
    ->onOneServer()
    ->runInBackground()
    ->tap(function(Event $schedule) {
        $environment = config('app.env');

        return match($environment) {
            'production' => $schedule->daily(),
            default => $schedule->weekly(),
        };
    });

@modernben
Copy link
Author

Awesome. Thank you @joshmanders !

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

Successfully merging this pull request may close these issues.

None yet

3 participants