Skip to content

Fix inconsistent route progress and index after rerouting#3345

Merged
1ec5 merged 5 commits into
mainfrom
1ec5-reroute-response-1141
Sep 16, 2021
Merged

Fix inconsistent route progress and index after rerouting#3345
1ec5 merged 5 commits into
mainfrom
1ec5-reroute-response-1141

Conversation

@1ec5
Copy link
Copy Markdown
Contributor

@1ec5 1ec5 commented Sep 9, 2021

After rerouting or proactive rerouting, keep the array of routes in the same order as in the Directions API response. Instead of reshuffling the array to put the most similar route first, update the route index to point to the most similar route (except when proactively rerouting to the most optimal route). This change makes the post-rerouting state more consistent with the pre-rerouting state as of #3182.

RouteController.routeProgress and LegacyRouteController.routeProgress are no longer writable. Synchronize RouteController.indexedRouteResponse after rerouting to ensure consistency with routeProgress.

Consolidated calls to NavigationServiceDelegate.navigationService(_:willRerouteFrom:) and NavigationServiceDelegate.navigationService(_:didRerouteAlong:at:proactive:) and the posting of Notification.Name.routeControllerWillReroute and Notification.Name.routeControllerDidReroute to ensure they occur consistently around reroutes. When posting these notifications, pass in a proactive rerouting flag directly instead of relying on a parallel didFindFasterRoute flag that was difficult to reason about.

Fixes #3343 and potentially other bugs.

/cc @mapbox/navigation-ios

@1ec5 1ec5 added bug Something isn’t working op-ex Refactoring, Tech Debt or any other operational excellence work. backwards incompatible changes that break backwards compatibility of public API labels Sep 9, 2021
@1ec5 1ec5 added this to the v2.0.0 (RC) milestone Sep 9, 2021
@1ec5 1ec5 requested review from S2Ler and ShanMa1991 September 9, 2021 07:51
@1ec5 1ec5 self-assigned this Sep 9, 2021
@1ec5 1ec5 force-pushed the 1ec5-reroute-response-1141 branch from f645e10 to 8db32ca Compare September 9, 2021 07:55
@1ec5 1ec5 force-pushed the 1ec5-reroute-response-1141 branch from 8db32ca to 378bc78 Compare September 9, 2021 08:03
@1ec5 1ec5 requested a review from OttyLab September 9, 2021 08:04
Comment thread Sources/MapboxCoreNavigation/Router.swift Outdated
@S2Ler
Copy link
Copy Markdown
Contributor

S2Ler commented Sep 9, 2021

One of the tests are failing.

Copy link
Copy Markdown
Contributor

@azarovalex azarovalex left a comment

Choose a reason for hiding this comment

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

lgtm, but if we add changes in the latest moment before the RC, we need to test them at least manually

Comment thread Sources/MapboxCoreNavigation/LegacyRouteController.swift Outdated
Comment thread Sources/MapboxCoreNavigation/Router.swift Outdated
@1ec5 1ec5 force-pushed the 1ec5-reroute-response-1141 branch from 378bc78 to 446e6b3 Compare September 9, 2021 08:24
@1ec5

This comment has been minimized.

@1ec5 1ec5 force-pushed the 1ec5-reroute-response-1141 branch from b293a0b to be2bdda Compare September 9, 2021 09:17
Comment on lines 587 to 588
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The route index and step index default to 0, so I removed the explicit call to change the step index to 0.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This was the one other place where the did-reroute notification needed to get inlined. It’s weird that an application explicitly setting the route will get a notification back telling it what it just did, but that’s the only way that various parts of MapboxNavigation will be able to respond to the new route being set. As a case in point, the addition of this line fixes the integration test failure.

Comment on lines 272 to 275
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

While inlining setRoute(_:proactive:routeOptions:) here, I restored an old comment from before #1986 that explained why we try to persist the spoken instruction index in the new route progress. Apparently we consider it confusing to hear the “Head northwest on Main Street” instruction out of the blue without the rerouting chime.

This bit of gymnastics dates back to when we originally implemented proactive rerouting in #346. At the time, there was no concept of an instruction index, only an “alert level” that increased as the user neared the maneuver point. Maintaining the alert level made sense as a way to suppress that initial instruction, since the alert level would’ve been guaranteed to be nonzero at any time beyond the beginning of the old step.

