@@ -271,15 +271,28 @@ public UpdateResult applyTripUpdates(
271
271
// starts for example at 40:00, yesterday would probably be a better guess.
272
272
serviceDate = localDateNow .get ();
273
273
}
274
-
275
- uIndex += 1 ;
276
- LOG .debug ("trip update #{} ({} updates) :" , uIndex , tripUpdate .getStopTimeUpdateCount ());
277
- LOG .trace ("{}" , tripUpdate );
278
-
279
274
// Determine what kind of trip update this is
280
275
final TripDescriptor .ScheduleRelationship tripScheduleRelationship = determineTripScheduleRelationship (
281
276
tripDescriptor
282
277
);
278
+ var canceledPreviouslyAddedTrip = false ;
279
+ if (!fullDataset ) {
280
+ // Check whether trip id has been used for previously ADDED trip message and mark previously
281
+ // created trip as DELETED unless schedule relationship is CANCELED, then as CANCEL
282
+ var cancelationType = tripScheduleRelationship ==
283
+ TripDescriptor .ScheduleRelationship .CANCELED
284
+ ? CancelationType .CANCEL
285
+ : CancelationType .DELETE ;
286
+ canceledPreviouslyAddedTrip =
287
+ cancelPreviouslyAddedTrip (tripId , serviceDate , cancelationType );
288
+ // Remove previous realtime updates for this trip. This is necessary to avoid previous
289
+ // stop pattern modifications from persisting
290
+ this .buffer .removeRealtimeAddedTripPatternAndTimetablesForTrip (tripId , serviceDate );
291
+ }
292
+
293
+ uIndex += 1 ;
294
+ LOG .debug ("trip update #{} ({} updates) :" , uIndex , tripUpdate .getStopTimeUpdateCount ());
295
+ LOG .trace ("{}" , tripUpdate );
283
296
284
297
Result <UpdateSuccess , UpdateError > result ;
285
298
try {
@@ -297,8 +310,18 @@ public UpdateResult applyTripUpdates(
297
310
tripId ,
298
311
serviceDate
299
312
);
300
- case CANCELED -> handleCanceledTrip (tripId , serviceDate , CancelationType .CANCEL );
301
- case DELETED -> handleCanceledTrip (tripId , serviceDate , CancelationType .DELETE );
313
+ case CANCELED -> handleCanceledTrip (
314
+ tripId ,
315
+ serviceDate ,
316
+ CancelationType .CANCEL ,
317
+ canceledPreviouslyAddedTrip
318
+ );
319
+ case DELETED -> handleCanceledTrip (
320
+ tripId ,
321
+ serviceDate ,
322
+ CancelationType .DELETE ,
323
+ canceledPreviouslyAddedTrip
324
+ );
302
325
case REPLACEMENT -> validateAndHandleModifiedTrip (
303
326
tripUpdate ,
304
327
tripDescriptor ,
@@ -347,6 +370,26 @@ public UpdateResult applyTripUpdates(
347
370
return updateResult ;
348
371
}
349
372
373
+ /**
374
+ * This shouldn't be used outside of this class for other purposes than testing where the forced
375
+ * snapshot commit can guarantee consistent behaviour.
376
+ */
377
+ TimetableSnapshot getTimetableSnapshot (final boolean force ) {
378
+ final long now = System .currentTimeMillis ();
379
+ if (force || now - lastSnapshotTime > maxSnapshotFrequency .toMillis ()) {
380
+ if (force || buffer .isDirty ()) {
381
+ LOG .debug ("Committing {}" , buffer );
382
+ snapshot = buffer .commit (transitLayerUpdater , force );
383
+ } else {
384
+ LOG .debug ("Buffer was unchanged, keeping old snapshot." );
385
+ }
386
+ lastSnapshotTime = System .currentTimeMillis ();
387
+ } else {
388
+ LOG .debug ("Snapshot frequency exceeded. Reusing snapshot {}" , snapshot );
389
+ }
390
+ return snapshot ;
391
+ }
392
+
350
393
private static void logUpdateResult (
351
394
String feedId ,
352
395
Map <TripDescriptor .ScheduleRelationship , Integer > failuresByRelationship ,
@@ -367,22 +410,6 @@ private static void logUpdateResult(
367
410
});
368
411
}
369
412
370
- private TimetableSnapshot getTimetableSnapshot (final boolean force ) {
371
- final long now = System .currentTimeMillis ();
372
- if (force || now - lastSnapshotTime > maxSnapshotFrequency .toMillis ()) {
373
- if (force || buffer .isDirty ()) {
374
- LOG .debug ("Committing {}" , buffer );
375
- snapshot = buffer .commit (transitLayerUpdater , force );
376
- } else {
377
- LOG .debug ("Buffer was unchanged, keeping old snapshot." );
378
- }
379
- lastSnapshotTime = System .currentTimeMillis ();
380
- } else {
381
- LOG .debug ("Snapshot frequency exceeded. Reusing snapshot {}" , snapshot );
382
- }
383
- return snapshot ;
384
- }
385
-
386
413
/**
387
414
* Determine how the trip update should be handled.
388
415
*
@@ -435,11 +462,6 @@ private Result<UpdateSuccess, UpdateError> handleScheduledTrip(
435
462
return UpdateError .result (tripId , NO_SERVICE_ON_DATE );
436
463
}
437
464
438
- // If this trip_id has been used for previously ADDED/MODIFIED trip message (e.g. when the
439
- // sequence of stops has changed, and is now changing back to the originally scheduled one),
440
- // mark that previously created trip as DELETED.
441
- cancelPreviouslyAddedTrip (tripId , serviceDate , CancelationType .DELETE );
442
-
443
465
// Get new TripTimes based on scheduled timetable
444
466
var result = pattern
445
467
.getScheduledTimetable ()
@@ -686,10 +708,6 @@ private Result<UpdateSuccess, UpdateError> handleAddedTrip(
686
708
"number of stop should match the number of stop time updates"
687
709
);
688
710
689
- // Check whether trip id has been used for previously ADDED trip message and mark previously
690
- // created trip as DELETED
691
- cancelPreviouslyAddedTrip (tripId , serviceDate , CancelationType .DELETE );
692
-
693
711
Route route = getOrCreateRoute (tripDescriptor , tripId );
694
712
695
713
// Create new Trip
@@ -1104,10 +1122,6 @@ private Result<UpdateSuccess, UpdateError> handleModifiedTrip(
1104
1122
var tripId = trip .getId ();
1105
1123
cancelScheduledTrip (tripId , serviceDate , CancelationType .DELETE );
1106
1124
1107
- // Check whether trip id has been used for previously ADDED/REPLACEMENT trip message and mark it
1108
- // as DELETED
1109
- cancelPreviouslyAddedTrip (tripId , serviceDate , CancelationType .DELETE );
1110
-
1111
1125
// Add new trip
1112
1126
return addTripToGraphAndBuffer (
1113
1127
trip ,
@@ -1122,19 +1136,21 @@ private Result<UpdateSuccess, UpdateError> handleModifiedTrip(
1122
1136
private Result <UpdateSuccess , UpdateError > handleCanceledTrip (
1123
1137
FeedScopedId tripId ,
1124
1138
final LocalDate serviceDate ,
1125
- CancelationType markAsDeleted
1139
+ CancelationType cancelationType ,
1140
+ boolean canceledPreviouslyAddedTrip
1126
1141
) {
1142
+ // if previously a added trip was removed, there can't be a scheduled trip to remove
1143
+ if (canceledPreviouslyAddedTrip ) {
1144
+ return Result .success (UpdateSuccess .noWarnings ());
1145
+ }
1127
1146
// Try to cancel scheduled trip
1128
- final boolean cancelScheduledSuccess = cancelScheduledTrip (tripId , serviceDate , markAsDeleted );
1129
-
1130
- // Try to cancel previously added trip
1131
- final boolean cancelPreviouslyAddedSuccess = cancelPreviouslyAddedTrip (
1147
+ final boolean cancelScheduledSuccess = cancelScheduledTrip (
1132
1148
tripId ,
1133
1149
serviceDate ,
1134
- markAsDeleted
1150
+ cancelationType
1135
1151
);
1136
1152
1137
- if (!cancelScheduledSuccess && ! cancelPreviouslyAddedSuccess ) {
1153
+ if (!cancelScheduledSuccess ) {
1138
1154
debug (tripId , "No pattern found for tripId. Skipping cancellation." );
1139
1155
return UpdateError .result (tripId , NO_TRIP_FOR_CANCELLATION_FOUND );
1140
1156
}
0 commit comments