make it possible to manually cancel preceding pipeline stages
dherman opened this issue · 7 comments
When .provide()
gives a result for a later step than the pipeline is currently at, we fulfill the earlier promise with undefined
. This seems like a good candidate for cancellation, assuming JS promise cancellation gets worked out in time for us to adopt it.
Update:
We shouldn't automatically cancel preceding stages, but we should make it possible to get access to all preceding stages so that code can manually cancel them. Today they'd have to come up with their own protocol for canceling (like .resolve(undefined)
or .reject(CANCELED)
) but once promises have a cancellation API we should expose that for pipeline stages.
With PR #97 we now have the ability to resolve/reject the current stage but not preceding stages. Ideally, we should expose an API that hands out all preceding stages to make it plausible more future-proof for this standard to acquire additional stages. So maybe we should only expose access to an entry's stages with something like:
// ensures we get the preceding stages before resolving
let { preceding, stage } = entry.stagesUpTo('translate');
// have to resolve this before canceling the preceding stages
stage.resolve(v);
// now we can cancel the preceding stages
preceding.forEach(stage => stage.reject(CANCELED));
But that API is super awkward. If we abandon the future-proofing constraint, we can make something less goofy, but then we ought to convince ourselves we don't need to (or can't) future-proof for additional pipeline stages.
Shouldn't the earlier promise resolive with the result of provide()?
Same for install.
Shouldn't the earlier promise resolive with the result of provide()?
No, because the value passed to .provide()
is the result of a different step.
I'm not sure I follow. I thought we were talking about this scenario:
var origPromise = loader.import("foo");
setTimeout(function(){
// origPromise is on step "fetch"
loader.provide("foo", "translate", "export var a = 1;");
});
If the original import is on step "fetch" when the provide()
is called then origPromise
should be resolved with the result of provide.
Do you disagree here?
Do you disagree here?
Oh, no, that's not what this issue is referring to. (Although the result of origPromise
won't be the actual string "export var a = 1;" but that string will continue through the pipeline to parse, link, and instantiate the module with that source.)
This issue is referring to the promise associated with the fetch step. If we were in the middle of fetching and that promise hasn't completed, and meanwhile someone calls .provide
, we're basically pre-empting the fetch. So we should really inform the fetch that it's not needed anymore.
Does that make more sense?
That makes sense, you are pre-empting the fetch but not pre-empting the entire import() promise. The import() should be resolved with the instantiated module provided by provide().
In the old spec this did not work correct. I've mentioned this previous here: #48
This effectively make define/set (the old provide/install) of little use.