Skip to content
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

Enforce immutability of published timetable snapshot #5934

Conversation

vpaturet
Copy link
Contributor

@vpaturet vpaturet commented Jun 27, 2024

Summary

This PR makes use of immutable data structures in the timetable snapshot.
This ensures that attempts to modify the data structures after the snapshot is committed will fail fast.

In addition the immutable maps created by Map.copyOf() and ImmutableSetMultimap.copyOf() cannot contain null keys or values, providing a way to fail fast if these conditions are not fulfilled.

To further prevent attempts to modify a published timetable snapshot, methods that modify the states are either made private or are guarded by a condition on the readOnly field.

Note: It does not seem that in today's code any of these requirements on immutability is broken: the write API is not called after the timetable snapshot is created, null keys and values are not used, the collections are not modified after publication (but the objects they refer to may be modified).
The main purpose of this PR is to make these requirements more visible, to make sure they are not broken in the future, and to make reasoning on the timetable snapshot easier.

Issue

No

Unit tests

Added unit tests to check immutability (some existing tests already partially test the public API for immutability. The new tests are more focused on testing only this aspect)

Documentation

No

Copy link

codecov bot commented Jun 27, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 69.47%. Comparing base (15b49f9) to head (22ed45e).
Report is 24 commits behind head on dev-2.x.

Additional details and impacted files
@@            Coverage Diff             @@
##             dev-2.x    #5934   +/-   ##
==========================================
  Coverage      69.47%   69.47%           
- Complexity     17075    17079    +4     
==========================================
  Files           1936     1937    +1     
  Lines          73669    73679   +10     
  Branches        7539     7539           
==========================================
+ Hits           51180    51188    +8     
- Misses         19865    19870    +5     
+ Partials        2624     2621    -3     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@vpaturet vpaturet changed the title Use immutable collections in timetable snapshot. Enforce immutability of published timetable snapshot. Jun 27, 2024
@vpaturet vpaturet force-pushed the use_immutable_collections_in_timetable_snapshot branch from 2437559 to 108f0a2 Compare June 28, 2024 08:38
@vpaturet vpaturet marked this pull request as ready for review June 28, 2024 08:55
@vpaturet vpaturet requested a review from a team as a code owner June 28, 2024 08:55
@leonardehrenfried leonardehrenfried changed the title Enforce immutability of published timetable snapshot. Enforce immutability of published timetable snapshot Jun 28, 2024
@vpaturet vpaturet force-pushed the use_immutable_collections_in_timetable_snapshot branch from 108f0a2 to 22ed45e Compare July 2, 2024 08:34
@leonardehrenfried leonardehrenfried added the Real-Time Update The issue/PR is related to RealTime updates label Jul 2, 2024
@leonardehrenfried leonardehrenfried added this to the 2.6 (next release) milestone Jul 2, 2024
Copy link
Member

@leonardehrenfried leonardehrenfried left a comment

Choose a reason for hiding this comment

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

Thanks for the explanation in today's meeting. This looks like a good change.

@@ -91,16 +92,15 @@ public class TimetableSnapshot {
* The compound key approach better reflects the fact that there should be only one Timetable per
* TripPattern and date.
*/
private HashMap<TripPattern, SortedSet<Timetable>> timetables = new HashMap();
private Map<TripPattern, SortedSet<Timetable>> timetables = new HashMap<>();
Copy link
Member

Choose a reason for hiding this comment

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

I wonder if it would make sense to convert this to a SortedSetMultimap.

Copy link
Contributor Author

@vpaturet vpaturet Jul 8, 2024

Choose a reason for hiding this comment

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

That would make the intent more obvious, but at the same time that would hide the SortedSet as an implementation detail of the MultiMap. But we need to keep control over this SortedSet to be able to implement copy-and-write (and to replace it by an ImmutableSortedSet) as done in #5941

Copy link
Member

@abyrd abyrd left a comment

Choose a reason for hiding this comment

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

This looks like a great step in the right direction for the realtime updating subsystem! Thanks for explaining all your findings to us in the meetings.

For future reference: core changes here include replacing HashMap.clone() with Map.copyOf and using ImmutableSetMultimap.copyOf() when committing the read-only snapshot.

@vpaturet vpaturet merged commit 05b9f38 into opentripplanner:dev-2.x Jul 10, 2024
5 checks passed
@vpaturet vpaturet deleted the use_immutable_collections_in_timetable_snapshot branch July 10, 2024 06:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Real-Time Update The issue/PR is related to RealTime updates Skip Changelog Technical Debt
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants