perf: hoist DB calls out of realTimeMutex in GetAlertsForTrip#282
Conversation
|
@aaronbrethorst
|
aaronbrethorst
left a comment
There was a problem hiding this comment.
Smart optimization, Aditya. Moving blocking database I/O outside the realTimeMutex is the right call - holding a lock during slow operations like database queries is a classic recipe for contention and stale data. The change itself is correct and safe, but there's a misleading comment that should be fixed.
Incorrect/Misleading Comment
File: internal/gtfs/realtime.go:73
The comment says:
// IMPORTANT: Caller must hold manager.RLock() before calling this method.This comment is incorrect for this function:
manager.RLock()refers tostaticMutex(protectsgtfsData,lastUpdated, etc.)GetAlertsForTripdoesn't access any data protected bystaticMutex- It only accesses:
manager.GtfsDB- thread-safe (Go'sdatabase/sqlguarantees)manager.realTimeAlerts- protected byrealTimeMutex, which the function acquires internally
- Sibling functions
GetAlertsForRouteandGetAlertsForStophave no such comment and follow the same pattern
Fix: Remove or correct the comment:
// GetAlertsForTrip returns alerts matching the trip, its route, or agency.
func (manager *Manager) GetAlertsForTrip(ctx context.Context, tripID string) []gtfs.Alert {Good optimization. Just fix the misleading comment and this is ready to merge.
|
@aaronbrethorst |
aaronbrethorst
left a comment
There was a problem hiding this comment.
Hey Aditya! This is a nice performance optimization. Reducing lock scope to exclude blocking I/O is exactly the right approach for preventing writer starvation.
Fit and Finish
1. Stale comment in related code (out of scope, but worth noting)
Location: internal/restapi/trips_helper.go:769
The GetSituationIDsForTrip function has a comment that says:
// IMPORTANT: Caller must hold manager.RLock() before calling this method.This comment appears to be stale—none of the callers hold the lock before calling this method, and with your change, GetAlertsForTrip now manages its own locking internally. Additionally, GetSituationIDsForTrip itself does DB calls which shouldn't be done under a lock.
This is out of scope for this PR, but might be worth a quick follow-up PR to clean up that misleading comment.
Thanks for the contribution!

Description:
This PR fixes a concurrency bug where blocking database I/O was performed while holding the global
realTimeMutex.Closes #281
Motivation:
Previously,
GetAlertsForTripacquired a read lock before querying the database. This caused the real-time updater (which requires a write lock) to starve during high read traffic or slow database queries, leading to stale vehicle data.Changes:
Refactored
GetAlertsForTripininternal/gtfs/realtime.goto:RLockonly during the in-memory filtering of alerts.Verification: