-
Notifications
You must be signed in to change notification settings - Fork 2.3k
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
Conversation
@@ -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) { |
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.
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.
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.
@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.
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.
redoWhenDone
is also used when the tile is loaded, here.
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.
Ah, I missed that somehow. Will fix, thanks for spotting 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.
Fixed now. Ready for review.
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.
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.
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.
Looks like I'm having a bad day. Amended the commit, need to add a test for 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.
@jfirebaugh added a few more basic tests for this.
f8b5c9e
to
2d4e854
Compare
2d4e854
to
5763249
Compare
@@ -129,14 +129,16 @@ class Tile { | |||
} | |||
|
|||
redoPlacement(source) { | |||
if (source.type !== 'vector' && source.type !== 'geojson') { | |||
if ((source.type !== 'vector' && source.type !== 'geojson')) { |
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.
Nit: unnecessary extra parentheses.
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 tilestate
isloaded
, but all the data variables arenull
, causingredoPlacement
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
document any changes to public APIspost benchmark scores