opentripplanner / OpenTripPlanner

An open source multi-modal trip planner
http://www.opentripplanner.org
Other
2.21k stars 1.03k forks source link

Transit model refactor for easier integration with RT-updaters and transit model maintenance #4002

Open t2gran opened 2 years ago

t2gran commented 2 years ago

The transit model needs some love and care. RT-updates is error prone and inefficient, and almost impossible to maintain. The Raptor integration is unnecessarily complex.

Goals

Milestones

This is a very big task, so we decided on adding a few milestones to track progress.

Strategy: We will try to refactor/migrate as much as possible, but in some cases it will not be cost effective - very difficult. So, at some point we will create a OTPFeature flag to switch between the new and the old model. Note! The graph will be different, so the feature flag must be set to the same value for transit graph build and serve. The Street graph should not be affected.

Checklist - features we should remember to support

This is the list of features we should use to "functionally" verify our model. We do not need to implement these, but the model should take them into account so we CAN implement them in the future.

Model refactoring

New Transit Model

Package structure

This is just a starting point/suggestion, while working with this we will probably refactor several times.

[1] Might be a sub package of timetable

Package dependencies

transitPAckages This is WIP, we will see if the works out well. It might be that we also want to add a dependency from [network] to [schedule] (Pattern ->* Trip).

optionsome commented 2 years ago

"Allow for multiple new shapes for a changed trip/pattern" I think this issue is not only related to realtime updated patterns but for even scheduled ones.

slvlirnoff commented 2 years ago

For RT updates, I feel that there's a lot of duplication between GTFS and Siri relatives TimeTableSnapshotSource and associated classes (TripPatternCache, etc..) and this is not helping integrating other RT sources (VDV, custom profiles, etc.)

Would it be a goal also to generalize the interface to update the real time information? The various producers (gtfs-rt, siri, etc..) only mapping information for it?

t2gran commented 2 years ago

@slvlirnoff I agree, this is the intention. I added another goals to the list above - hope that makes it a bit more clear.

t2gran commented 2 years ago

Draft v31

I AM NOT MAINTAINING THIS MODEL ANY MORE, GO TO THE TRANSIT MODEL PACKAGE FOR LATEST VERSION. THE DOC IS INCLUDED IN #4718.

Note! This is the static Transit model used to serve Raptor, the mutable model seen by RT-Updaters will be different, and so will the model seen by the API. The idea is to decorate with view classes to simplify read access and use builders for mutation.

TransitModelDiagram_v31

slvlirnoff commented 2 years ago

@t2gran I have a few questions but also unable to see all the texts on my device (some are truncated), could you include it in another format?

t2gran commented 2 years ago

@t2gran Could you include it in another format?

Yes, I posted a png instead now - hope that works better. I used gliffy for this diagram, I can provide the gliffy file as well if someone wants it.

t2gran commented 2 years ago

At yesterdays developer meeting we discussed namin conventions and after the meeting I did little bit of design - I just document it here, waiting to get to the point where we can do this part.


Updaters run with a context(editor) This is not implemented, but is our vision :-)

TransitModelEditor ctx = transitService().editTransitModel();

// To modify a trip we get the builder, change it, and call save() 
ctx.trip(id).withPrivateCode("CBP").save();

// A more common case would be to perform a change to a trip schedule on a given date
// We would like something like this. Here a combination of command and entity builders are used        
ctx.on(date).changePattern(patternMatcher).removeStop(stopId).save();
ctx.on(date).cancelTrip(tripMatcher).save();
ctx.on(date).updateTrip(matchId(tripId)).arrivalTime(stopId, arrTime).depatureTime(stopId, depTime).save();

// To update the model and make the changes visible to other threads
ctx.commit();

The editor can keep track of what is changed and perform cascading updates and reindexing for the part of the model which is changed.

slvlirnoff commented 2 years ago

Hey @t2gran , some updaters have incremental updates and some have full dataset that should replace previous updates. How would that work with this? Would it be possible to "rollback" only the changes made by a specific ctx?

Maybe a "reset" call on the editor could help resetting changes saved and committed previously. A full dataset updater would first call reset() on the existing ctx before adding new changes and committing these and an incremental one would not and create new changes, committing these on top of existing ones.

Side question, how would the editors interact with each others? For instance ctx1 edit and commit trip1. Will ctx2 changes to trip1 be applied to the updated trip1 or to the "original" version of trip1. If these are applied on top of the updated trip1, what happens if you want to "reset" the changes made by ctx1?

t2gran commented 1 year ago

Maybe a "reset" call on the editor could help resetting changes saved and committed previously. A full dataset updater would first call reset() on the existing ctx before adding new changes and committing these and an incremental one would not and create new changes, committing these on top of existing ones.

Something like this:

// Revert an earlier update by going back to the planed version and apply new changes
ctx.on(date).trip(id).revertToPlanned().withDelay(5m).save();  

Side question, how would the editors interact with each others? For instance ctx1 edit and commit trip1. Will ctx2 changes to trip1 be applied to the updated trip1 or to the "original" version of trip1. If these are applied on top of the updated trip1, what happens if you want to "reset" the changes made by ctx1?

Not decided jet. But, I my first thought is to do "optimistic locking", if an updater have applied a change to an object that is not present in the main model any more, then the change is dropped. Each updater only see its own context; Hence it can query the model and get back the its own changes, but not changes in other contexts or changes made to the model after the context was created.

2martens commented 1 year ago

I have a question: would this model refactor allow combining, for example, GTFS schedule data and SIRI SX and SIRI ET?

leonardehrenfried commented 1 year ago

That's already possible.

Once the static data is imported we don't know anymore if it came from Netex or GTFS (well, almost) and you can apply any realtime updater you want.

2martens commented 1 year ago

Somewhere I took the information that NeTEx/SIRI and GTFS/GTFS-RT are linked.

leonardehrenfried commented 1 year ago

You have to do a bit of conceptual mapping (trip/journey, stop/quay, ...) in your head but OTP is already full of these.

github-actions[bot] commented 1 year ago

This issue is stale because it has been open 90 days with no activity. Remove stale label or comment or this will be closed in 30 days

github-actions[bot] commented 11 months ago

This issue is stale because it has been open 90 days with no activity. Remove stale label or comment or this will be closed in 30 days

github-actions[bot] commented 7 months ago

This issue is stale because it has been open 90 days with no activity. Remove stale label or comment or this will be closed in 30 days

github-actions[bot] commented 4 months ago

This issue is stale because it has been open 90 days with no activity. Remove stale label or comment or this will be closed in 30 days

github-actions[bot] commented 1 month ago

This issue is stale because it has been open 90 days with no activity. Remove stale label or comment or this will be closed in 30 days