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

scheduler.postTask() API #338

Closed
3 of 5 tasks
spanicker opened this issue Jan 24, 2019 · 36 comments
Closed
3 of 5 tasks

scheduler.postTask() API #338

spanicker opened this issue Jan 24, 2019 · 36 comments
Assignees
Labels
Progress: review complete Resolution: satisfied The TAG is satisfied with this design Review type: CG early review An early review of general direction from a Community Group

Comments

@spanicker
Copy link

spanicker commented Jan 24, 2019

こんにちはTAG!

I'm requesting a TAG review of:

Further details (optional):

You should also know that...
This is a very early proposal and we are seeking broad feedback.

We'd prefer the TAG provide feedback as (please select one):

  • open issues in our Github repo for each point of feedback
  • open a single issue in our Github repo for the entire review
  • leave review feedback as a comment in this issue and @-notify [github usernames]
@kenchris kenchris self-assigned this Jan 24, 2019
@dbaron dbaron self-assigned this Jan 24, 2019
@dbaron
Copy link
Member

dbaron commented Feb 4, 2019

After a first read-through, this seems like useful stuff.

Some of this (particularly the comment in the explainer about misuse of Promise.prototype.then for things that shouldn't block the browser's event loop) got me thinking a little about the tie between syntax and the various types of timing options on the platform. As a result of adding new types of timing (e.g., microtasks) for things where that timing seemed like the right thing for the "canonical" use of a new API, we now have a set of syntaxes where people might choose between say, Promises and setTimeout based on API familiarity or usability, even when they have non-obvious differences in semantics that are important. It makes me wonder:

  • if we should have a more flexible relationship between the syntaxes and the timings, e.g., better ability to choose the timings when using a given syntax (at least for some of the important ones)
  • whether the builtin API for task queues proposed here makes that problem better or worse -- which I suspect may depend on how easy/hard it is to hook all the existing sorts of delayed work we have in the platform up to these task queues (in lieu of their current defaults).

@slightlyoff
Copy link
Member

The link to the filled-out Self-Review Questionnare on Security and Privacy doesn't seem to resolve. Can someone post it here?

@cynthia
Copy link
Member

cynthia commented Feb 5, 2019

Taken up during the Tokyo F2F. @hober @travisleithead @kenchris @dbaron @cynthia discussed this at length.

Interesting problem! Thanks for bringing this to our attention. This is absolutely worth exploring.

That said, we do have concerns about the limited audience that will immediately benefit from this.

Additionally, we are a bit curious what is supposed to go on this task queue, and how are they expected to behave.

We think a solution in this space will need to account for how legacy scheduling APIs interact as not all authors will be expected to switch to the new model for scheduling (as long as the old model is still around).

We'd love to see this advance further, and would like to see some strawman proposals when you have any.

@cynthia cynthia removed the extra time label Feb 5, 2019
@spanicker
Copy link
Author

spanicker commented Feb 12, 2019

people might choose between say, Promises and setTimeout based on API familiarity or usability, even when they have non-obvious differences in semantics that are important.
Yes that is right. The introduction of async / await has compounded this by steering developers towards microtask timing, when they are really making a syntax choice without considering the semantics.

  • if we should have a more flexible relationship between the syntaxes and the timings, e.g., better ability to choose the timings when using a given syntax (at least for some of the important ones)

Would love to hear your ideas.
I'd floated the idea of additional syntax for promise, but we also really should address async / await.
Example:
Promise.resolve().thenYield(bar);
OR
myPromise
.then(Priority.Default)
.then(value => { ...
});
OR
myPromise
.thenAtPriorityDefault()
etc.

  • whether the builtin API for task queues proposed here makes that problem better or worse -- which I suspect may depend on how easy/hard it is to hook all the existing sorts of delayed work we have in the platform up to these task queues (in lieu of their current defaults).

the builtin API certainly aims to make this better with "semantic priority", however we have to really pick appropriate names here (work-in-progress):
https://github.com/spanicker/main-thread-scheduling#1-immediate-priority
https://github.com/spanicker/main-thread-scheduling#2-render-blocking-priority-render-immediate
etc.

@spanicker
Copy link
Author

spanicker commented Feb 12, 2019

The link to the filled-out Self-Review Questionnare on Security and Privacy doesn't seem to resolve. Can someone post it here?

This is not a specification yet and there will be separate specifications and TAG requests for each API.
Example: https://github.com/WICG/is-input-pending#privacy-and-security

That said, we do have concerns about the limited audience that will immediately benefit from this.

Could you elaborate on the concern of limited audience, why do you think it is limited?
For example if we can get few popular frameworks (eg. React, Vue etc) and widely used apps (Facebook, Maps) to adopt the APIs, that in turn results in relatively wide adoption: both in terms of type of apps and chromium (pagevisit) usecounter etc.

Additionally, we are a bit curious what is supposed to go on this task queue, and how are they expected to behave.

I will link the explainer for this proposal when ready (soon!).