We migrated to server-generated instructions in #614, eliminating the concept of alert levels in favor of instruction indices. 903e020 migrated this code to persist the instruction index, but that introduced a potential problem: unlike alert levels, there’s theoretically an arbitrary number of instruction indices that could vary from one step to the next, or between two steps belonging to two different routes.

I don’t know for sure that this persistence is causing any problems, so I’ve retained the behavior for now, but it needs a closer look. There’s got to be a better way to suppress the initial departure instruction, if we still think that’s necessary.

@1ec5

This comment has been minimized.

@S2Ler

This comment has been minimized.

@1ec5
Copy link
Copy Markdown
Contributor Author

1ec5 commented Sep 9, 2021

lgtm, but if we add changes in the latest moment before the RC, we need to test them at least manually

Since we’re literally on the cusp of releasing v2.0.0-rc.1, I’ve cleaned up #3344 so we can land just that targeted fix for #3343 and the related bugs. We’ll land this PR right after v2.0.0-rc.2 to give us some additional time to test the more comprehensive fixes before releasing v2.0.0-rc.2.

@1ec5 1ec5 modified the milestones: v2.0.0 (RC), v2.0.0 (GA) Sep 9, 2021
@1ec5 1ec5 force-pushed the 1ec5-reroute-response-1141 branch from ff86c07 to d8965bc Compare September 9, 2021 10:34
@1ec5 1ec5 requested review from S2Ler and azarovalex September 9, 2021 15:35
@1ec5 1ec5 force-pushed the 1ec5-reroute-response-1141 branch from d8965bc to f462297 Compare September 14, 2021 01:26
@1ec5

This comment has been minimized.

@S2Ler

This comment has been minimized.

Copy link
Copy Markdown
Contributor

@ShanMa1991 ShanMa1991 left a comment

Choose a reason for hiding this comment

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

When I test this pr on Example-CarPlay with multiple route legs under simulation mode and repeated several times. There's a failure occurring as following:

