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

Same priority tasks get run after scheduler.yield? #86

Closed
sefeng211 opened this issue Apr 8, 2024 · 1 comment
Closed

Same priority tasks get run after scheduler.yield? #86

sefeng211 opened this issue Apr 8, 2024 · 1 comment

Comments

@sefeng211
Copy link

<script>
  async function run() {
    scheduler.postTask(() => {
      console.log("task 1\n");
    });
    scheduler.postTask(() => {
      console.log("task 2\n");
    });

    await scheduler.yield();
    console.log("yield 1 done\n");

    await scheduler.yield();
    console.log("yield 2 done\n");
  }

  run();
</script>

The above script prints yield 1 done, yield 2 done, task 1, task 2 in Chrome. This feels counter-intuitive. They all have the same priorities as user_visible, and postTask scheduled tasks earlier. Shouldn't it be task 1, task 2, yield 1 done, yield 2 done ?

@shaseley
Copy link
Collaborator

shaseley commented Apr 8, 2024

That's WAI. The basic idea is that yield() tasks are continuations, and continuations should be given a slightly higher effective priority than tasks with the same priority. (See also the explainer intro for motivation for that and the section on continuation scheduling behavior.)

This behavior is largely to mitigate the impact of yielding which developers cite as a reason for not yielding — it can take too long to regain control of the thread because all other queued tasks run. And not yielding in long tasks is very bad for responsiveness/INP. yieldToHigherPriorityWork() might be a better name, but it's terribly verbose (see explainer section on naming).

The way I think of it is:

  • The task entry point has a priority (postTask(), setTimeout(), etc.)
  • The continuation is a logical extension of that task and retains that priority [1], but is scheduled differently (effective priority within the scheduler) since the task already previously started (and it's less penalty for doing a thing that benefits users!)

[1] By default, anyways. There was an open question about what should happen if no arguments are passed, and we're leaning towards "inherit the current priority" (see this section). That's typically what you'd want: if you're in a background task, for example, continuations are prioritized over new background tasks but not over anything with higher priority, etc. But there may be cases where devs want to provide an explicit (continuation) priority, so the API takes similar options as postTask().

It's still a WIP and the event loop integration still needs to be resolved, but I just pushed a draft spec PR in case you're interested in seeing the details of this.

@shaseley shaseley closed this as completed Aug 9, 2024
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

2 participants