- Child tracebacks survive Future.result(): the worker carries its
rendered traceback on the failure and the parent re-attaches it via
__cause__, so result() shows the originating frames. An unpicklable
exception becomes a RuntimeError preserving that traceback rather than
degrading silently into SubmissionDied.
- BaseException escaping a worker is now diagnosable: a SystemExit or
KeyboardInterrupt raised by fn is wrapped as SubmissionDied with the
cause chained, while a causeless SubmissionDied still means a truly
silent death (SIGKILL, os._exit, failed send).
- CallbackRaised reports a registration seqno: Future.when_done() returns
a per-Future seqno (user callbacks start at 0) carried on
CallbackRaised.seqno, so a caught exception ties back to the registering
call.
- concurrent.futures.Future.cancel() is wired through JobserverExecutor:
cancelling a PENDING future tells the dispatcher to prune the work before
dispatch rather than running it and discarding the result, via a weakref
callback that no longer pins the executor alive.
- map() reclaims slots more eagerly: abandoning the returned generator
(close()/del/GC or a Blocked deadline) reclaims finished workers' slots,
and children blocked mid-send on a large result (exceeding the ~64KB pipe
buffer) are drained via their result connection.
- JobserverExecutor fails loudly instead of hanging: the receiver loop
marks the executor broken and fails all outstanding futures with
BrokenExecutor (chaining the cause), catches a cancel/Started
InvalidStateError race, and cleans up an owned Jobserver on startup
failure.
- submit()/shutdown() race fixed: a submit racing shutdown(cancel_futures=
True) could land after the blanket Cancel and still run; the dispatcher
now latches a cancelling flag so any late Submit is cancelled on arrival.
- MinimalQueue hardened: put() is narrowed to a single item to remove a
partial-sequence hazard on BrokenPipeError, get()/put() read the
connection under the lock to close a close-vs-use race, and a plain
threading.Lock replaces the cross-process Lock.
- Earlier and clearer validation: env keys/values must be strings, map()'s
argses elements must be iterable with eager length-mismatch reporting,
non-dict Mapping kwargs (e.g. ChainMap) are coerced to dict, and an
unpicklable preexec_fn is detected before launch under spawn/forkserver.
- Resource leaks surfaced: Future.__del__ emits a ResourceWarning for an
abandoned future still holding a connection, and an orphaned future is
cleaned up when put() fails for any reason, including BaseException.
- API surface trimmed: MinimalQueue, resolve_context, and the
deadline/timeout helpers are removed from the public __all__, and
absolute_deadline/relative_timeout are renamed timeout_to_deadline/
deadline_to_timeout.
- Many documentation clarifications: Jobserver thread-safety contract,
picklability under spawn/forkserver, the shutdown(wait=False) caveat,
orphaned-worker risk, map() chunksize memory behavior, and
ignore_sigpipe scope.