grass.pygrass: Pin fork start method for RPC servers on Python 3.14#7724
Open
petrasovaa wants to merge 1 commit into
Open
grass.pygrass: Pin fork start method for RPC servers on Python 3.14#7724petrasovaa wants to merge 1 commit into
petrasovaa wants to merge 1 commit into
Conversation
Python 3.14 changed the default multiprocessing start method from fork to forkserver on all platforms except macOS (python/cpython#84559). The RPC servers in grass.pygrass.rpc and grass.temporal rely on fork: their worker processes call libgis via ctypes and must inherit the initialized library state and the GRASS session environment from the parent. Under forkserver the worker is forked from an early, clean process without the GRASS runtime, and the forkserver socket teardown raises FileNotFoundError in the server-checker thread. Define a shared multiprocessing context in grass.pygrass.rpc.base that pins fork where it was the previous default, and reuse it in the three start_server implementations. macOS (already spawn) and Windows (no fork) keep their default start method, so the change is a no-op there and on Python <= 3.13. Root-caused and drafted with the help of Claude (Opus 4.8).
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.
Problem
Running temporal tools under Python 3.14 fails, e.g.
t.list strds:Reported by @veroandreo (WSL, Python 3.14).
Cause
Python 3.14 changed the default
multiprocessingstart method fromforktoforkserveron every platform except macOS(python/cpython#84559).
GRASS's RPC servers were relying on the implicit
forkdefault. Their worker processes runlibgisthrough ctypes and depend onforksemantics: they inherit the already-initialized C library state and the live GRASS session environment (GISRC, etc.) from the parent. Underforkserver, the worker is forked from an early, clean forkserver process that never had the GRASS runtime set up, and the forkserver control socket gets torn down as the session exits — producing theFileNotFoundErrorin the checker thread and the leaked-semaphore warning.Fix
This targeted fix pins fork to restore prior behavior. A longer-term move to spawn is worth evaluating separately...
Pin
forkin one shared place and reuse it. Thestart_serverpattern is duplicated across three implementations that all shareRPCServerBase:python/grass/pygrass/rpc/base.py— add a module-levelMP_CONTEXTthat selectsforkwhere it was the previous default, and use it instart_server.python/grass/pygrass/rpc/__init__.py(DataProvider) andpython/grass/temporal/c_libraries_interface.py(CLibrariesInterface) — importMP_CONTEXTand use it in their overriddenstart_server.macOS was already on spawn (since 3.8) and Windows has no fork, so the change is a deliberate no-op on those platforms and on Python <= 3.13, where fork was already the default.
Testing
Tested with @veroandreo and locally on linux with Python 3.12, worked fine.