-
Notifications
You must be signed in to change notification settings - Fork 3.5k
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
Replace when.js with native promises #10149
Conversation
Thanks for the pull request @ggetz!
Reviewers, don't forget to make sure that:
|
It will be great to see this at last! Did you consider a major version update due to the API change @ggetz ? https://semver.org/ |
Thanks @chris-cooper, historically cesiumjs has chosen not to use semver due to frequent breaking changes especially early in development. However, we are presently considering moving to semver to make updates like this easier. We're in the process of confirming this decision since it will likely have impacts among government users. So we're thinking about it, but I can't promise a version increment for this next release. |
I know @kring mentioned that |
This is private, right? So I assume you mean the internal documentation? I agree with @kring that all of Cesium's |
@mramato |
@ggetz I would definitely recommend a clean break. Anyone that was using |
The docs, I'm still fixes a handful of specs, but this is almost complete and should be ready for review. @sanjeetsuhag Could you please do a pass on this? |
@ggetz I went through all the Sandcastles and it seems like the only problematic one is CZML Custom Properties. |
Thanks @sanjeetsuhag, fixed! That test just needed to await loading the CZML. The tests are also in order now. I had to exclude a handful, mostly 3D tiles related, specs as there was some questionable error handling that led to errors being thrown that cannot be sensibly caught. I'm opening an issue for these excluded tests and will link it back into the specs. |
I wasn't able to duplicate locally, but I believed I've handled the intermittent failure that was happening in CI. @sanjeetsuhag do you have any additional feedback? |
Thanks @sanjeetsuhag. I do agree that its high priority, and labeled it accordingly. There's also only two tests in |
Have we ran any performance benchmarks against main to ensure that we haven't introduced a perf regression in any of the most common areas? (Like CWT + 3DTiles loading) or simple.czml animating on an empty globe. Not sure if we have any "canned" perf tests ready to go, perhaps @lilleyse might have some ideas about what we have done for 3D Tiles testing. |
if (!defined(this._backgroundTextureAtlas)) { | ||
this._backgroundTextureAtlas = new TextureAtlas({ | ||
context: context, | ||
initialSize: whitePixelSize, | ||
}); | ||
backgroundBillboardCollection.textureAtlas = this._backgroundTextureAtlas; | ||
addWhitePixelCanvas(this._backgroundTextureAtlas, this); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like a bugfix in addition to Promise update? Is that true? If so, what bug does it fix and should we include that in CHANGES? (even if we have no issue number for it).
I noticed a few places where there are little changes like this that appear to be bug fixes of some kind. If we just figured out the code is wrong but don't know how/if a bug manifested from it, that's fine too, nothing to report. But I just wanted to point it out in case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These were to address cases where the code assumed a promise was executing synchronously. When transitioning to native promises, even in cases where the promise immediately resolved, it wouldn't do so until the end of the frame. So the timing of the rest of the function is thrown off. I don't think these fix any existing bugs, just keep behavior working as before.
@@ -353,6 +352,49 @@ function addImage(textureAtlas, image, index) { | |||
textureAtlas._guid = createGuid(); | |||
} | |||
|
|||
function getIndex(atlas, image) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As a general rule, stuff like this should be called out in the PR description. I assume by looking at it we had to add some branch new code in order to provide a path for synchronous operations that would otherwise be async in our new "native" Promise world, but in a PR this big; it would be easy for a reviewer to miss. Also, if someone needs to use revision history to track where/why this code was added, it won't be obvious to them by reading the PR description (which it should be).
Even just a single bullet like "Added TextureAtlas.addImageSync to xxxx" would be extremely valuable to future devs.
This is especially true given the terseness of many of the commit messages in this PR (or perhaps we are squashing) but either way, a paper trail is important.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I planned on squashing commits with a more useful commit message. But understood, I'll call out these changes in the PR explicitly.
Two big things that jumped out at me:
|
Okay @ggetz I'll admit I kind of lost steam when I got to the specs, so I didn't review them thoroughly by any means. But this PR looks great and those minor comments were all I had. This is a major stepping stone for CesiumJS and an awesome way to start a true modernization effort. |
Yes, the extra code is definitely coming from spec modifications. There were tons of cases where we needed to add a few lines to await a promise before continuing. |
I've run several 3D Tiles and CWT examples including various photogrammetry, point clouds, and OSM buildings. I'm seeing similar loading times using the Chome profiler on main and this branch. Likewise with |
I usually just record how long it takes for tiles to load for a given view. Sometimes I'll also set up a flight path. Here are two of my go-to sandcastles:
|
There were a few areas in Source where a function was assumed to be executed synchronously when a function was resolved. Native Promises however, by spec, will resolve at the end of a frame. There were also some strange handling of promise rejection in imagery providers that I cleaned up a bit in order to make them testable. - In LabelCollection and EntityCluster, order of execution adjustment where made. - Added TextureAtlas.addImageSync to support the order of execution fix in LabelCollection - ArcGisMapServerImageryProvider.readyPromise will not reject if there is a failure unless the request cannot be retried. - SingleTileImageryProvider.readyPromise will not reject if there is a failure unless the request cannot be retried. The majority of the changes lie in the Specs, where unresolved promises weren’t being awaited before finishing executions, and where resolved promises are assumed to be synchronous all over the place and needed a good amount of fixes. Another issue which came up was calling Promise.reject in the body of a spec can cause node to halt execution when running via the command line.
Replaces #8525
Fixes #3967
Fixes #9578
This PR removes
when.js
in favor of native promises. Besides removing the files related to when itself, this generally follows the migration guide as laid out in the migration guide, swapping outwhen.defer
with a newdefer
function, switchingotherwise
forcatch
, andalways
forfinally
.There were a few areas in
Source
where a function was assumed to be executed synchronously when a function was resolved. Native Promises however, by spec, will resolve at the end of a frame. There were also some strange handling of promise rejection in imagery providers that I cleaned up a bit in order to make them testable.LabelCollection
andEntityCluster
, order of execution adjustment where made.TextureAtlas.addImageSync
to support the order of execution fix inLabelCollection
ArcGisMapServerImageryProvider.readyPromise
will not reject if there is a failure unless the request cannot be retried.SingleTileImageryProvider.readyPromise
will not reject if there is a failure unless the request cannot be retried.The majority of the changes lie in the Specs, where unresolved promises weren’t being awaited before finishing executions, and where resolved promises are assumed to be synchronous all over the place and needed a good amount of fixes. Another issue which came up was calling
Promise.reject
in the body of a spec can cause node to halt execution when running via the command line.Finally, I did need to tweak
eslint
in order to turn off the rule which disallows promises.Opening this a bit early. Still to do:defer
in generalCHANGES.md
- Add note aboutArcGisImageServerProvider
rejecting ready promise if there is a failure and retry isfalse
.build-ts
warnings