Skip to content
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -750,30 +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()) {
Expand Down Expand Up @@ -858,6 +834,50 @@ 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 on fields in a candidate monitored trip as obtained from the database, to determine
* whether to do all the other checking that instantiating this class has to offer.
* @param trip candidate monitored trip to quickly check some fields of
* @return whether to skip the trip, boolean value
*/
protected static boolean shouldSkipMonitoredTripPreCheck(MonitoredTrip trip) {
// before anything else, return true if the trip is inactive
if (!trip.isActive) {
Copy link
Collaborator

Choose a reason for hiding this comment

The 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 MonitorAllTripsJob.makeTripFilter (where some checks here are redundant with those filters). What do you think?

Copy link
Collaborator

Choose a reason for hiding this comment

The 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;
}

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.
Expand Down Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Copy link
Collaborator

Choose a reason for hiding this comment

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

Delete this block and move the call to shouldSkipMonitoredTripPreCheck, either back inside shouldSkipMonitoredTripCheck, or in doRun right before the call to shouldSkipMonitoredTripCheck.

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), new CheckMonitoredTrip(trip).run() gets run. Because the skipping logic is no longer run, it will try to compute the next active date of an inactive trip (and will never find one).

LOG.info("Analyzing trip {}", tripId);

// place lock on trip
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ void testSkipMonitoredTripCheck(SkipMonitoringTestArgs args) throws Exception {
}
assertEquals(
args.expectedResult,
new CheckMonitoredTrip(trip).shouldSkipMonitoredTripCheck(false),
new CheckMonitoredTrip(trip).shouldSkipMonitoredTripCheck(false, true),
args.message
);
}
Expand Down
Copy link
Collaborator

Choose a reason for hiding this comment

The 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
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Fix indent for if block.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Indent fixed.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Fix indent for the closing bracket.

}

private static Stream<Arguments> createUpdateTripWithStaleStateCases() {
Expand Down Expand Up @@ -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)) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Would it make sense to replace this if block with an assertion on the expected value for shouldSkipMonitoredTripCheck?

// 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() {
Expand Down
Loading