Skip to main content

Provides tools for multiprocessing.

Project description

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.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

procnexus-0.0.4.tar.gz (10.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

procnexus-0.0.4-py3-none-any.whl (9.2 kB view details)

Uploaded Python 3

File details

Details for the file procnexus-0.0.4.tar.gz.

File metadata

  • Download URL: procnexus-0.0.4.tar.gz
  • Upload date:
  • Size: 10.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.7

File hashes

Hashes for procnexus-0.0.4.tar.gz
Algorithm Hash digest
SHA256 bde75cfdf2fd348f4d3043b4e7fc3fa63b7e12113ec9a5e053f4d2d5e14f9a3e
MD5 39c3e70b400dbd0a6210339a3d8c3d70
BLAKE2b-256 ebd91cbb5ca53b31ce80709bc3f4f9c35140cbf9d3001c4435e7db2f7af6670f

See more details on using hashes here.

File details

Details for the file procnexus-0.0.4-py3-none-any.whl.

File metadata

  • Download URL: procnexus-0.0.4-py3-none-any.whl
  • Upload date:
  • Size: 9.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.7

File hashes

Hashes for procnexus-0.0.4-py3-none-any.whl
Algorithm Hash digest
SHA256 e2f38343172486d7c07683a4bc676ccb81970357d16fac17d6dd041d6a817c61
MD5 c4d0e23695723f5833dd33a0ed2226cf
BLAKE2b-256 a358c032cab232fe710121b2cca6256629f7fb2753daf94467199966832e8970

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page