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 a "ghost points" scenario #27

Merged
merged 25 commits into from
Jan 12, 2017
Merged

Fix a "ghost points" scenario #27

merged 25 commits into from
Jan 12, 2017

Conversation

hackergrrl
Copy link
Contributor

This happens where a map query is made with 'forks' disabled, meaning only
the latest version of each OSM element is returned.

In some cases an OSM 'way' that is excluded will reference OSM nodes that
are not present in the way that is ultimately returned. Prior to this
commit, those ways' unreferenced nodes would be returned regardless,
resulting in the final map being peppered with unlabeled
"ghost points", with no way referencing them.

This fixes the issue by tracking which nodes are referenced to by ways that
are excluded, and filtering them out of the final result.

This happens where a map query is made with 'forks' disabled, meaning
only the latest version of each OSM element is returned.

In some cases an OSM 'way' that is excluded will reference OSM nodes
that are not present in the way that is ultimately returned. Prior to
this commit, those ways' unreferenced nodes would be returned
regardless, resulting in the final map being peppered with unlabeled
"ghost points", with no way referencing them.

This fixes the issue by tracking which nodes are referenced to by ways
that are excluded, and filtering them out of the final result.
@hackergrrl hackergrrl changed the title Fix "ghost points" bug. Fix a "ghost points" bug scenario Jan 10, 2017
@hackergrrl hackergrrl changed the title Fix a "ghost points" bug scenario Fix a "ghost points" scenario Jan 10, 2017
@@ -29,13 +29,7 @@ module.exports = function (req, res, api, params, next) {
}
api.getMap(bbox, function (err, elements) {
Copy link
Member

Choose a reason for hiding this comment

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

This fork logic should be in https://github.com/digidem/osm-p2p-server/blob/master/api/get_map.js I think. I see now an unrelated error: the switch (accept.types(['xml', 'json'])) should be called whether query.forks is true or false - I introduced this bug when I introduced the json endpoint.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done and fixed.

Copy link
Member

@gmaclennan gmaclennan left a comment

Choose a reason for hiding this comment

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

Can we move the logic to api/get_map.js? I think it makes more sense there. We could extract the filterForkElements function and test that independently, which would make the test simpler - we just test that function.

Copy link
Member

@gmaclennan gmaclennan left a comment

Choose a reason for hiding this comment

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

Sorry somehow started another "review" instead of just leaving a comment

// Remove excluded entries that appear in the keep entries.
Object.keys(keepNodeRefs).forEach(function (ref) {
if (excludeNodeRefs[ref]) {
delete excludeNodeRefs[ref]
Copy link
Member

Choose a reason for hiding this comment

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

This will be slow and can cause memory issues. I think that looking at line #94 you don't actually need this, but my head is a little slow right now...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I see an opportunity to expand my Node knowledge! Why will this be slow? What memory issues will it cause?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed; though I'm still curious to understand the performance concerns.

@hackergrrl
Copy link
Contributor Author

  1. Moved the filter piece to the API layer.
  2. Moved the filter logic into its own module in lib/.
  3. Added unit tests for (2).
  4. Simplified filtering logic to hopefully be more performant.

@gmaclennan
Copy link
Member

gmaclennan commented Jan 11, 2017 via email

@hackergrrl
Copy link
Contributor Author

I added some more tests to cover the scenario where there are two forks to a way: one modifies a point, one deletes a point.

@gmaclennan
Copy link
Member

Sorry to report bad news... Unfortunately there seems to be some kind of race condition here, and test/ghost_points.js fails about 1 in 3 times:

not ok 19 should be equal
  ---
    operator: equal
    expected: 2
    actual:   3
    at: ConcatStream.<anonymous> (/Users/gregor/Dev/DdDev/osm-p2p-server/node_modules/concat-stream/index.js:36:43)
  ...
not ok 20 should be equivalent
  ---
    operator: deepEqual
    expected: |-
      [ '2864043637183826736', '9003328637408641236' ]
    actual: |-
      [ '2864043637183826736', '5274879986653545291', '9003328637408641236' ]
    at: ConcatStream.<anonymous> (/Users/gregor/Dev/DdDev/osm-p2p-server/node_modules/concat-stream/index.js:36:43)
  ...
ok 21 undefined

Unfortunately setting env OSM_P2P_DB_DELAY=200 does not seem to reliably reproduce this bug, which it is supposed to.

@gmaclennan
Copy link
Member

I added slowdb() to the tests but still not reliably reproducing. This race condition may be coming from somewhere else, maybe in the test setup itself.

@gmaclennan
Copy link
Member

Still getting random errors...

Without fully parsing your code, I suspect that this may be due to unstable sorting of forks because you are creating points directly (i.e. not with the osm-server api) without timestamps, so the sorting will be based on version numbers rather than timestamps.

@gmaclennan
Copy link
Member

Ok, adding timestamps fixes this. I'm going to merge and cut a release so we can work with this today, but @noffle can you review this test once more to check I'm not missing anything with this fix?

@gmaclennan gmaclennan merged commit 0494f02 into master Jan 12, 2017
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.

2 participants