@dbaron dbaron added the Review type: CG early review An early review of general direction from a Community Group label May 21, 2019
@shaseley
Copy link

We've made some progress on the API shape here, and are moving ahead with two APIs—scheduler.postTask() and scheduler.yield(). They are closely related (both part of window.scheduler, and tied together by priority), but are useful on their own and can ship independently.

The explainer has been updated:
Overview
Prioritized post task
Yield and continuation

We also have a design doc which covers both APIs.

@bzbarsky
Copy link

bzbarsky commented Aug 1, 2019

The proposal assumes that everything at a given priority is in fact linearized into a single FIFO queue, and that the set of priorities is the fixed one in the proposal. This is at odds with the way the HTML spec defines independent unordered task sources and with browser ability to reorder those wrt each other, as far as I can tell.

@shaseley
Copy link

@bzbarsky Thanks for raising this concern.

Integrating the proposed prioritized task queues with the existing unprioritized task queues is certainly a challenge and is an open question at this point. It is not our goal to remove the ability for UAs to reorder independent task sources, but there is an open question around how prioritized task queues should fit in.

There are a few questions to consider here:

  1. How should tasks from prioritized task queues be ordered with respect to each other for task queues created by a specific Scheduler?

    This is all about establishing a priority system for the postTask API, which is a primary goal of the API. There are a lot of options here, many of which are discussed here. We could leave this up to browsers to decide, but this comes at the cost of less developer certainty.

  2. How should tasks from all prioritized task queues be ordered with respect to each other, regardless of which Scheduler creates them?

    This is about scoping (1). Should this be global? You bring up a good point that the current spec preserves order across documents that share an event loop, but I worry about things like high priority script on background pages or in off-screen frames, etc. Maybe throttling will suffice here?

  3. How should tasks from prioritized task queues and other task queues be ordered?

    As mentioned earlier, it isn’t our goal to limit the ability of UAs to prioritize the various task sources. And IMO one of the biggest open and most important questions of this API is how existing task sources and rendering integrate with respect to tasks in prioritized task queues. For example, do we guarantee that the highest priority (called immediate for now) is render-blocking? What about high priority with respect to timers, or other methods developers currently use to schedule tasks?

    Providing developers with some minimum guarantees would lead to more predictable behavior, which is a good thing. At the same time, it’s important to provide flexibility to allow browsers to experiment and optimize performance, and in this case, perhaps alleviate concerns around starvation caused by high priority work.

    Our current thinking here is that speccing the priority of certain task sources, specifically those that are alternatives methods of scheduling (setTimeout/setInterval, potentially postMessage) would be very beneficial to both this API and developers. We would evaluate other task sources in response to developer concern/feedback, and if needed, each resulting in a separate spec change proposal.

We’d be happy to hear any further thoughts you have on this.

@dbaron
Copy link
Member

dbaron commented Sep 10, 2019

It feels like the main use case given in the overview for the prioritized post task API is about coordination within a single site -- although this does include third party context in nested browsing contexts.

I agree with @bzbarsky that it's valuable to allow browser flexibility to schedule differently across third-party boundaries; such boundaries are quite opaque to begin with and it feels like heavily constraining the relative priorities between origins could interfere with useful things that browsers could do to help users. Whereas within a single site, where there's already much closer interaction, it feels more like there's value in having things clearly-specified -- as the HTML spec currently does, since there's only a single task source. So specifying these priorities as being something meaningful within a single task source, but not across task sources, feels like a good approach to me.

And given the comments in the explainer it sounds like this is the approach currently being taken.

@kenchris
Copy link

Generally, I think it is great to see work done in this area, but I am also a bit worried that this will make the average developer's life more complicated.

Especially, it might be hard to understand what priority to use (high, low, default) so it is important that frameworks and libraries don't force people to make that decision when not needed. Also, today people use a ton of libraries and all of these might use this API internally and set their own prioritization that might conflict with what I am trying to do. So it needs to be very easy to see what a library is doing and change the priority. If every library ends up creating their own APIs for doing so, it might turn into a mess.

I also find the name "immediate" confusing as it doesn't run immediately, as it runs after microtasks.

Should it be possible to access something like the micro task queue using this API?

@dbaron
Copy link
Member

dbaron commented Sep 10, 2019

Next steps:

  • it would be good to hear responses to the comments above, but also
  • I think we should take a closer (not-during-meeting) look at the explainers and perhaps provide some additional comments

@bzbarsky
Copy link

@dbaron There is not a single task source for a single "site". There are a bunch of different task sources, which per HTML spec are unordered with each other. For example, setTimeout, most DOM-related tasks, user-interaction-triggered tasks, postMessage are all different task sources. There's a bunch of other ones as well; those are just the ones I know off the top of my head.

My comments were explicitly about the single-site situation, not the different-site situation; in the different-site case there are no observable ordering guarantees between the two sites apart from ordering within communication channels like postMessage, so there is no problem there; I hadn't even thought about people reading it that way...

@dbaron
Copy link
Member

dbaron commented Sep 10, 2019

