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

Upend resource loading approach #6035

Merged
merged 54 commits into from
Jan 19, 2018
Merged

Upend resource loading approach #6035

merged 54 commits into from
Jan 19, 2018

Conversation

hpinkos
Copy link
Contributor

@hpinkos hpinkos commented Dec 6, 2017

Not ready to merge, looking for early feedback on this approach.

An alternate solution for #6019 (based on #6019 (comment))

Instead of adding yet another argument to loadWithXhr, this creates a Resource class that handles all the arguments used by loadWithXhr and methods for getting a derived resource with a modified url from the parent resource.

Resource will also help us replace all the joinUrls and crazy url string concatenation we do all over the code base. Instead of building a url with a query string by appending them together, it has separate url, queryParameter and hash properties so we can make changes to them separately. The getter for url builds the final url from all of these pieces.

@mramato @shunter what do you think of this approach vs #6019? Is this what you had in mind?

The changes I made thus far were fairly painless. I left the more complicated ones for the end:

  • ArcGisMapServerImageryProvider
  • BingMapsImageryProvider
  • GoogleEarthEnterpriseMapsProvider
  • GoogleEarthEnterpriseImageryProvider
  • MapboxImageryProvider
  • SingleTileImageryProvider
  • UrlTemplateImageryProvider
  • WebMapServiceImageryProvider
  • WebMapTileServiceImageryProvider
  • createOpenStreetMapImageryProvider
  • CesiumTerrainProvider
  • VRTheWorldTerrainProvider
  • GoogleEarthEnterpriseTerrainProvider
  • GoogleEarthEnterpriseMetadata
  • Model
  • ModelInstanceCollection
  • ClassificationModel
  • Cesium3DTileset
  • Cesium3DTile
  • Batched3DModel3DTileContent
  • Instanced3DModel3DTileContent
  • PointCloud3DTileContent
  • Composite3DTileContent
  • Tileset3DTileContent
  • Cesium3DTileStyle
  • CzmlDataSource
  • GeoJsonDataSource
  • KmlDataSource
  • ModelGraphics
  • ModelVisualizer

Other TODOs:

  • Properly deprecate options that are in the Resource object that a class may have taken separately (usually proxy, headers or query) Deprecation for resources #6120
  • Possibly deprecate joinUrls.
  • Add retry logic to loadImage
  • Make sure allowCrossOrigin is used properly.
  • Broken Sandcastle examples
    • Time Dynamic WMTS
    • KML
    • Both CZML Model examples
  • Tests
    • Retry tests for loadWithXhr and loadImage
    • At least 1 test that takes a Resource for the above classes
    • Resource class

Copy link
Contributor

@shunter shunter left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a good start and fits what I had imagined. I see there is still a lot of cleanup to go through. Hopefully in the end a lot of this code will seem simpler than it previously did.

uri.query = undefined;
}

