v0.35.0
This release contains a major overhaul of marcel internals, intended to anticipate
Python changes, and to enable porting.
Most marcel commands execute as jobs, which can be suspended, run in the background,
and brought to the foreground, as in other shells. The multiprocessing module is used
to run a job in a process. This module can start processes in one of three ways:
- fork: The child process inherits the parent's resources, including memory. (The memory is not shared,
as in threading. Changes made by the child are not visible by the parent.) - spawn: The child process is a new Python interpreter, and resources, including memory, are not shared.
- forkserver: Like fork, but the forking is done by a server process created for the purpose of
forking processes.
Fork is the default on Linux. Spawn is the default on MacOS, and will become the default on
Python. Prior to this release, marcel relied on fork. But it looks like spawn really needs to be
supported, especially to support MacOS. Fork on MacOS is known to possibly cause crashes.
Marcel environment variables are kept in a namespace, which serves as a Python namespace for
the execution of Python functions that appear in marcel commands. The problem was that the marcel
namespace worked well with the fork model of multiprocessing, but not spawn. With fork, the namespace
exists in memory shared with the child process. But when a process is spawned, the namespace isn't
shared, it has to be pickled and transmitted, and the namespace contains values that could
not be pickled: e.g. Python functions and modules.
So in order to support the spawn model of multiprocessing, the namespace implementation had to be
overhauled. Values that can be pickled are pickled. Others values require special handling.
For example, suppose a user has run the command import math. The math module cannot be pickled.
But by noting the import, and replaying it in the child process, we can avoid pickling the math
module, but still transmit it to the child process.
For now, marcel uses the spawn model of multiprocessing by default. This results in noticeably slower
operation, imposing
a fraction of a second delay to command execution. (It might be worth investigating forkserver
to fix this problem.) If this delay is intolerable, or you have found a bug and it seems
like spawning is implicated, then to use fork instead, set the environment variable
MARCEL_MULTIPROCESSING_START_METHOD. Valid values are fork and spawn.
With spawn multiprocessing supported, MacOS support should now be possible. Watch this space for
information on MacOS support.