GithubHelp home page GithubHelp logo

zmqless / python-zeroless Goto Github PK

View Code? Open in Web Editor NEW
141.0 12.0 13.0 112 KB

ZeroMQ for Pythonistas™

Home Page: http://python-zeroless.readthedocs.io

License: GNU Lesser General Public License v2.1

Python 100.00%
zeromq zmq zeroless sockets networking python

python-zeroless's Introduction

Zeroless

Build Status Coverage Status Codacy PyPi Docs License

Yet another ØMQ wrapper for Python. However, differing from PyZMQ, which tries to stay very close to the C++ implementation, this project aims to make distributed systems employing ØMQ as pythonic as possible.

Being simpler to use, Zeroless doesn't supports all of the fine aspects and features of ØMQ. However, you can expect to find all the message passing patterns you were accustomed to (i.e. pair, request/reply, publisher/subscriber, push/pull). Despite that, the only transport available is TCP, as threads are not as efficient in Python due to the GIL and IPC is unix-only.

Installation

$ pip install zeroless

Python API

In the zeroless module, two classes can be used to define how distributed entities are related (i.e. Server and Client). To put it bluntly, with the exception of the pair pattern, a client may be connected to multiple servers, while a server may accept incoming connections from multiple clients.

Both servers and clients are able to create a callable and/or iterable, depending on the message passing pattern. So that you can iterate over incoming messages and/or call to transmit a message.

All examples assume:

from zeroless import (Server, Client)

Push-Pull

Useful for distributing the workload among a set of workers. A common pattern in the Stream Processing field, being the cornestone of applications like Apache Storm for instance. Also, it can be seen as a generalisation of the Map-Reduce pattern.

# Binds the pull server to port 12345
# And assigns an iterable to wait for incoming messages
listen_for_push = Server(port=12345).pull()

for msg in listen_for_push:
    print(msg)
# Connects the client to as many servers as desired
client = Client()
client.connect_local(port=12345)

# Initiate a push client
# And assigns a callable to push messages
push = client.push()

for msg in [b"Msg1", b"Msg2", b"Msg3"]:
    push(msg)

Publisher-Subscriber

Useful for broadcasting messages to a set of peers. A common pattern for allowing real-time notifications at the client side, without having to resort to inneficient approaches like pooling. Online services like PubNub or IoT protocols like MQTT are examples of this pattern usage.

# Binds the publisher server to port 12345
# And assigns a callable to publish messages with the topic 'sh'
pub = Server(port=12345).pub(topic=b'sh', embed_topic=True)

# Gives publisher some time to get initial subscriptions
sleep(1)

for msg in [b"Msg1", b"Msg2", b"Msg3"]:
    pub(msg)
# Connects the client to as many servers as desired
client = Client()
client.connect_local(port=12345)

# Initiate a subscriber client
# Assigns an iterable to wait for incoming messages with the topic 'sh'
listen_for_pub = client.sub(topics=[b'sh'])

for topic, msg in listen_for_pub:
    print(topic, ' - ', msg)

Note: ZMQ's topic filtering capabilities are publisher side since ZMQ 3.0.

Last but not least, SUB sockets that bind will not get any message before they first ask for via the provided generator, so prefer to bind PUB sockets if missing some messages is not an option.

Request-Reply

Useful for RPC style calls. A common pattern for clients to request data and receive a response associated with the request. The HTTP protocol is well-known for adopting this pattern, being it essential for Restful services.

# Binds the reply server to port 12345
# And assigns a callable and an iterable
# To both transmit and wait for incoming messages
reply, listen_for_request = Server(port=12345).reply()

for msg in listen_for_request:
    print(msg)
    reply(msg)
# Connects the client to as many servers as desired
client = Client()
client.connect_local(port=12345)

# Initiate a request client
# And assigns a callable and an iterable
# To both transmit and wait for incoming messages
request, listen_for_reply = client.request()

for msg in [b"Msg1", b"Msg2", b"Msg3"]:
    request(msg)
    response = next(listen_for_reply)
    print(response)

Pair

More often than not, this pattern will be unnecessary, as the above ones or the mix of them suffices most use cases in distributed computing. Regarding its capabilities, this pattern is the most similar alternative to usual posix sockets among the aforementioned patterns. Therefore, expect one-to-one and bidirectional communication.

# Binds the pair server to port 12345
# And assigns a callable and an iterable
# To both transmit and wait for incoming messages
pair, listen_for_pair = Server(port=12345).pair()

for msg in listen_for_pair:
    print(msg)
    pair(msg)
# Connects the client to a single server
client = Client()
client.connect_local(port=12345)

# Initiate a pair client
# And assigns a callable and an iterable
# To both transmit and wait for incoming messages
pair, listen_for_pair = client.pair()

for msg in [b"Msg1", b"Msg2", b"Msg3"]:
    pair(msg)
    response = next(listen_for_pair)
    print(response)

Logging

The zeroless module allows logging via a global Logger object.

from zeroless import log

To enable it, just add an Handler object and set an appropriate logging level.

Testing

To run individual tests:

$ py.test tests/test_desired_module.py

To run all the tests:

$ python setup.py test

Alternatively, you can use tox:

$ tox

Need help?

For more information, please see our documentation.

License

Copyright 2014 Lucas Lira Gomes [email protected]

This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with this library. If not, see http://www.gnu.org/licenses/.

python-zeroless's People

Contributors

vaibhavsagar avatar x8lucas8x avatar xdmiodz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

python-zeroless's Issues

Recover / Reconnect / Restart Server

Hi there,
First of all let me say thanks a lot
I've been using this library for a few years and i love it for the most part

The only thing is that I cant seem to recover from errors
If something has happened during the client/server conversation
I have to restart all of the Servers and all of the Clients

 ::: NEW QUERY REQUEST ON ROUTER SERVER PIPELINE: Local RID: 6 ::: Query: tell a joke :::
Traceback (most recent call last):
  File "/Users/magic/wholesomegarden/magicllight/magicllight/core/airouter/pipelines/xo_benedict/freshServer.py", line 69, in listen
    for payload in listen_for_request:
  File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/zeroless/zeroless.py", line 60, in _recv
    frames = sock.recv_multipart()
             ^^^^^^^^^^^^^^^^^^^^^
  File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/zmq/sugar/socket.py", line 806, in recv_multipart
    parts = [self.recv(flags, copy=copy, track=track)]
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "_zmq.py", line 1137, in zmq.backend.cython._zmq.Socket.recv
  File "_zmq.py", line 1172, in zmq.backend.cython._zmq.Socket.recv
  File "_zmq.py", line 1264, in zmq.backend.cython._zmq._recv_copy
  File "_zmq.py", line 1259, in zmq.backend.cython._zmq._recv_copy
  File "_zmq.py", line 160, in zmq.backend.cython._zmq._check_rc
zmq.error.ZMQError: Operation cannot be accomplished in current state
.............. server crashed, needs recovering.........

but no matter what i do, i cant seem to recover [ALL CLIENTS AND SERVERS MUST DIE TO RESTART]
I want a simple recovery without closing everything

Again this library is amazing,
But the server/clients connections must be more robust, and auto handle reconnecting

Please let me know what you think, and how we can solve this
Thanks a lot and all the best!

No way to start/stop Server

The server just starts on construction so there is no way to stop the server once it is started. It would be good to add start(), stop() methods and may be a flag in constructor auto_start which if true then server gets started in construction.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.