w3c / requestidlecallback

Cooperative Scheduling of Background Tasks
https://w3c.github.io/requestidlecallback/
Other
50 stars 19 forks source link

Collapse deadline and isExeeded into single function? #11

Closed igrigorik closed 9 years ago

igrigorik commented 9 years ago
interface IdleDeadline {
    readonly    attribute DOMHighResTimeStamp deadline;
    readonly    attribute boolean             didTimeout;

    boolean isExceeded();
};

Would it make sense to simplify the above interface by collapsing deadline and isExceeded into a single function? For example, timeLeft(), or some such, that reports the amount of time left in the idle period? The developer API would then be...

function doSomeIdleWork(deadline) {
 while (deadline.timeLeft() > 0) {
  // ... do work here ...
 }
 window.requestIdleCallback(doSomeIdleWork);
}
window.requestIdleCallback(doSomeIdleWork);

Also, on the implementation side for the reported estimate, we probably need to add some quantization logic for idle periods... E.g. multiples of ~2ms for <16ms, and millisecond granularity for >16ms.

/cc @esprehn @ojanvafai

ojanvafai commented 9 years ago

The code example is backwards I think. It should be: while (deadline.timeLeft() > 0) { ... }

In addition to simplifying the API, it would make the natural path for using this API avoid doing an expensive performance.now() call in the common case.

igrigorik commented 9 years ago

@ojanvafai woops, good catch. Fixed the example.

rmcilroy commented 9 years ago

The reason we originally went for an absolute deadline rather than a relative "time remaining" was because the OS might deschedule the thread, making a remaining time invalid. However now that we are passing a deadline object rather than just a raw DOMHighResTimeStamp this is no longer really a concern (since timeLeft() can update appropriately when called).

If there are no use-cases for having the absolute deadline rather than just the "time left" then maybe this would be a reasonable simplification. It wouldn't actually avoid the performance.now() call however, since the timeLeft() call would have to internally do the same thing as performance.now() would (although it would possibly avoid one extra call across of the binding layer). Also, performance.now() isn't super expensive (although it seems more expensive on Chrome than it needs to be - see http://crbug.com/502205)

igrigorik commented 9 years ago

If there are no use-cases for having the absolute deadline rather than just the "time left" then maybe this would be a reasonable simplification.

Thinking out loud.. If, as a developer, I'm scheduling a one-shot work item based on provided estimate (e.g. "ok looks like I have X ms, my work should take less then that, run it"), then in the descheduling case I'm going to overshoot my quota regardless of how we report it. If, on the other hand, I'm processing smaller work chunks (e.g. running in a loop), then the timeLeft approach is better because it allows the system to adjust the reported value if we get descheduled.

Seems like timeLeft is a better choice?

rmcilroy commented 9 years ago

I'm processing smaller work chunks (e.g. running in a loop), then the timeLeft approach is better because it allows the system to adjust the reported value if we get descheduled.

Either the isExceeded() or performance.now() > deadline would also allow the system to adjust the reported amount of time remaining (via the fact that performance.now() would increase while we are descheduled), so I don't think timeLeft is better for this reason, but it seems like a reasonable simplification to the API.

rmcilroy commented 9 years ago

Created a pull request with this spec change in #12. Decided to go for timeRemaining() instead of timeLeft(). Please take a look, thanks.

igrigorik commented 9 years ago

Thanks Ross, let's continue in #12. Closing this.