{ "info": { "author": "Shahar Evron", "author_email": "shahar@shoppimon.com", "bugtrack_url": null, "classifiers": [], "description": "Majortomo\n=========\n*Majortomo* is a pure-Python [ZeroMQ MDP 0.2](https://rfc.zeromq.org/spec:18/MDP/)\n(\"Majordomo\") implementation. It provides a ready-to-use MDP Service Broker,\nas well as a Python 2.7 / 3.5+ library for implementing MDP clients and workers\nwith just a few lines of code. \n\nMDP / Majordomo is a protocol for implementing a highly scalable, lightweight \nservice oriented messaging on top of [ZeroMQ](https://zeromq.org). It is very \nuseful, for example, for facilitating communication between different\nmicro-services in a scalable, robust and fault-tolerant manner. \n\n[![Build Status](https://travis-ci.org/shoppimon/majortomo.svg?branch=master)](https://travis-ci.org/shoppimon/majortomo)\n[![Documentation Status](https://readthedocs.org/projects/majortomo/badge/?version=latest)](https://majortomo.readthedocs.io/en/latest/?badge=latest)\n\nInstallation\n------------\n\nQuick Start\n-----------\n\n### Running the Broker\n\n### Exposing a Service using an MDP Worker\n\n### Consuming a Service using an MDP Client\n\nFull Documentation\n------------------\nProject documentation is available here: https://majortomo.readthedocs.io/en/latest/\n\nUsage\n-----\n### Running the Broker\nIn most cases the MDP broker can be used as-is, simply by running it with the \nright command line arguments. You can do this by building and running it using \nDocker:\n\n # Build the Docker image\n $ docker build -t shoppimon/mdp-broker -f mdp-broker/Dockerfile .\n\n # Run the broker from Docker\n $ docker run --rm -ti shoppimon/mdp-broker -b tcp://0.0.0.0:5555 --verbose\n\nYou can run the broker with `--help` for more command line options. \n\nOf course, you can also run the broker directly using Python 3.5 and up:\n\n $ python -m majortomo.broker --help\n\nNote that this requires setting up a virtual environemnt with the project \ndependencies, which is described below. \n\n### Installing & Using the Client and Worker modules\nTBD\n\n### Using the Client class\nSee `majortomo.echo` for a sample client implementation.\n\nThe `Client` class should normally be used directly (without subclassing) to\nsend requests to the broker (and workers). \n\n##### Opening and closing client connections\nWhile a lower-level API is available (through the `connect`, `is_connected`, \nand `close`), managing the connection to the broker is easiest done through\nthe context manager protocol:\n\n```python\nwith Client(broker_url='tcp://127.0.0.1:5555') as client:\n client.send(b'my-service', b'frame1', b'frame2')\n reply = client.recv_all_as_list(timeout=10.0)\n```\n\nThe example above takes care of opening and closing the ZeroMQ socket as \nneeded.\n\n**NOTE**: ZeroMQ takes care of re-creating dropped TCP connections and waiting\nfor not-yet-bound peers automatically. \n\n##### Sending Requests & Receiving Replies\nTo send a request, use the `send` method:\n\n```python\nclient.send(service_name, frame1, frame2, frame3)\n```\n\nThis method takes the service name (as `bytes`) as a first argument. \nAll other arguments are sent as message frames - the MDP protocol supports\nsending requests with more than one frame to the broker. The contents of these\nframes is application dependent and is up to you.\n\nOnce a request has been sent, you *must* read the entire reply send back from\nthe broker (or close the connection to the broker and reconnect if you wish\nto retry). \n\nThere are multiple methods for reading replies, depending on your needs: \n\n**`recv_part(timeout: float=None) -> Optional[List[bytes]]`**\n\nReceive one reply part from the broker (a reply part is a list of bytes, as it\nmay contain multiple ZeroMQ frames). \n\nIf no more parts are available (i.e. the last part was a `FINAL` reply), will\nreturn `None`.\n\n**`recv_all(timeout: float=None) -> Iterable[List[bytes]]`**\n\nReturns an iterator that yields each message part as it is received, and exists\nafter the `FINAL` reply has been received:\n\n```python\nfor part in client.recv_all(timeout=5.0): \n do_something_with_reply_part(part)\n```\n\n**Note**: the `timeout` parameter in this case relates to the time between reply\nchunks, not to the time it would take to receive the entire reply until `FINAL`. \n\n**`recv_all_as_list(timeout: float=None) -> List[bytes]`**\n\nReturns a flat list of all message frames from all reply parts. Regardless of \nhow many `PARTIAL` replies were sent by the worker until the `FINAL` reply, \nthis method will always return a single one-dimentional list of `bytes` with\nmessage frames.\n\n##### Timeouts & Retrying\nAll `recv_*` methods of the client receive a `timeout` argument which should\nspecify the number of seconds to wait for a response (a `float` is expected \nso you can specify second fractions as well). If no `timeout` is specified, \nthe function will wait forever. \n\nOnce `recv_*` times out, a `majortomo.error.Timeout` will\nbe raised. It is sometimes useful to catch this exception and retry the \noperation after reconnecting to the broker:\n\n```python\nwhile True:\n with Client(broker_url='tcp://127.0.0.1:5555') as client:\n try:\n\n client.send(b'my-service', b'frame1', b'frame2')\n reply = client.recv_all_as_list(timeout=10.0)\n break\n except majortomo.error.Timeout:\n logging.warning(\"Timed out waiting for a reply from broker, reconnecting\")\n time.sleep(1.0)\n continue\n```\n\nOr, if you do not wish to rely on the context manager for reconnecting (e.g. if\nthe context is managed in an outer scope):\n\n```python\n# Here `client` is passed from an outer scope\nwhile True:\n try:\n client.send(b'my-service', b'frame1', b'frame2')\n reply = client.recv_all_as_list(timeout=10.0)\n break\n except majortomo.error.Timeout:\n logging.warning(\"Timed out waiting for a reply from broker, reconnecting\")\n time.sleep(1.0)\n client.connect(reconnect=True)\n continue\n```\n\nEven better, it is advisable to manage the number of retries and the `sleep` time\nbetween them using some kind of exponential backoff & retry library, for example\n[backoff](https://pypi.org/project/backoff/) or [redo](https://pypi.org/project/redo)\n\n#### Implementing MDP Workers\nSee `majortomo.echo` for a sample worker implementation\n\nMore details TBD\n\nCopyright & Credits\n-------------------\nMajortomo was created and is maintained by the [Shoppimon](https://www.shoppimon.com) \nteam, and is distributed under the terms of the Apache 2.0 License \n(see `LICENSE`).\n\nMajortomo is (C) Copyright 2018 Shoppimon LTD. \n\n\u00d8MQ is Copyright (c) 2007-2014 iMatix Corporation and Contributors.\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/shoppimon/majortomo", "keywords": "", "license": "", "maintainer": "", "maintainer_email": "", "name": "majortomo", "package_url": "https://pypi.org/project/majortomo/", "platform": "", "project_url": "https://pypi.org/project/majortomo/", "project_urls": { "Homepage": "https://github.com/shoppimon/majortomo" }, "release_url": "https://pypi.org/project/majortomo/0.1.0/", "requires_dist": [ "figcan", "pyyaml", "pyzmq", "typing ; python_version < \"3.0\"" ], "requires_python": "", "summary": "Majortomo - ZMQ MDP 0.2 (Majordomo) Python Implementation", "version": "0.1.0" }, "last_serial": 4576840, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "6e39d0fbd3f4d7c8132f8324b6cfc5a1", "sha256": "d698567058b82de3a9e80dca01a6b1bdaf9d662833b554fbd6031a234f019f94" }, "downloads": -1, "filename": "majortomo-0.1.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "6e39d0fbd3f4d7c8132f8324b6cfc5a1", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 24385, "upload_time": "2018-12-09T07:17:01", "url": "https://files.pythonhosted.org/packages/8c/41/f8f19bea25bd9752f19c1ef403dc9d941aa25958057cb98b8192d666035b/majortomo-0.1.0-py2.py3-none-any.whl" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "6e39d0fbd3f4d7c8132f8324b6cfc5a1", "sha256": "d698567058b82de3a9e80dca01a6b1bdaf9d662833b554fbd6031a234f019f94" }, "downloads": -1, "filename": "majortomo-0.1.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "6e39d0fbd3f4d7c8132f8324b6cfc5a1", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 24385, "upload_time": "2018-12-09T07:17:01", "url": "https://files.pythonhosted.org/packages/8c/41/f8f19bea25bd9752f19c1ef403dc9d941aa25958057cb98b8192d666035b/majortomo-0.1.0-py2.py3-none-any.whl" } ] }