if (defined(uri.fragment)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fragment is an interesting case, since it's not actually sent to the server, so technically it's can't affect a remote resource in any way. I suppose it makes sense since this encapsulates an URI, though. I would be curious if any of the existing functionality actually makes use of fragments (I suspect not).


this._url = '';
this._queryParameters = defaultValue(options.queryParameters, {});
this._hash = defaultValue(options.hash, '');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably prefer the term "fragment" to "hash".

this.url = options.url;

this.headers = options.headers;
this.request = options.request;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suspect we can continue further and inline the contents of Request into Resource as well.

@@ -629,7 +635,13 @@ define([
extensionList.push('watermask');
}

var promise = loadArrayBuffer(url, getRequestHeader(extensionList), request);
var resource = this._resource.getDerivedResource({
url: urlTemplates[(x + tmsY + level) % urlTemplates.length].replace('{z}', level).replace('{x}', x).replace('{y}', tmsY),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

URL template interpolation might be another good candidate to move into Resource, since we do this in a number of places. Basically it could accept a templated URL and a dictionary of key-value parameters.

@a-stacey
Copy link

I know that this is early stage code looking for feedback, but I was wondering whether any thought had gone into what options in retryOnError(options) was going to look like https://github.com/AnalyticalGraphicsInc/cesium/pull/6035/files#diff-2fc7c9967319d4e36d2cfaa797fd2326R164?

I have recently been working on implementing refreshing tokens for ArcGisMapServerImageryProvider and being able to detect and update the token specifically when the token expires is quite essential (to make sure that the token refresh code can specifically renew the token only when this is known or likely to be the underlying cause):
https://github.com/TerriaJS/cesium/pull/25/files#diff-0aee433aff2911bddecaa6f3d1515d8dR585
https://github.com/TerriaJS/cesium/pull/25/files#diff-0aee433aff2911bddecaa6f3d1515d8dR651

It seems that the structure in this branch/PR allows much more scope for options to include the status code when present then the structure on #6019 and in particular the issue described by @mramato comment on the status code response #6019 (comment).

@samherrmann
Copy link

Would this solution also support the loading of Billboard images?

@mramato
Copy link
Contributor

mramato commented Dec 14, 2017

@a-stacey The goal is to definitely provide the status code where possible. (any time the browser returns it)

@samherrmann Yes, the goal of this approach is that anywhere Cesium currently takes a string url/uri will now be able to take a Resource object as well.

Glad to see we already have two people interested in this PR, I think it will fix a lot of long-standing issues with how Cesium handles external requests.

@shunter
Copy link
Contributor

shunter commented Dec 14, 2017

Copying my comment which I accidentally left on the old PR:

Also consider the differences in how images are requested by imagery providers - loadImage won't be able to handle request headers, for example. Automatic transparent fallback to loadImageViaBlob can be done if the request needs it (for performance reasons, it should prefer direct loadImage if it will work for a given resource).

See discussion thread: https://groups.google.com/d/topic/cesium-dev/3NxyEFmMzDM/discussion

callbackParameterName = options.callbackParameterName;
}
if (defined(request)) {
//TODO deprecate
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO

});
function loadText(urlOrResource, headers, request) {
if (typeof urlOrResource === 'string') {
urlOrResource = new Resource({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing deprecation if headers or request is provided?

@@ -87,7 +89,7 @@ define([
that._isReady = true;
}

when(loadImageViaBlob(options.missingImageUrl), success, failure);
when(loadImageViaBlob(new Resource({url: options.missingImageUrl})), success, failure);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file can be reverted.

});
}
if (defined(request)) {
//TODO deprecation warning
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO

@mramato
Copy link
Contributor

mramato commented Jan 17, 2018

Phew, I started to run out of steam at the end there, but I think that's everything I have for my first pass. Awesome work @tfili (and thank you @hpinkos for getting the ball rolling).

My main concern is the whole race condition/modification of resource issue I brought up in #6035 (comment)

I would really appreciate another full set of eyeballs on this (particular your @shunter) so let me know what bribes you are currently accepting 😄

@tfili
Copy link
Contributor

tfili commented Jan 18, 2018

Ok, I think this is ready for another look.

@mramato
Copy link
Contributor

mramato commented Jan 18, 2018

Thanks @tfili, I'll do another pass ASAP.

@mramato
Copy link
Contributor

mramato commented Jan 19, 2018

@tfili is that last checkbox done, or is that still TODO?

@mramato
Copy link
Contributor

mramato commented Jan 19, 2018

@tfili I'm getting 161 failures running the tests locally, do they pass for you? (I'm on Linux, I'll check the Windows side and see if it happens there too). I'm surprised travis is passing.

@mramato
Copy link
Contributor

mramato commented Jan 19, 2018

@tfili never mind, false alarm. Looks like a GPU driver update was causing the issues.

*
* @returns {Request} The modified result parameter or a new Resource instance if one was not provided.
*/
Request.prototype.clone = function(result) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like you have a comment in Resource.clone about purposefully not cloning the request, so is this still used or should this file be reverted?

@mramato
Copy link
Contributor

mramato commented Jan 19, 2018

I think that's the only other comments I have. Does anyone else want to look at this? At the very least it would be good if someone hammered on it some more in case there was any breaking I missed. (but it will also have 2 weeks in master to settle down before release, so we'll be fine either way).

@tfili
Copy link
Contributor

tfili commented Jan 19, 2018

@mramato I reverted Request.js and yes, the checkbox was already done. I think this is good unless someone else has something.

@pjcozzi
Copy link
Contributor

pjcozzi commented Jan 19, 2018

I don't have bandwidth to review, but impressive stats @tfili @hpinkos!

image

@mramato
Copy link
Contributor

mramato commented Jan 19, 2018

Thanks again @hpinkos and @tfili! Plenty of time until the next release in case we missed anything.

@mramato mramato merged commit 9dc0836 into master Jan 19, 2018
@cesium-concierge
Copy link

Congratulations on closing the issue! I found these Cesium forum links in the comments above:

https://groups.google.com/d/topic/cesium-dev/3NxyEFmMzDM/discussion

If this issue affects any of these threads, please post a comment like the following:

The issue at #6035 has just been closed and may resolve your issue. Look for the change in the next stable release of Cesium or get it now in the master branch on GitHub https://github.com/AnalyticalGraphicsInc/cesium.


I am a bot who helps you make Cesium awesome! Contributions to my configuration are welcome.

🌍 🌎 🌏

@mramato mramato deleted the upend-resource-loading branch January 19, 2018 15:15
});

urlResource.addQueryParameters({
key: this._key
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding the key here results in it being sent with every tile request, which is not correct. The key is only supposed to be sent with the metadata request, as it was in the previous code. I'll open a PR.

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

Successfully merging this pull request may close these issues.

9 participants