func updateIndexes(status: NavigationStatus, progress: RouteProgress) {
let newLegIndex = Int(status.legIndex)
let newStepIndex = Int(status.stepIndex)
let newIntersectionIndex = Int(status.intersectionIndex)
let oldLegIndex = progress.legIndex
if newLegIndex != progress.legIndex {
progress.legIndex = newLegIndex
}

It happened in a two legs route which would advance from the first leg to the next leg. The routeProgress.legIndex as 1.

But the route in the routeProgress only has one leg , and the oldLegIndex = 0. Then it triggers the assertion failure of legIndex < route.legs.endIndex after the progress.legIndex = newLegIndex.

So my concern is that why the routeProgress contains the route only has 1 leg which in fact should have 2 on this branch. Is it related with the indexedRouteResponse?

@1ec5 1ec5 force-pushed the 1ec5-reroute-response-1141 branch from f462297 to 344115b Compare September 16, 2021 01:20
Previously, rerouting and proactive rerouting reshuffled the response to place the most similar route at the front, expecting client code to assume a route index of zero. With this change, the response remains intact and so does the route index, except when proactively rerouting to the most optimal (first) route.
Setting RouteController.routeProgress or LegacyRouteController.routeProgress no longer calls delegate methods or posts notifications related to rerouting; this is now the responsibility of its callers. Consolidated will-reroute delegate method calls and notifications to ensure they occur consistently around reroutes. Use the proactive rerouting flag directly instead of relying on parallel state. Inlined route setting in response to proactive rerouting.
Prevent client code from desynchronizing routeProgress from indexedRouteResponse, which is already read-only.
@1ec5 1ec5 force-pushed the 1ec5-reroute-response-1141 branch from 344115b to f96227b Compare September 16, 2021 19:32
@1ec5
Copy link
Copy Markdown
Contributor Author

1ec5 commented Sep 16, 2021

When I test this pr on Example-CarPlay with multiple route legs under simulation mode and repeated several times. There's a failure occurring as following

I’m unable to reproduce this issue when simulating a route with two legs in Example-CarPlay on this branch.

destination 3

Did you use the navigation SDK’s built-in route simulation feature or the iOS or Xcode route simulation feature? Can you share the coordinates of the waypoints you used?

@ShanMa1991
Copy link
Copy Markdown
Contributor

Did you use the navigation SDK’s built-in route simulation feature or the iOS or Xcode route simulation feature? Can you share the coordinates of the waypoints you used?

Yes, I'm using the navigation SDK’s built-in route simulation feature with the waypoints inside the SF downtown area. This issue could be reproduced with multiple times of 2-leg routes navigation star and cancel, along with the issue #3276 .

@ShanMa1991
Copy link
Copy Markdown
Contributor

The inconsistent route progress and index issue in multi-leg rout navigation under simulation mode will be tracked in #3276 . Thanks for the testing !

@1ec5 1ec5 merged commit 1e35987 into main Sep 16, 2021
@1ec5 1ec5 deleted the 1ec5-reroute-response-1141 branch September 16, 2021 23:43
@1ec5
Copy link
Copy Markdown
Contributor Author

1ec5 commented Sep 16, 2021

After squashing and merging, this build failed. Rerunning the build succeeded.

Test Case '-[MapboxCoreNavigationTests.BillingHandlerUnitTests testSessionBeginFailed]' started.
Warning: Using NavigationSettings.initialize(directions:tileStoreConfiguration:) after corresponding variables was initialized. Possible reasons: Initialize called more than once, or the following properties was accessed before initialization: `tileStoreConfiguration`, `directions`. This might result in an undefined behaviour. 
2021-09-16 23:49:38.511471+0000 xctest[1677:62393] [Billing] Trip session isn't started. Please check that you have the correct Mapboox Access Token
2021-09-16 23:49:38.521475+0000 xctest[1677:62689] <nav-native> No PersistentConfig found at /Users/distiller/Library/Developer/CoreSimulator/Devices/DED5E213-8043-44B3-9F26-6D4CB4FED885/data/Library/Application Support/.mapbox/tile_store/navigation/config.json
2021-09-16 23:49:38.521783+0000 xctest[1677:62689] <nav-native> Unable to find the latest version of routing tiles!
2021-09-16 23:49:38.522037+0000 xctest[1677:62689] <nav-native> Async config init - Unable to determine the routing tiles version
/Users/distiller/project/Tests/MapboxCoreNavigationTests/BillingHandlerTests.swift:159: error: -[MapboxCoreNavigationTests.BillingHandlerUnitTests testSessionBeginFailed] : XCTAssertEqual failed: ("stopped") is not equal to ("running")
Test Case '-[MapboxCoreNavigationTests.BillingHandlerUnitTests testSessionBeginFailed]' failed (0.276 seconds).

@S2Ler, should we increase the timeout for this test too, or is there a deeper issue?

waitForExpectations(timeout: 1, handler: nil)

@S2Ler
Copy link
Copy Markdown
Contributor

S2Ler commented Sep 17, 2021

After squashing and merging, this build failed. Rerunning the build succeeded.

Test Case '-[MapboxCoreNavigationTests.BillingHandlerUnitTests testSessionBeginFailed]' started.
Warning: Using NavigationSettings.initialize(directions:tileStoreConfiguration:) after corresponding variables was initialized. Possible reasons: Initialize called more than once, or the following properties was accessed before initialization: `tileStoreConfiguration`, `directions`. This might result in an undefined behaviour. 
2021-09-16 23:49:38.511471+0000 xctest[1677:62393] [Billing] Trip session isn't started. Please check that you have the correct Mapboox Access Token
2021-09-16 23:49:38.521475+0000 xctest[1677:62689] <nav-native> No PersistentConfig found at /Users/distiller/Library/Developer/CoreSimulator/Devices/DED5E213-8043-44B3-9F26-6D4CB4FED885/data/Library/Application Support/.mapbox/tile_store/navigation/config.json
2021-09-16 23:49:38.521783+0000 xctest[1677:62689] <nav-native> Unable to find the latest version of routing tiles!
2021-09-16 23:49:38.522037+0000 xctest[1677:62689] <nav-native> Async config init - Unable to determine the routing tiles version
/Users/distiller/project/Tests/MapboxCoreNavigationTests/BillingHandlerTests.swift:159: error: -[MapboxCoreNavigationTests.BillingHandlerUnitTests testSessionBeginFailed] : XCTAssertEqual failed: ("stopped") is not equal to ("running")
Test Case '-[MapboxCoreNavigationTests.BillingHandlerUnitTests testSessionBeginFailed]' failed (0.276 seconds).

@S2Ler, should we increase the timeout for this test too, or is there a deeper issue?

waitForExpectations(timeout: 1, handler: nil)

yes, increasing to 3 or 5 should fix it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backwards incompatible changes that break backwards compatibility of public API bug Something isn’t working op-ex Refactoring, Tech Debt or any other operational excellence work.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Parallel copies of route in Router can get out of sync

4 participants