-
Notifications
You must be signed in to change notification settings - Fork 2
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
Trip monitor timing refactor #75
Conversation
Codecov Report
@@ Coverage Diff @@
## dev #75 +/- ##
============================================
+ Coverage 38.74% 42.13% +3.38%
- Complexity 264 297 +33
============================================
Files 81 81
Lines 2261 2307 +46
Branches 258 264 +6
============================================
+ Hits 876 972 +96
+ Misses 1301 1231 -70
- Partials 84 104 +20 Continue to review full report at Codecov.
|
@evansiroky the unit test "canMonitorTrip()" fails with the following exception: java.io.FileNotFoundException: src\test\resources\org\opentripplanner\middleware\planResponse.json (The system cannot find the file specified) This file is located in src\test\resources\org\opentripplanner\middleware\persistence. |
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.
On the face of it this looks really good. I don't feel I have enough experience to comment on the finer workings so will leave that to others. Perhaps a walk through would be useful, at least for me?
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.
I will need to play some more with it, but see my comments so far.
src/main/java/org/opentripplanner/middleware/models/MonitoredTrip.java
Outdated
Show resolved
Hide resolved
@@ -279,5 +302,68 @@ public boolean delete() { | |||
// TODO: Add journey state deletion. | |||
return Persistence.monitoredTrips.removeById(this.id); | |||
} | |||
|
|||
public List<NameValuePair> getParsedParams() throws URISyntaxException { |
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.
I think this should return a Map
, and it would simplify method isArriveBy
below and the class constructor.
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.
Should the be a @BsonIgnore
annotation?
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.
I have been trying to see if the stuff plays well with the UI. This is what I understand is happening:
reflection on the underlying types is still attempted on deserialization.@BsonIgnore
seems to prevent reflection on the field/method on serialization, but@JsonIgnore
seems to prevent reflection both on serialization and on deserialization. This is what we should use.
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.
Never mind that didn't seem to work. So this method should probably be renamed, e.g. parseParams()
src/main/java/org/opentripplanner/middleware/tripMonitor/jobs/CheckMonitoredTrip.java
Outdated
Show resolved
Hide resolved
src/main/java/org/opentripplanner/middleware/tripMonitor/jobs/CheckMonitoredTrip.java
Show resolved
Hide resolved
src/main/java/org/opentripplanner/middleware/tripMonitor/jobs/CheckMonitoredTrip.java
Outdated
Show resolved
Hide resolved
src/main/java/org/opentripplanner/middleware/tripMonitor/jobs/CheckMonitoredTrip.java
Outdated
Show resolved
Hide resolved
// parse query params | ||
List<NameValuePair> params = URLEncodedUtils.parse( | ||
new URI(String.format("http://example.com/%s", trip.queryParams)), | ||
UTF_8 | ||
); | ||
|
||
// begin building a new list and along the way and figure out if this trip is a depart at or arrive by trip | ||
// building a new list by copying all values, except for the date which is set to the target date | ||
List<NameValuePair> newParams = new ArrayList<>(); |
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.
Echoing my comment for MonitoredTrip#getParsedParams
, a map might be useful here too.
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.
I disagree because this variable is sent to the URLEncodedUtils.format
which needs some kind of Iterable.
List<NameValuePair> parsedParams = getParsedParams(); | ||
for (NameValuePair parsedParam : parsedParams) { | ||
if (parsedParam.getName().equals("time")) { | ||
tripTime = parsedParam.getValue(); |
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.
At least of these things should also take place with this change:
- Update all
MonitoredTrip
records in Mongo with a value fortripTime
(and on UI side, make sure that field gets populated too), - If reading a
MonitoredTrip
record from Mongo with notripTime
value set, initializetripTime
on first use ofgetHour()
orgetMinute()
, which would be more fool-proof.
* use the local time at the destination. Therefore, this method will return the timezone at the destination if this | ||
* trip is an arriveBy trip, or the timezone at the origin if the trip is a depart at trip. | ||
*/ | ||
@BsonIgnore |
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.
Same here. @BsonIgnore
and JsonIgnore
are... ignored by the Mongo POJO codec on serialization. The easiest way is to rename the method (findTimezoneForTargetLocation
?). If a get
prefix is still needed, we can use the transient
keyword (we've faced a similar issue 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.
- Some
MonitoredTrip
methods need to be modified to play well with serialization. MonitoredTrip#tripTime
may need to be initialized on first use, or the databases need to be updated, let me know what approach you'd prefer.
Should be ready for review again. |
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.
Sorry, there is one gap regarding the initialization of tripTime
I would like to get resolved.
// extract trip time from parsed params | ||
Map<String, String> params = parseQueryParams(); | ||
tripTime = params.get("time"); | ||
if (tripTime == null) { |
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.
To follow up on #75 (comment),
the UI does not currently initialize tripTime
, so tripTime
also needs to be initialized when polling tripTimeHour
or tripTimeMinute
. (Those methods are called by CheckMonitoredTrip#shouldSkipMonitoredTripCheck
).
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, ok I see what's happening. I added some logic to the MonitoredTripController's preCreateHook and preUpdateHook to enforce the existence of the trip time before it gets saved to the database.
*/ | ||
@BsonIgnore | ||
public int tripTimeHour() { | ||
return Integer.valueOf(tripTime.split(":")[0]); |
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.
There should still be a null check (at least) here and in tripTimeMinutes
.
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.
The tripTime should be guaranteed to exist due to #75 (comment).
@@ -24,7 +24,7 @@ | |||
import static com.beerboy.ss.descriptor.EndpointDescriptor.endpointPath; | |||
import static com.beerboy.ss.descriptor.MethodDescriptor.path; | |||
import static org.opentripplanner.middleware.auth.Auth0Connection.isUserAdmin; | |||
import static org.opentripplanner.middleware.utils.DateTimeUtils.YYYY_MM_DD; | |||
import static org.opentripplanner.middleware.utils.DateTimeUtils.DEFAULT_DATE_FORMAT_PATTERN; |
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.
In my view, this variable just became harder to read with this name change.
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.
I disagree and believe it has resulted in a more explicit meaning with intended usage conveyed through its name.
public boolean isArriveBy() throws URISyntaxException { | ||
// if arriveBy is not included in query params, OTP will default to false, so initialize to false | ||
return parseQueryParams().getOrDefault("arriveBy", "false").equals("true"); | ||
} |
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.
I find the code in parseQueryParams and isArriveBy to be a little hard to read and overly clever. I would prefer the use of one or two variables to improve legibility. Also, these could use some basic javadoc.
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.
I also agree that the parseQueryParams is clever, but don't think it's too clever. I think breaking it up wouldn't really add much value. I went ahead and added JavaDoc though in 6fd00a9
src/main/java/org/opentripplanner/middleware/models/MonitoredTrip.java
Outdated
Show resolved
Hide resolved
src/main/java/org/opentripplanner/middleware/models/MonitoredTrip.java
Outdated
Show resolved
Hide resolved
src/main/java/org/opentripplanner/middleware/models/MonitoredTrip.java
Outdated
Show resolved
Hide resolved
* - the current time is after the lead time before the next itinerary starts, but is over an hour until the | ||
* itinerary start time and the trip has already been checked within the last 60 minutes | ||
* - the current time is after the lead time before the next itinerary starts and between 60-15 minutes prior to the | ||
* itinerary start time, but a check has occurred within the last 15 minutes |
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.
This feels a bit wordy. The language could be simplified to improve how it reads (without losing clarity). Also, I don't think this accounts for the every minute check within 30 minutes that has been added.
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.
I updated this a little bit in 6fd00a9, but prefer to be hyper-specific when talking about timing matters.
src/main/java/org/opentripplanner/middleware/tripMonitor/jobs/CheckMonitoredTrip.java
Show resolved
Hide resolved
src/main/java/org/opentripplanner/middleware/tripMonitor/jobs/CheckMonitoredTrip.java
Outdated
Show resolved
Hide resolved
src/main/java/org/opentripplanner/middleware/tripMonitor/jobs/CheckMonitoredTrip.java
Show resolved
Hide resolved
src/main/java/org/opentripplanner/middleware/tripMonitor/jobs/CheckMonitoredTrip.java
Show resolved
Hide resolved
src/main/java/org/opentripplanner/middleware/tripMonitor/jobs/CheckMonitoredTrip.java
Outdated
Show resolved
Hide resolved
src/main/java/org/opentripplanner/middleware/tripMonitor/jobs/CheckMonitoredTrip.java
Show resolved
Hide resolved
src/main/java/org/opentripplanner/middleware/tripMonitor/jobs/CheckMonitoredTrip.java
Outdated
Show resolved
Hide resolved
src/main/java/org/opentripplanner/middleware/tripMonitor/jobs/CheckMonitoredTrip.java
Outdated
Show resolved
Hide resolved
src/main/java/org/opentripplanner/middleware/otp/response/OtpResponse.java
Show resolved
Hide resolved
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.
This is looking good, but I do have some concerns about how some of the CheckMonitoredTrips methods have been structured and how they update class variables (could use some touch ups to comments as well).
Codecov Report
@@ Coverage Diff @@
## dev #75 +/- ##
============================================
+ Coverage 38.74% 42.13% +3.39%
- Complexity 264 296 +32
============================================
Files 81 81
Lines 2261 2302 +41
Branches 258 265 +7
============================================
+ Hits 876 970 +94
+ Misses 1301 1228 -73
- Partials 84 104 +20 Continue to review full report at Codecov.
|
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.
Thanks for the changes/consideration.
Checklist
dev
before they can be merged tomaster
)Description
This PR refactors the timing aspects of the trip monitor. The previous implementation was a little naive and had trouble calculating the proper time to check since it didn't use information from previous checks. This PR changes that and now will store the next upcoming itinerary for a trip and will use that check as a baseline for determining if a trip check should be skipped and how long to wait before the lead time. This results in making requests on the proper date and tracking a trip all the way until the end even if it goes longer than scheduled.
So, this PR addresses both the
change in monitored trip monitoring window settings
andRecalculate for current day (plan trip at the appropriate time)
items in #70.Here is a summary of changes:
YYYY_MM_DD
->DEFAULT_DATE_FORMAT_PATTERN
org.opentripplanner.middleware.otp.response.Response
->org.opentripplanner.middleware.otp.response.OtpResponse
...millis
to make it clear that the values are millisecondsisInActive
method for checking if the trip is never activegetTimezoneForTargetLocation
and associated helper methods to get the appropriate timezone to calculate a target time with based off of whether the trip is departing at or arriving bygetHour
andgetMinute
.startTime
andendTime
withduration
instead. This is probably a temporary fix and more nuance will be needed in the future especially when dealing with realtime itinerariesshouldSkipMonitoredTripCheck
. This method now calculates itineraries if none have been calculated before in order to have a baseline to use when determining if a formal check of the trip is warranted that might result in notifications being sent out.calculateNextItinerary
which advances the trip to the appropriate date and sends off a request to OTP to obtain a new baseline itinerary to compare with in future checks of the trip.canGenerateTripPlanQueryParams
was removed.