fix(routing): Release the GVL during native model setup - #5
Merged
Conversation
Allow Ruby threads to keep running while callback-free routing models close and restore route assignments. Keep the GVL when Ruby transit callbacks may execute.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Planner model close and warm-route restoration can spend tens of seconds in native OR-Tools code. Those calls held MRI's GVL, so one slow planner job prevented unrelated Ruby threads in the same process from serving requests, heartbeating, or handling signals. This addresses the process stalls investigated in the initial report and the second occurrence.
RoutingModel#close_modeland#read_assignment_from_routesnow release the GVL when the model uses only native callbacks. Models with Ruby transit callbacks retain the GVL so callback execution remains safe. Route arrays are converted to owned C++ values before release, and returned assignments are wrapped only after Ruby execution resumes.The callback-aware Ruby wrappers are the safety boundary. Raw native callback, solve, close, and assignment-restoration entry points are private so callers cannot bypass that gate. The planner algorithm and routing results remain unchanged; an individual native call can still run for a long time, but it no longer pauses the entire Ruby process.