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

RunOnceAtStart sometimes it doesn't work. #353

Open
Kerwin1202 opened this issue Nov 27, 2023 · 10 comments
Open

RunOnceAtStart sometimes it doesn't work. #353

Kerwin1202 opened this issue Nov 27, 2023 · 10 comments
Assignees

Comments

@Kerwin1202
Copy link

Kerwin1202 commented Nov 27, 2023

Describe the bug

    scheduler.Schedule<Service>()
        .Cron("30 */2 * * *")
        .RunOnceAtStart()
        .Zoned(TimeZoneInfo.Local);

    scheduler.ScheduleAsync(async () =>
        {
             Console.WriteLine("Start refresh data");
           // ... other code 
        })
        .DailyAtHour(9)
        .RunOnceAtStart()
        .Zoned(TimeZoneInfo.Local);
public class Service : IInvocable
{
   ......  other code
    public async Task Invoke()
    {
        _logger. Information($"Start login {_config. UserName}");
        await Login();
    }
   ......  other code
}

Affected Coravel Feature
Scheduling

Expected behaviour
Output content immediately when starting the program. ( "Start login xxx" and "Start refresh data") , but when I run it many times, sometimes it does not output content, and the console does not report any error message.

run windows service.
.net core 7.0
coravel : 5.0.2.0

@arteny
Copy link

arteny commented Feb 7, 2024

Not works for me in .net 8 with ScheduleAsync as well

@chris-rp
Copy link

This is still an issue in
.net8, coravel 5.0.4

Anything new on this issue?

@jamesmh
Copy link
Owner

jamesmh commented Sep 26, 2024

No news on this yet. Will look to investigate soon. Not sure what's going on at first glance. Unless someone else has any idea by looking at the source?

@jamesmh jamesmh self-assigned this Jan 17, 2025
@jamesmh
Copy link
Owner

jamesmh commented Jan 17, 2025

Curious for those who reported this: what kind of machine was this on? A small container? Local machine with many threads?

I have an idea of a potential race condition causing this, but can't reproduce at all ATM.

@jamesmh
Copy link
Owner

jamesmh commented Jan 17, 2025

Was able to reproduce via unit testing the suspect concurrency scenario. Fixed in 6.0.2!

@jamesmh jamesmh closed this as completed Jan 17, 2025
@jamesmh
Copy link
Owner

jamesmh commented Jan 17, 2025

Please re-open if you find the issue persists. It's still possible that the issue has some other causes related to the .NET lifecycle 🤷.

@arteny
Copy link

arteny commented Jan 17, 2025

Still not works on my side with 6.0.2
from this breakpoint:

		Scheduler.ScheduleAsync(async () => { await updateExposure(); })
			.EveryFifteenSeconds()
			.RunOnceAtStart();

desitnation method is called after several seconds

@jamesmh jamesmh reopened this Jan 17, 2025
@jamesmh
Copy link
Owner

jamesmh commented Jan 17, 2025

🥲 Thanks @arteny - I'll have to take another gander at this.

@jamesmh
Copy link
Owner

jamesmh commented Jan 20, 2025

@arteny It's possible that there's another task causing this one to be delayed. If you put this task first in the list of all schedule tasks, does it improve things?

@jamesmh
Copy link
Owner

jamesmh commented Jan 20, 2025

For example:

                scheduler.Schedule(() => Thread.Sleep(10000)).EverySecond();
                scheduler.ScheduleAsync(async () => { await Task.Delay(1); Console.WriteLine("SHOULD GO FIRST"); })
                    .Hourly()
                    .RunOnceAtStart();

Because the first task is not returning a Task (e.g. not await/async) it hogs the thread. So the second task won't run until the first one completes (after 10 seconds....). So it "looks" like the second one doesn't run immediately upon start up, but it IS triggered properly. It's just that another task is not letting go of the thread.

That's what schedule workers are for. So this works:

                scheduler.Schedule(() => Thread.Sleep(10000)).EverySecond();
                scheduler.OnWorker("TEST");
                scheduler.ScheduleAsync(async () => { await Task.Delay(1); Console.WriteLine("SHOULD GO FIRST"); })
                    .Hourly()
                    .RunOnceAtStart();

This code will put the second scheduled task on it's own thread, so it's not blocked / waiting on the first task to complete.

It might be the case that everyone or some of you guys/gals are experiencing this issue. Otherwise, I cannot reproduce this issue at all, other than this approach.

So what I recommend for everyone having this issue is to either list these "run once at start" tasks first in your configuration (so they run first at run time) or put them on a dedicated worker.

Let me know this works for anyone or doesn't! Thanks!

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

No branches or pull requests

4 participants