{ "info": { "author": "Madison May", "author_email": "madison.may@students.olin.edu", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta" ], "description": "What is semisync.py?\r\n--------------------\r\n\r\nSome problems are best solved synchronously, while others are a better\r\nfit for the asynchronous paradigm. Most problems fall somewhere in\r\nbetween -- they could benefit from asynchronous execution, but require\r\nsome events to happen in a certain order. This module seeks to make\r\nblending the two paradigms a bit easier by introducing a concept of\r\ndependencies. If one process must not run until another process has\r\ncompleted, that process is said to be \"dependent\" on the second process.\r\nSemisync.py was built using python's multiprocessing library and a\r\nliberal dose of decorator syntax.\r\n\r\nInstallation\r\n------------\r\n\r\nInstall via pip\r\n\r\n::\r\n\r\n sudo pip install semisync\r\n\r\nor via setup.py\r\n\r\n::\r\n\r\n sudo python setup.py install\r\n\r\nLet's See Some Code\r\n-------------------\r\n\r\n::\r\n\r\n from semisync import semisync\r\n from multiprocessing import Manager\r\n from random import random, randint\r\n from time import sleep\r\n\r\n # shared data between processes\r\n shared = Manager().Namespace()\r\n\r\n # a demo callback function\r\n def output(field, value):\r\n print field + \": $\" + str(value)\r\n\r\n # simple callback syntax\r\n @semisync(callback=output)\r\n def revenue():\r\n # simulated api call\r\n sleep(random())\r\n shared.revenue = randint(1, 1000)\r\n return \"Revenue\", shared.revenue\r\n\r\n @semisync(callback=output)\r\n def expenses():\r\n # simulated api call\r\n sleep(random())\r\n shared.expenses = randint(1, 500)\r\n return \"Expenses\", shared.expenses\r\n\r\n # will run only when revenue() and expenses() have completed\r\n @semisync(callback=output, dependencies=[revenue, expenses])\r\n def profit():\r\n shared.profit = shared.revenue - shared.expenses\r\n return \"Profit\", shared.profit\r\n\r\n # queue function calls\r\n revenue()\r\n expenses()\r\n profit()\r\n\r\n # executes queued calls semi-synchronously\r\n semisync.begin()\r\n\r\nTo repeat the process, simply clear the cache of function calls by using\r\nsemisync.clear() after each iteration\r\n\r\n::\r\n\r\n for i in range(10):\r\n revenue()\r\n expenses()\r\n profit()\r\n semisync.begin()\r\n semisync.clear()\r\n\r\nIn this simple example, moving from synchronous to semi-synchronous\r\nexecution cuts the average execution time from 1.00 seconds to .700\r\nseconds. And although the example used is trivial, dependency trees can\r\nbe arbitrarily complex.\r\n\r\nAdditional Notes\r\n----------------\r\n\r\nIn order to make the module more flexible, few assumptions are made\r\nabout how you choose to deal with shared data. Although Manager() from\r\nthe multiprocessing library is used in the example, you're free to use\r\nwhatever format you desire. You're also in charge of locking shared data\r\nif multiple processes access the same variable. With great flexibility\r\ncomes great responsibility.", "description_content_type": null, "docs_url": null, "download_url": "https://github.com/madisonmay/Semisync", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/madisonmay/SemiSync", "keywords": "async, asynchronous, decorator, callback, process", "license": "MIT", "maintainer": "Madison May", "maintainer_email": "madison.may@students.olin.edu", "name": "semisync", "package_url": "https://pypi.org/project/semisync/", "platform": "", "project_url": "https://pypi.org/project/semisync/", "project_urls": { "Download": "https://github.com/madisonmay/Semisync", "Homepage": "https://github.com/madisonmay/SemiSync" }, "release_url": "https://pypi.org/project/semisync/0.1/", "requires_dist": null, "requires_python": null, "summary": "A decorator-based module for semi-synchronous programming", "version": "0.1" }, "last_serial": 956165, "releases": { "0.1": [ { "comment_text": "", "digests": { "md5": "ccc4d3b84565cf737a4ccc2b601532c3", "sha256": "fd0f726790637eb56fd7f2513202d41ac3e362887aecec577310f82c1d6918fa" }, "downloads": -1, "filename": "semisync-0.1.tar.gz", "has_sig": false, "md5_digest": "ccc4d3b84565cf737a4ccc2b601532c3", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 1836, "upload_time": "2013-12-29T04:19:44", "url": "https://files.pythonhosted.org/packages/99/09/f0237ff501754852f8188359580be4527fdeaf0cdc55e3ed1a6e2623a364/semisync-0.1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "ccc4d3b84565cf737a4ccc2b601532c3", "sha256": "fd0f726790637eb56fd7f2513202d41ac3e362887aecec577310f82c1d6918fa" }, "downloads": -1, "filename": "semisync-0.1.tar.gz", "has_sig": false, "md5_digest": "ccc4d3b84565cf737a4ccc2b601532c3", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 1836, "upload_time": "2013-12-29T04:19:44", "url": "https://files.pythonhosted.org/packages/99/09/f0237ff501754852f8188359580be4527fdeaf0cdc55e3ed1a6e2623a364/semisync-0.1.tar.gz" } ] }