Skip to main content

ZProc - Process on steroids

Project description

ZProc - Process on steroids

Multi-Tasking how it should've been.

ZProc logo

To make utterly perfect MT programs (and I mean that literally), we don't need mutexes, locks, or any other form of inter-thread communication except messages sent across ZeroMQ sockets.

P.S. ZProc is short for Zero Process

Behold, the power of ZProc:

from time import sleep

import zproc

ctx = zproc.Context(background=True)
ctx.state['cookies'] = 0


def eat_cookie(state):
    state['cookies'] -= 1


def make_cookie(state):
    state['cookies'] += 1


@ctx.call_when_change('cookies')
def cookie_eater(state):
    state.task(eat_cookie)
    print('child: nom nom nom')


sleep(0.5)  # wait for the process to stabilize
print(cookie_eater.pid)  # The "Process" pid.

for i in range(5):
    ctx.state.task(make_cookie)
    print('main: I made a cookie!')

Install

pip install zproc

License: MIT License (MIT)
Requires: Python >=3.5

Documentation ( Documentation Status )

Read the docs

Examples

Backstory

Traditional Multi Processing was mostly, built on the principle of shared memory. This might sound odd, but shared memory violates the laws of Physics itself.
Don't believe me? watch this (from Joe Armstrong, the creator of Erlang)

The solution presented by Erlang, (and ZMQ) is the notion of message passing for achieving parallelism, or at least concurrency.
Yes, they are different things.

However, Message passing can be tedious, and often un-pythonic. This is where ZProc comes in.

It provides a middle ground between message passing and shared memory.

It does message passing, without you ever knowing that it's doing it.

It borrows the concept of state and props from reactJS.

Hence, provides you a global dict which we like to call state.
Each Process can also be supplied with some props that make processes re-usable.

The state is not a shared object. It works purely on message passing.

Unlike reactJS, you are free to mutate the state and ZProc won't sweat.

If you're a CS majaor, you might recognize this as the Actor Model.
ZProc doesn't blindly follow it, but you can think of it as such.

It also borrows the autoretry feature of Celery, but unlike Celery it doesn't need a broker.

The zen of zero

The Ø in ØMQ is all about trade-offs. On the one hand, this strange name lowers ØMQ’s visibility on Google and Twitter. On the other hand, it annoys the heck out of some Danish folk who write us things like “ØMG røtfl”, and “Ø is not a funny-looking zero!” and “Rødgrød med Fløde!” (which is apparently an insult that means “May your neighbours be the direct descendants of Grendel!”). Seems like a fair trade.

Originally, the zero in ØMQ was meant to signify “zero broker” and (as close to) “zero latency” (as possible). Since then, it has come to encompass different goals: zero administration, zero cost, zero waste. More generally, “zero” refers to the culture of minimalism that permeates the project. We add power by removing complexity rather than by exposing new functionality.

Features

  • 🌠   Global State w/o shared memory

    • Globally synchronized state (dict), without using shared memory.
    • 🔖
  • 🌠   Asynchronous paradigms without async def

    • Build any combination of synchronous and asynchronous systems.
    • watch for changes in state, without Busy Waiting.
    • 🔖
  • 🌠   Process management

    • Process Factory
    • Remembers to kill processes when exiting, for general peace. (even when they're nested)
    • Keeps a record of processes created using ZProc.
    • 🔖
  • 🌠   Atomic Operations

    • Perform an arbitrary number of operations on state as a single, atomic operation.
    • 🔖

Caveats

  • The state only gets updated if you do it directly.
    This means that if you mutate objects inside the state, they wont get updated in global state.
  • The state should be pickle-able
  • It runs an extra Process for managing the state.
    Its fairly lightweight though, and shouldn't add too much weight to your application.

FAQ

  • Fast?

    • plenty, since its written with ZMQ.
    • Click -> 🔖 for a taste.
  • Stable?

    • The code itself is stable, but the API is quite unstable.
  • Production ready?

    • Please don't use it in production right now.
  • Real?

    • YES. It works.
    • 🔖
  • Windows compatible?

    • Probably?

Inner Workings

  • The process(s) communicate over zmq sockets, over ipc://.

    • The clients (Proceses) use a ZMQ_DEALER socket.
    • The zproc server uses a ZMQ_ROUTER socket.
  • Zproc runs a zproc server, which is responsible for storing and managing the state.

    • updates the state whenever a Process wishes to update it.
    • transmitts the state whenever a Process needs to access it.
    • The zproc server helps create an illusion of a global shared state when actually, it isn't shared at all!
  • If a Process wishes to watch the state, it subscribes to a global publish message.

    • The zproc server publishes the state at every state update. (using ZMQ_PUB socket)
    • A Process may subscribe to this message and filter out the event it needs (using ZMQ_SUB socket).
    • zmq sockets block your application efficiently till an update occurs, eliminating the need for Busy Waiting.
    • (Earlier, we used a centralized approach, but this new, distributed approach is much more efficient)

(Busy waiting refers to the while True: "check condition" approach).

Local development

git clone https://github.com/pycampers/zproc.git
cd zproc
pipenv install

Build documentation

Assuming you have sphinx installed (Linux)

cd docs
pipenv run ./build.sh

Thanks

  • Thanks to pieter hintjens, for his work on the ZeroMQ library and for his amazing book.
  • Thanks to tblib, ZProc can raise First-class Exceptions from the zproc server!
  • Thanks to psutil, ZProc can handle nested procesess!
  • Thanks to Kennith Rietz. His setup.py was used to host this project on pypi. Plus lot of documentation is blatantly copied from his documentation on requests

Buy Me A Coffee

🐍🏕️

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

zproc-0.3.6.tar.gz (14.8 kB view details)

Uploaded Source

Built Distribution

zproc-0.3.6-py2.py3-none-any.whl (24.5 kB view details)

Uploaded Python 2 Python 3

File details

Details for the file zproc-0.3.6.tar.gz.

File metadata

  • Download URL: zproc-0.3.6.tar.gz
  • Upload date:
  • Size: 14.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No

File hashes

Hashes for zproc-0.3.6.tar.gz
Algorithm Hash digest
SHA256 16823d06ef9f0cc129a243a80865173be373f9438032eb81e07c1592c4122a2c
MD5 de02f5459a760c25a4e5f970499eacb0
BLAKE2b-256 6c6f45b723a2abfe1f850d5e3134d974bde643a777a1a5b9db7be705916057ec

See more details on using hashes here.

File details

Details for the file zproc-0.3.6-py2.py3-none-any.whl.

File metadata

File hashes

Hashes for zproc-0.3.6-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 b42d9e6544cf0b06bdebdc5b475be7cd6d61ef5d69feb9888ae36ed636b35c6f
MD5 891f45cfc1034963fe4639a9cadacf38
BLAKE2b-256 a27344bc1051e3812771e2938318559c6f3f3484d2625116c496864696d2e264

See more details on using hashes here.

Supported by

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