Skip to main content

procnexus

Provides tools for multiprocessing.

procnexus offers a tiny, explicit interface for collecting function calls and executing them concurrently with Python's multiprocessing.Pool or multiprocessing.pool.ThreadPool.

🛠️ Installation

$ pip install procnexus

✨ Features

  • Simple task submission (submit) API.
  • Batch execution with process or thread pools.
  • Asynchronous execution with start(), join(), and get()
  • Ordered results (same order as submitted tasks).
  • Lightweight wrapper around the standard library.
  • Optional thread-based execution for shared-memory or non-picklable callables.

🚀 Quick Start

from procnexus import nexus


def add(a: int, b: int) -> int:
    return a + b


job = nexus(add, processes=4)
job.submit(1, 2)
job.submit(10, 5)
job.submit(-1, 8)

results = job.run()
print(results)  # [3, 15, 7]

# Or start the work asynchronously and collect it later.
job = nexus(add, processes=4)
job.submit(1, 2)
job.submit(10, 5)
job.start()
# Do other work here, and optionally submit more tasks before joining.
job.submit(-1, 8)
job.join()
results = job.get()
print(results)  # [3, 15, 7]

# Use threads=... to run with threads instead of processes.
job = nexus(add, threads=4)
job.submit(1, 2)
job.submit(10, 5)
print(job.run())  # [3, 15]

🧩 API

nexus(func, processes=None, threads=None) -> ParallelNexus

Create a sequential runner by default, a process-backed runner with processes, or a thread-backed runner with threads.

  • func: target function for each task.
  • processes: process pool size setting.
    • < 0: use os.cpu_count().
    • 0 or None: normalize to None.
    • > 0: pass directly to multiprocessing.Pool.
  • threads: thread pool size setting.
    • < 0: use os.cpu_count().
    • 0 or None: normalize to None.
    • > 0: pass directly to multiprocessing.pool.ThreadPool.
  • After normalizing 0 to None, exactly one non-None setting selects process-backed or thread-backed execution, two non-None settings raise TypeError, and two None settings select sequential execution.

ParallelNexus

Runners created by nexus() are subinstances of ParallelNexus who share the same lifecycle and ordered result behavior. The default runner is sequential; passing processes uses process-based concurrency, while passing threads uses thread-based concurrency. Threads share memory with the parent process, so the submitted callable and arguments do not need to be picklable.

submit(*args, **kwargs) -> None

Queue one invocation of func. Before start(), the invocation is stored for later execution. After start() and before join(), the invocation is scheduled immediately and is included in the ordered get() result.

start() -> None

Start executing all queued tasks. Sequential runners compute immediately in the current process; process- and thread-backed runners start asynchronous execution.

join(timeout=None) -> None

Wait for a previously started run to finish. Results are stored on the runner instead of being returned directly. For pooled runs, timeout is passed to each task result wait; if it expires, unfinished work is stopped and multiprocessing.TimeoutError is raised.

get() -> list

Return results in submission order, including tasks submitted after start(). If the runner is still active, get() raises RuntimeError; call join() before retrieving results.

run() -> list

Execute all currently queued tasks in parallel and return results in submission order. This one-shot convenience method leaves the runner in the pending state and keeps submitted tasks queued, so it can be called repeatedly before start().

📝 Notes

  • For process runners, the submitted callable should be picklable by multiprocessing.
  • For process runners, arguments must also be serializable for inter-process communication.
  • Thread runners share memory and can run non-picklable callables, but Python thread scheduling still follows the normal GIL rules.
  • Exceptions from submitted tasks propagate when calling join() or run().

🔗 See Also

Github repository

PyPI project

⚖️ License

This project falls under the BSD 3-Clause License.

🕒 History

v0.0.4

  • Added thread-backed execution through ThreadNexus with shared-memory support for non-picklable callables and the same ordered lifecycle behavior as process-backed runs.
  • Changed nexus() selection so no worker option creates a sequential runner, while processes and threads explicitly select mutually exclusive pool-backed runners.
  • Refactored runner classes around the shared ParallelNexus lifecycle and renamed the in-process runner to SequentialNexus.

v0.0.3

  • Changed get() to reject calls while a nexus is still running, making join() the explicit synchronization point before result retrieval.
  • Added join(timeout=None) support for process-pool runs, terminating unfinished workers and propagating multiprocessing.TimeoutError when a task wait expires.

v0.0.2

  • Made run() a non-mutating convenience API to better align with Python conventions: it returns results without implicitly advancing the asynchronous start()/join() lifecycle or consuming queued tasks.
  • Updated process-pool run() execution to use multiprocessing.Pool.starmap, preserving ordered results and keyword-argument handling while keeping queued tasks available for a later async run.
  • Added unit coverage for repeated run() calls, process-pool execution, keyword arguments, and rejecting run() after start().

v0.0.1

  • Added asynchronous execution with start(), join(), and get(), while keeping run() as the one-shot convenience API.
  • Allowed submit() calls after start() and before join(), preserving submission-order results across queued and late-submitted tasks.
  • Expanded README/API documentation and added unit coverage for async lifecycle, ordered results, and invalid state transitions.

v0.0.0

  • Initial release.

Metadata

Release files for procnexus 0.0.4

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for procnexus 0.0.4
File Size Uploaded
procnexus-0.0.4.tar.gz 10.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for procnexus 0.0.4
File Interpreter ABI Platform
procnexus-0.0.4-py3-none-any.whl Python 3 none any Details

Total release size: 20.0 kB

Release files / procnexus-0.0.4.tar.gz

Download URL procnexus-0.0.4.tar.gz
Size 10.8 kB
Tags Source
SHA-256 checksum
How to use checksums
bde75cfdf2fd348f4d3043b4e7fc3fa63b7e12113ec9a5e053f4d2d5e14f9a3e
BLAKE2b-256 checksum
How to use checksums
ebd91cbb5ca53b31ce80709bc3f4f9c35140cbf9d3001c4435e7db2f7af6670f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.7

Release files / procnexus-0.0.4-py3-none-any.whl

Download URL procnexus-0.0.4-py3-none-any.whl
Size 9.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e2f38343172486d7c07683a4bc676ccb81970357d16fac17d6dd041d6a817c61
BLAKE2b-256 checksum
How to use checksums
a358c032cab232fe710121b2cca6256629f7fb2753daf94467199966832e8970
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.7

Release history Release notifications | RSS feed

This release

0.0.4 This release

2 release files

0.0.3

2 release files

0.0.2

2 release files

0.0.1

2 release files

0.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page