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

Fix race condition in Tile redoPlacement #3985

Merged
merged 3 commits into from
Jan 18, 2017
Merged

Conversation

mourner
Copy link
Member

@mourner mourner commented Jan 16, 2017

Closes #3700. @sguignot please confirm that this fixes the issue for you.

The race condition happened when redoPlacement was called for an empty GeoJSON tile. In this case tile state is loaded, but all the data variables are null, causing redoPlacement to proceed sending the request to redo placement when it's not necessary, and breaking in the callback. Added a basic tests to make sure this doesn't regress.

Launch Checklist

  • briefly describe the changes in this PR
  • write tests for all new functionality
  • document any changes to public APIs
  • post benchmark scores
  • manually test the debug page

@mourner mourner requested a review from lucaswoj January 16, 2017 18:22
@@ -129,11 +129,11 @@ class Tile {
}

redoPlacement(source) {
if (source.type !== 'vector' && source.type !== 'geojson') {
if ((source.type !== 'vector' && source.type !== 'geojson') ||
!this.hasData() || !this.collisionTile) {
Copy link
Contributor

@jfirebaugh jfirebaugh Jan 16, 2017

Choose a reason for hiding this comment

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

Does this affect the behavior if redoPlacement is called before the tile is initially loaded? For example, if the map is rotated while tiles are loading, it may be necessary to redo placement immediately after the load completes. This normally happens via this.redoWhenDone, but it appears that this change may bypass that logic.

Copy link
Member Author

Choose a reason for hiding this comment

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

@jfirebaugh I thought about that, but the problem is that this logic doesn't work currently anyway, because redoWhenDone is only processed in the done callback which can only happen after a successful redoPlacement request (after the tile got loaded). Maybe we should rewrite the code to take this case into account in a follow-up PR.

Copy link
Contributor

Choose a reason for hiding this comment

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

redoWhenDone is also used when the tile is loaded, here.

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah, I missed that somehow. Will fix, thanks for spotting this.

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed now. Ready for review.

Copy link
Contributor

Choose a reason for hiding this comment

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

Can you explain how this avoids the issue? It looks like checking !this.collisionTile will still prevent reaching the this.redoWhenDone = true; case when redoPlacement is called while the tile is initially loading.

Copy link
Member Author

Choose a reason for hiding this comment

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

Looks like I'm having a bad day. Amended the commit, need to add a test for this.

Copy link
Member Author

Choose a reason for hiding this comment

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

@jfirebaugh added a few more basic tests for this.

@sguignot
Copy link

@mourner yes it fixes the issue #3700, thanks!

@mourner mourner force-pushed the fix-reload-symbol-error branch from 2d4e854 to 5763249 Compare January 17, 2017 21:24
@@ -129,14 +129,16 @@ class Tile {
}

redoPlacement(source) {
if (source.type !== 'vector' && source.type !== 'geojson') {
if ((source.type !== 'vector' && source.type !== 'geojson')) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: unnecessary extra parentheses.

@mourner mourner merged commit d0543e6 into master Jan 18, 2017
@mourner mourner deleted the fix-reload-symbol-error branch January 18, 2017 22:53
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.

Uncaught TypeError: Cannot read property 'length' of null (CollisionTile in Tile.reloadSymbolData)
3 participants