-
Notifications
You must be signed in to change notification settings - Fork 2
OTP-1807 Move Trivial MonitoredTrip PreChecks #343
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
base: dev
Are you sure you want to change the base?
Changes from 9 commits
1a08039
40a74b7
2dcd510
6618ec7
ae692fc
6dcbe8e
a2e1470
d0339b8
71f1547
52c36d5
be84fd9
34c33c6
e914f22
4d31203
41c71a8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -750,43 +750,6 @@ public boolean shouldSkipMonitoredTripCheck() throws Exception { | |
| } | ||
|
|
||
| public boolean shouldSkipMonitoredTripCheck(boolean persist) throws Exception { | ||
| // before anything else, return true if the trip is inactive | ||
| if (!trip.isActive) { | ||
| LOG.info("Skipping: Trip is inactive."); | ||
| return true; | ||
| } | ||
|
|
||
| // If trip is no longer possible, no further checking is needed. The itinerary existence data should not be | ||
| // checked here to avoid incorrectly skipping trips that are monitored on a single day of the week, but which | ||
| // may have not had a matching itinerary on that day for one week (even though the trip could be possible the | ||
| // next week). | ||
| if (previousJourneyState.tripStatus == TripStatus.NO_LONGER_POSSIBLE) { | ||
| LOG.info("Skipping: Trip is no longer possible."); | ||
| return true; | ||
| } | ||
|
|
||
| // If trip is one-time and has ended, no further checking is needed. The itinerary existence data should not be | ||
| // checked here to avoid incorrectly skipping trips that are monitored on a single day of the week, but which | ||
| // may have not had a matching itinerary on that day for one week (even though the trip could be possible the | ||
| // next week). | ||
| if (isOneTimeTripInPast()) { | ||
| LOG.info("Skipping: One-time trip is in the past."); | ||
| return true; | ||
| } | ||
|
|
||
| // For trips that are snoozed, see if they should be unsnoozed first. | ||
| if (trip.snoozed) { | ||
| if (shouldUnsnoozeTrip()) { | ||
| // Clear previous matching itinerary as we want to start afresh. | ||
| previousMatchingItinerary = null; | ||
| // unsnooze trip now, for cases where the next itinerary isn't calculated | ||
| trip.snoozed = false; | ||
| } else { | ||
| LOG.info("Skipping: Trip is snoozed."); | ||
| return true; | ||
| } | ||
| } | ||
|
|
||
| // initialize the trip's journey state and matching itinerary to the latest journeyState's matching | ||
| // itinerary, or use the itinerary that the trip was saved with | ||
| if (previousMatchingItinerary == null) { | ||
|
|
@@ -858,6 +821,63 @@ public boolean shouldSkipMonitoredTripCheck(boolean persist) throws Exception { | |
| return true; | ||
| } | ||
|
|
||
| /** | ||
| * Convenience method for unit tests to do the precheck before the full check | ||
| */ | ||
| protected boolean shouldSkipMonitoredTripCheck(boolean persist, boolean preCheck) throws Exception { | ||
| if (preCheck && CheckMonitoredTrip.shouldSkipMonitoredTripPreCheck(trip)) { | ||
| return true; | ||
| } | ||
| return shouldSkipMonitoredTripCheck(persist); | ||
| } | ||
|
|
||
| /** | ||
| * A series of trivial checks a {@pre MonitoredTrip} object, just fields obtained from the database, to | ||
| * determine whether to instantiate a {@pre CheckMonitoredTrip} object to do further checking. | ||
| * @param trip candidate monitored trip to quickly check some fields of | ||
JymDyerIBI marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
JymDyerIBI marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| * @return whether to skip the trip, boolean value | ||
| */ | ||
| protected static boolean shouldSkipMonitoredTripPreCheck(MonitoredTrip trip) { | ||
JymDyerIBI marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| // before anything else, return true if the trip is inactive | ||
| if (!trip.isActive) { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because no action is performed on trips that match at least the criteria in these methods, I think the criteria should be added to the Mongo filter in
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @JymDyerIBI (not blocking) Any thoughts on my comment above? |
||
| LOG.info("Skipping: Trip {} is inactive.", trip.id); | ||
| return true; | ||
| } | ||
|
|
||
| // If trip is no longer possible, no further checking is needed. The itinerary existence data should not be | ||
| // checked here to avoid incorrectly skipping trips that are monitored on a single day of the week, but which | ||
| // may have not had a matching itinerary on that day for one week (even though the trip could be possible the | ||
| // next week). | ||
| if (trip.journeyState.tripStatus == TripStatus.NO_LONGER_POSSIBLE) { | ||
| LOG.info("Skipping: Trip {} is no longer possible.", trip.id); | ||
| return true; | ||
| } | ||
|
|
||
| // If trip is a one-off trip which has already happened, no further checking is needed. The itinerary existence | ||
| // data should not be checked here to avoid incorrectly skipping trips that are monitored on a single day of | ||
| // the week, but which may have not had a matching itinerary on that day for one week (even though the trip | ||
| // could be possible the next week). | ||
| if (trip.isOneTime() && trip.journeyState.tripStatus == TripStatus.PAST_TRIP) { | ||
| LOG.info("Skipping: One-time trip {} is in the past.", trip.id); | ||
| return true; | ||
| } | ||
|
|
||
| // For trips that are snoozed, see if they should be unsnoozed first. | ||
| if (trip.snoozed) { | ||
| if (shouldUnsnoozeTrip(trip.journeyState.lastCheckedEpochMillis)) { | ||
| // Clear previous matching itinerary as we want to start afresh. | ||
| trip.journeyState.matchingItinerary = null; | ||
| // unsnooze trip now, for cases where the next itinerary isn't calculated | ||
| trip.snoozed = false; | ||
| } else { | ||
| LOG.info("Skipping: Trip {} is snoozed.", trip.id); | ||
| return true; | ||
| } | ||
| } | ||
|
|
||
| return false; | ||
| } | ||
|
|
||
| /** | ||
| * Calculate target time for the next trip plan request. Find the next possible day the trip is active by | ||
| * initializing the appropriate target time. | ||
|
|
@@ -921,13 +941,6 @@ private static ZonedDateTime findNextMonitoredDay(MonitoredTrip trip, ZonedDateT | |
| return nextMonitoredDay; | ||
| } | ||
|
|
||
| /** | ||
| * Is a one-off trip which has already happened. | ||
| */ | ||
| private boolean isOneTimeTripInPast() { | ||
| return trip.isOneTime() && previousJourneyState.tripStatus == TripStatus.PAST_TRIP; | ||
| } | ||
|
|
||
| /** Check if previous matching itinerary day is still valid */ | ||
| private boolean isPrevMatchingItineraryDayValid() { | ||
| if (previousMatchingItinerary == null) return false; | ||
|
|
@@ -1070,14 +1083,15 @@ private Locale getOtpUserLocale() { | |
|
|
||
| /** | ||
| * Whether a trip should be unsnoozed and monitoring should resume. | ||
| * @param lastCheckedEpochMillis to acquire the trip's start day | ||
| * @return true if the current time is after the calendar day (on or after midnight) | ||
| * after the matching trip start day, false otherwise. | ||
| */ | ||
| public boolean shouldUnsnoozeTrip() { | ||
| public static boolean shouldUnsnoozeTrip(long lastCheckedEpochMillis) { | ||
| ZoneId otpZoneId = DateTimeUtils.getOtpZoneId(); | ||
| var midnightAfterLastChecked = ZonedDateTime | ||
| .ofInstant( | ||
| Instant.ofEpochMilli(previousJourneyState.lastCheckedEpochMillis).plus(1, ChronoUnit.DAYS), | ||
| Instant.ofEpochMilli(lastCheckedEpochMillis).plus(1, ChronoUnit.DAYS), | ||
| otpZoneId | ||
| ) | ||
| .withHour(0) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -72,6 +72,13 @@ public void run() { | |
| continue; | ||
| } | ||
|
|
||
| // Do a few trivial prechecks to see whether to even bother locking the trip | ||
| // and instantiating a CheckMonitoredTrip run. | ||
| if (CheckMonitoredTrip.shouldSkipMonitoredTripPreCheck(trip)) { | ||
| analyzerIsIdle.set(true); | ||
| continue; | ||
| } | ||
|
|
||
|
Comment on lines
+75
to
+81
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Delete this block and move the call to This change as written causes an error when updating a trip from the UI, for instance to pause notifications or modify a paused trip. When a trip is updated (PUT request), |
||
| LOG.info("Analyzing trip {}", tripId); | ||
|
|
||
| // place lock on trip | ||
|
|
||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Some code broke in CI with the error "CheckMonitoredTripTest.java:[1164,43] method shouldUnsnoozeTrip in class org.opentripplanner.middleware.tripmonitor.jobs.CheckMonitoredTrip cannot be applied to given types". |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1031,7 +1031,7 @@ void shouldReportRecurringTripInstanceInPastWithTrackingAsActive() throws Except | |
| String todayFormatted = trip.journeyState.targetDate; | ||
|
|
||
| CheckMonitoredTrip check = new CheckMonitoredTrip(trip, this::mockOtpPlanResponse); | ||
| check.shouldSkipMonitoredTripCheck(false); | ||
| check.shouldSkipMonitoredTripCheck(false, true); | ||
| check.checkOtpAndUpdateTripStatus(); | ||
| // Trip should remain active, and the target date should still be "today". | ||
| assertEquals(TRIP_ACTIVE, trip.journeyState.tripStatus); | ||
|
|
@@ -1215,13 +1215,15 @@ void canUpdateTripWithStaleState( | |
| // Mock the current time | ||
| DateTimeUtils.useFixedClockAt(clockTime); | ||
|
|
||
| // After trip has completed, check that trip status has been updated. | ||
| CheckMonitoredTrip check = new CheckMonitoredTrip(monitoredTrip, this::mockOtpPlanResponse); | ||
| if (!CheckMonitoredTrip.shouldSkipMonitoredTripPreCheck(monitoredTrip)) { | ||
| // After trip has completed, check that trip status has been updated. | ||
| CheckMonitoredTrip check = new CheckMonitoredTrip(monitoredTrip, this::mockOtpPlanResponse); | ||
|
|
||
| check.run(); | ||
| check.run(); | ||
|
|
||
| MonitoredTrip modifiedTrip = Persistence.monitoredTrips.getById(monitoredTrip.id); | ||
| assertEquals(expectedStatus, modifiedTrip.journeyState.tripStatus, message); | ||
| MonitoredTrip modifiedTrip = Persistence.monitoredTrips.getById(monitoredTrip.id); | ||
| assertEquals(expectedStatus, modifiedTrip.journeyState.tripStatus, message); | ||
| } | ||
|
||
| } | ||
|
|
||
| private static Stream<Arguments> createUpdateTripWithStaleStateCases() { | ||
|
|
@@ -1266,17 +1268,19 @@ void shouldNotUpdateInactiveOrSnoozedTrip( | |
| // Mock the current time | ||
| DateTimeUtils.useFixedClockAt(clockTime); | ||
|
|
||
| // After trip has completed, check that trip status has been updated. | ||
| CheckMonitoredTrip check = new CheckMonitoredTrip(monitoredTrip, this::mockOtpPlanResponse); | ||
| if (!CheckMonitoredTrip.shouldSkipMonitoredTripPreCheck(monitoredTrip)) { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would it make sense to replace this |
||
| // After trip has completed, check that trip status has been updated. | ||
| CheckMonitoredTrip check = new CheckMonitoredTrip(monitoredTrip, this::mockOtpPlanResponse); | ||
|
|
||
| check.run(); | ||
| check.run(); | ||
|
|
||
| MonitoredTrip modifiedTrip = Persistence.monitoredTrips.getById(monitoredTrip.id); | ||
| assertEquals( | ||
| monitoredTrip.journeyState.lastCheckedEpochMillis, | ||
| modifiedTrip.journeyState.lastCheckedEpochMillis, | ||
| "Should not check trip if " + (isActive ? "" : "in") + "active and " + (isSnoozed ? "" : "not ") + "snoozed." | ||
| ); | ||
| MonitoredTrip modifiedTrip = Persistence.monitoredTrips.getById(monitoredTrip.id); | ||
| assertEquals( | ||
| monitoredTrip.journeyState.lastCheckedEpochMillis, | ||
| modifiedTrip.journeyState.lastCheckedEpochMillis, | ||
| "Should not check trip if " + (isActive ? "" : "in") + "active and " + (isSnoozed ? "" : "not ") + "snoozed." | ||
| ); | ||
| } | ||
| } | ||
|
|
||
| private static Stream<Arguments> shouldNotUpdateInactiveOrSnoozedTripCases() { | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.