{ "info": { "author": "Jason Moiron", "author_email": "jmoiron@jmoiron.net", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: POSIX" ], "description": "gaspar\n======\n\nGaspar is a library for creating small, simple TCP daemons that parallelize CPU\nintensive work with a simple and low-overhead request/response pattern.\n\nIt does this by forking off a number of worker processes, using eventlet to\nhandle incoming requests and the 0MQ push/pull message pattern to load\nballance work across the worker processes and receive responses.\n\n\nrunning servers\n---------------\n\nGaspar uses the terms ``producer`` and ``consumer`` for the process that receives\nincoming requests and the processes that actually handle those requests. In the\n0MQ documentation, these are called ``ventilator`` and ``sink``, and various\nother terms are used throughout distributed systems literature. To use Gaspar,\nyou need only to create a producer and a consumer, and then start the producer::\n\n >>> import gaspar\n >>> def echo(message): return message\n >>> consumer = gaspar.Consumer(handler=echo)\n >>> producer = gaspar.Producer(consumer, 10123)\n >>> producer.start()\n\nThe ``start`` call will block, and at this point you will have a server which is\nlistening on port ``10123``, receiving requests, sending them to a number of workers\n(default is the # of CPUs on your machine), and then replying based on the echo\nhandler.\n\n\nrequests\n--------\n\nGaspar's default Producer takes requests on a simple naked TCP port. These\nrequests are:\n\n * a 4-byte unsigned int in network-byte order (``struct.pack('!I', N)``)\n * a string of that length\n\nThe reply is simply a string followed by the termination of the socket. The\nconvenience function ``gaspar.client.request(\"host:port\", message)`` will send a\nrequest and return the reply synchronously. It uses the basic ``socket``\nlibraries, so you can \"green\" it safely with eventlet or gevent's monkey\npatching methods.\n\n``gaspar.client`` also provides a function called ``pack`` which takes a string\nand returns a new string with the 4-byte message length prepended. If you\nare using a gaspar daemon with async frameworks that are not greenlet based,\nyou can use this to cover that aspect of the client protocol.\n\nlimitations\n-----------\n\nformless request/response\n~~~~~~~~~~~~~~~~~~~~~~~~~\n\nGaspar requests and responses are just strings. There is no standard way to\nserialize multiple arguments or return multiple values. Because the nature of\nthe work being farmed out to such a daemon could be defeated by the wrong\ncalling semantics, these details are left to the ``Consumer`` implementation\nand to postprocessing client responses.\n\nsingle-server operation\n~~~~~~~~~~~~~~~~~~~~~~~\n\nAlthough the technologies in use (TCP and 0MQ) would allow for daemons to be\nspread across systems, this wasn't an original design goal of Gaspar and it\nis not currently supported.\n\n\nwhy shouldn't I use celery?\n---------------------------\n\nThe major \"advantages\" of Gaspar over Celery are its small size, conceptual\nsimplicity, and infrastructureless operation. The purpose of Gaspar was to\nmake it very easy to remove CPU bound processes from a tight event based I/O\nloop (like eventlet, gevent, tornado, et al), turn it into I/O wait, and\nspread that work across multiple cores.\n\nCelery serves a much broader range of purposes, is a lot more sophisticated,\nand has features like delayed and recurrent execution that Gaspar lacks. If\nyou have a number of assorted tasks you need to execute asynchronously, Celery\nis very good at this. If you have an asynchronous worker that has a few very\nCPU-intensive tasks that are blocking the event loop, Gaspar allows you to\nfarm that work out to daemons with very little code.", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "http://github.com/jmoiron/gaspar", "keywords": "eventlet zmq parallel prefork", "license": "MIT", "maintainer": null, "maintainer_email": null, "name": "gaspar", "package_url": "https://pypi.org/project/gaspar/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/gaspar/", "project_urls": { "Download": "UNKNOWN", "Homepage": "http://github.com/jmoiron/gaspar" }, "release_url": "https://pypi.org/project/gaspar/1.0/", "requires_dist": null, "requires_python": null, "summary": "gaspar eventlet zmq parallel worker", "version": "1.0" }, "last_serial": 792278, "releases": { "1.0": [ { "comment_text": "", "digests": { "md5": "5770d4b14cd45d6e1c07d6885708b43d", "sha256": "b12b2dbf6c5dd9288343085ef7f12c491fb9a7ec36a4f2674e033bbf03285f39" }, "downloads": -1, "filename": "gaspar-1.0.tar.gz", "has_sig": false, "md5_digest": "5770d4b14cd45d6e1c07d6885708b43d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7342, "upload_time": "2012-01-04T00:23:56", "url": "https://files.pythonhosted.org/packages/5d/85/a960c3c2e7d4fa127887cbbcb9f26fc4e8785ba5cdb5131a3f7260f6640b/gaspar-1.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "5770d4b14cd45d6e1c07d6885708b43d", "sha256": "b12b2dbf6c5dd9288343085ef7f12c491fb9a7ec36a4f2674e033bbf03285f39" }, "downloads": -1, "filename": "gaspar-1.0.tar.gz", "has_sig": false, "md5_digest": "5770d4b14cd45d6e1c07d6885708b43d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7342, "upload_time": "2012-01-04T00:23:56", "url": "https://files.pythonhosted.org/packages/5d/85/a960c3c2e7d4fa127887cbbcb9f26fc4e8785ba5cdb5131a3f7260f6640b/gaspar-1.0.tar.gz" } ] }