fix: resolve race condition and double HTTP write in location APIs#691
fix: resolve race condition and double HTTP write in location APIs#691AhmedAlian7 wants to merge 1 commit intoOneBusAway:mainfrom
Conversation
aaronbrethorst
left a comment
There was a problem hiding this comment.
Ahmed, this is a well-structured refactoring that tackles three distinct problems — race condition, double HTTP write, and scattered validation — with a single cohesive extraction. The LocationParams struct and parseLocationParams method are the right abstraction for consolidating the duplicated parsing logic across the three location handlers.
What works well
- Race condition fix: Moving
RLock()/RUnlock()aboveparseAndValidateRequestintrips_for_location_handler.go:22-25ensuresGetAgencies()is safely called under the read lock. - No more double writes: Removing the direct
ResponseWriterwrites from insideparseLocationParamsand instead returning errors for the caller to handle is the correct pattern. - Error aggregation: The
fieldErrorsmap threading throughparseLocationParams→ParseMaxCount→ etc. means clients see all validation problems in a single response instead of having to fix-and-retry one at a time. err→serverErrrename inparseAndValidateRequestmakes the distinction between field validation errors and server errors immediately clear.
Fit and Finish (1 found)
1. Return nil instead of the fieldErrors map on the happy path — location_params.go:47
When all parsing and validation succeeds, line 47 returns:
return &LocationParams{...}, fieldErrorsAt this point fieldErrors is either nil or an empty map (depending on what the upstream ParseFloatParam calls returned). Both work correctly at call sites since callers check len(fieldErrors) > 0, but returning nil explicitly on the success path is more idiomatic and removes any ambiguity:
return &LocationParams{
Lat: lat,
Lon: lon,
Radius: radius,
LatSpan: latSpan,
LonSpan: lonSpan,
}, nilThis is cosmetic — the current code is functionally correct.
Checklist
- Tests pass
- Lint clean (pre-existing
errcheckingtfs_manager_test.gois onmain) -
go fmtclean - Race condition addressed
- Double HTTP write resolved
- Error aggregation unified across all three handlers
Merge Conflicts
This branch currently has merge conflicts with main that will need to be resolved before merging. Please rebase or merge main into your branch and resolve the conflicts.
Recommended Action
Merge (after resolving conflicts). The fit-and-finish item is optional and can be addressed at your discretion.
Description
The changes address the race condition, double HTTP response write, and error aggregation issues mentioned in the previous review.
Changes Made
api.GtfsManager.RLock()anddefer api.GtfsManager.RUnlock()above theparseAndValidateRequestcall intrips_for_location_handler.goto safely protectGetAgencies().parseLocationParamssignature inlocation_params.goto accept and return thefieldErrorsmap. Removed the code that was directly writing tow(ResponseWriter) mid-process.stops_for_location_handler.go,routes_for_location_handler.go, andtrips_for_location_handler.goto properly chain thefieldErrorsmap using the newparseLocationParamssignature. This ensures that all validation errors (e.g., location,maxCount,routeType) are successfully aggregated and returned as a single list to the user.