Package: zproc
ZProc is a thought experiment, in making multi-tasking easier and accessible to everyone.It focuses on automating various tasks related to message passing systems, for pythonistas.
The eventual goal is to make Python a first-class language for doing multi-tasking.So thatyoudon't have to think about arcane details,
like request-reply loops, reliable pub-sub, worker management, task distributiom, exception propagation, that kind of thing...Behold, the power of ZProc:importzproc## define "atomic" operations#@zproc.atomicdefeat_cookie(snapshot):snapshot["cookies"]-=1print("nom nom nom")@zproc.atomicdefbake_cookie(snapshot):snapshot["cookies"]+=1print("Here's a cookie!")## specify a process#defcookie_eater(ctx):state=ctx.create_state({'ready':True})# `start_time=0` accesses events from the very beginning.for_instate.get_when_change("cookies",start_time=0,count=5):eat_cookie(state)# boilerplatectx=zproc.Context(wait=True)state=ctx.create_state({"cookies":0})# create a "ready" handleready=state.get_when_available("ready")# spwan the processproc=ctx.spawn(cookie_eater)print(proc)# wait for readynext(ready)# finally, bake some cookies.for_inrange(5):bake_cookie(state)Result:Process - pid: 10815 target: '__main__.cookie_eater' ppid: 10802 is_alive: True exitcode: None
Here's a cookie!
Here's a cookie!
nom nom nom
Here's a cookie!
nom nom nom
Here's a cookie!
nom nom nom
Here's a cookie!
nom nom nom
nom nom nomThe framework does message passing for you.Thestate.get_when_change()iterator supplies thecookie_eaterprocess with events asynchronously, as the state is updated.The core ideaMessage passing is cumbersome, error prone, and tedius --
because there is a lot of manual wiring involved.The idea behind this project is to provide a pythonic API over widely accepted models in the message passing realm.It started out withembracingshared state (but not shared memory).Shared memory is frowned upon by almost everyone, due to the fact that memory is inherently dumb.
Memory doesn't really care who's writing to it.Shared state brings it's own perils, because its really hard to keep track of changes.With the aid of the Actor Model, ZProc's state keeps a track of who's doing what.
So much so, that it can act as a time-machine and give you state events from any defined time.It then evolved to do handle exceptions across processes, failover, worker swarms, event sourcing,
and other very useful features realated to multi-tasking.The underlying architecture 100% message passing based,
and hence scalable across many computers,
with minimal modifications to the user code.Well why not just X?Each technology solution has it's place. Here is a rundown of why you would use ZProc over X.X == asyncioIt's kinda in the name. Asyncio is strictly for I/O based concurrency.
And then there's the fact that it implies extreme levels of refactoring.To quote Joe Armstrong,I want one way to program computers, not many.Install$ pip install zprocMIT LicensePython 3.5+DocumentationRead the docsExamplesWishlistHere are some of the ideas that I wish were implemented in ZProc, but currently aren't.Redundant state-servers -- automatic selection/fallback.Green, Erlang-style processes. (requires Cpython internals)Processlinks, that automatically propagate errors across processes.Make namespaces horizontally scalable.Features🌠   Process managementRemembers to cleanup processes when exiting, for general peace. (even when they're nested)Keeps a record of processes created using ZProc.🔖[ZProc] Cleaning up 'python' (13652)...🌠   Worker/Process MapsAutomatically manages worker processes, and delegates tasks to them.🔖🌠Communicating sequential processes, at the core.No need for manual message passing.Watchfor changes in state, withoutbusy waiting.🔖.Deterministic state updates.Ships with a event messaging system that doesn't rely on flaky PUB/SUB.Go back in time, with aTimeMachine!.Distributed, by default.Scalable to multiple computers, with minimal refactoring.🌠   Atomic OperationsPerform an arbitrary number of operations on state as a single, atomic operation.🔖🌠 Detailed, humane error logging for Proceeses.[ZProc] Crash report:
  target: '__main__.p1'
  pid: 8959
  ppid: 8944

  Traceback (most recent call last):
    File "/home/dev/Projects/zproc/zproc/child.py", line 88, in main
      **self.target_kwargs
    File "/home/dev/Projects/zproc/zproc/child.py", line 65, in target_wrapper
      return self.target(*args, **kwargs)
    File "test.py", line 12, in p1
      raise ValueError
  ValueErrorCaveatsThe state only gets updated if you do it at the highest level.This means that if you mutate objects deep down in the dict hirearchy,
they wont be reflected in the global state.The state should be pickle-able.It runs an extra Processes for managing the state.They're fairly lightweight though, and shouldn't add too
much weight to your application.FAQFast?Above all, ZProc is written for safety and the ease of use.However, since its written using ZMQ, it's plenty fast for most stuff.Stable?Mostly. However, since it's still in its development stage, you should expect some API changes.Production ready?Please don't use it in production right now.Windows compatible?Probably?Local development# get the code
git clone https://github.com/pycampers/zproc.git

# install dependencies
cd zproc
pipenv install
pipenv install -d

# activate virtualenv
pipenv shell

# install zproc, and run tests
pip install -e .
pytestBuild documentationcd docs
./build.sh 

# open docs
google-chrome _build/index.html 

# start a build loop
./build.sh loopZProc in the wildOscilloscopeMuroThanksThanks toopen logosfor providing the wonderful ZProc logo.Thanks topieter hintjens,
for his work on theZeroMQlibrary
and for hisamazing book.Thanks totblib,
ZProc can raise First-class Exceptions from the zproc server!Thanks topsutil,
ZProc can handle nested procesess!Thanks to Kennith Rietz.
His setup.py was used to host this project on pypi.
Plus a lot of documentation structure is blatantly copied
from his documentation on requestsZProc is short forZeroProcess.🐍🏕️