Ah, ok -- I'm curious how much flexibility browsers really have for some of these things -- it feels like some of that might be pretty constrained by web compatibility.

@plinss plinss added this to the 2020-02-10-week milestone Jan 22, 2020
@shaseley
Copy link

shaseley commented Feb 1, 2020

Hi folks, an update on the postTask API proposal:

  1. We've overhauled the API shape to use the controller/signal pattern, and the explainer reflects the change. Thanks @domenic for your comments and help along the way, and to @kenchris as well for raising this here. The new API shape was presented at WebPerfWG in November (minutes here).

  2. The language around how we plan to integrate the priorities has been updated in the explainer as well, reflecting the discussions in this thread.

  3. FYI: we're planning to get this to origin trial very soon, and will be sending the I2E shortly.

@kenchris
Copy link

Hi there

What are your current priorities? postTask? Where can be we (TAG) most helpful.

Maybe it makes sense to have separate issues for each of these APIs so that we better know what to focus on and better can track the progress?

@dbaron
Copy link
Member

dbaron commented Feb 18, 2020

Also worth noting that #415 has some discussion that's probably relevant to isInputPending.

@shaseley
Copy link

Hi there

What are your current priorities? postTask? Where can be we (TAG) most helpful.

Yes, postTask is our current priority, and a TAG review of postTask would be most helpful.

Maybe it makes sense to have separate issues for each of these APIs so that we better know what to focus on and better can track the progress?

Sorry for the confusion, yes separate issues sounds like the right approach. Should we repurpose this for postTask, or file a new issue? Much of the content of this thread is already related to postTask.

@acomminos acomminos mentioned this issue Feb 18, 2020
1 task
@dbaron dbaron changed the title Scheduling APIs scheduler.postTask() API Feb 19, 2020
@kenchris
Copy link

kenchris commented Mar 3, 2020

What happens in this case?

const controller = new TaskController('user-blocking');
scheduler.postTask(doWork, { signal, priority: 'background' });

@shaseley
Copy link

shaseley commented Mar 4, 2020

What happens in this case?

const controller = new TaskController('user-blocking');
scheduler.postTask(doWork, { signal, priority: 'background' });

signal gets downcast to an AbortSignal, allowing the abort component of the signal to be propagated while supporting the ability to spawn different priority subtasks.

A use case we had in mind is if devs want to post independent low priority subtasks that should still be canceled with the parent task. One example of this might be logging or cleanup tasks.

Note: I'm working on a separate explainer/issue to explore implementing TaskSignal this way (as an extension of AbortSignal) vs. having/supporting separable signals (e.g. PrioritySignal), and potentially making TaskSignal a composite. Where I think things get complicated is if/when more signals get added to the platform and how they interact with the various APIs. I'm planning to loop TAG folks and others in on that as well once it's written.

@kenchris
Copy link

kenchris commented Mar 4, 2020

But what priority is it going to get?

@shaseley
Copy link

shaseley commented Mar 4, 2020

Oh sorry, 'background'.

@kenchris
Copy link

kenchris commented Mar 4, 2020

So priority wins over the priority from the TaskController. But I assume that if I change the priority of the TaskController then that wins? Could you add that example and explanation?

@shaseley
Copy link

shaseley commented Mar 4, 2020

Yes, the priority option acts as an override and wins over the priority from the signal, but the priority remains fixed at that priority, meaning controller.setPriority() won't change the priority for that task. In this example, that means the priority of that task will always be background. The invariant here is that specifying a fixed priority, whether or not a signal is provided, will cause that task to always remain at that priority. That's what I meant by the signal is downcast to an AbortSignal if a priority is provided.

This is mentioned in the design doc, but looks like it didn't make it into the explainer; I'll add this information and an example.

There are other options here, e.g. ignoring the priority option, throwing an error. The current approach seemed to enable additional use cases which is why we selected it, but we're open to suggestions/feedback.

@kenchris
Copy link

Clarification looks good but I found a nit

Should be prioritychange as I assume that TaskSignal is an EventTarget (it should be) you can call addEventListener('prioritychange') in addition to .onprioritychange = ...

@cynthia
Copy link
Member

cynthia commented Sep 22, 2020

I think we're pretty happy with the direction this proposal is taking, so we propose to close this for now. If there is a formal spec that needs to be reviewed later on, we'd be happy to revisit this.

@cynthia cynthia added Progress: propose closing we think it should be closed but are waiting on some feedback or consensus and removed Progress: in progress labels Sep 22, 2020
@cynthia cynthia closed this as completed Sep 22, 2020
@cynthia cynthia added Progress: review complete Resolution: satisfied The TAG is satisfied with this design and removed Progress: propose closing we think it should be closed but are waiting on some feedback or consensus labels Sep 22, 2020
@shaseley shaseley mentioned this issue Jun 14, 2021
1 task
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Progress: review complete Resolution: satisfied The TAG is satisfied with this design Review type: CG early review An early review of general direction from a Community Group
Projects
None yet
Development

No branches or pull requests