{ "info": { "author": "Cameron Simpson", "author_email": "cs@cskk.id.au", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", "License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": "*Latest release 20191007*:\nDrop pipeline functionality, moved to new cs.pipeline module.\n\nQueue functions for execution later in priority and time order.\n\nI use `Later` objects for convenient queuing of functions whose\nexecution occurs later in a priority order with capacity constraints.\n\nWhy not futures?\nI already had this before futures came out,\nI prefer its naming scheme and interface,\nand futures did not then support prioritised execution.\n\nUse is simple enough: create a `Later` instance and typically queue\nfunctions with the `.defer()` method::\n\n L = Later(4) # a Later with a parallelism of 4\n ...\n LF = L.defer(func, *args, **kwargs)\n ...\n x = LF() # collect result\n\nThe `.defer` method and its siblings return a `LateFunction`,\nwhich is a subclass of `cs.result.Result`.\nAs such it is a callable,\nso to collect the result you just call the `LateFunction`.\n\n## Function `defer(func, *a, **kw)`\n\nQueue a function using the current default Later.\nReturn the LateFunction.\n\n## Class `LateFunction`\n\nMRO: `cs.result.Result` \nState information about a pending function,\na subclass of `cs.result.Result`.\n\nA `LateFunction` is callable,\nso a synchronous call can be done like this:\n\n def func():\n return 3\n L = Later(4)\n LF = L.defer(func)\n x = LF()\n print(x) # prints 3\n\nUsed this way, if the called function raises an exception it is visible:\n\n LF = L.defer()\n try:\n x = LF()\n except SomeException as e:\n # handle the exception ...\n\nTo avoid handling exceptions with try/except the .wait()\nmethod should be used:\n\n LF = L.defer()\n x, exc_info = LF.wait()\n if exc_info:\n # handle exception\n exc_type, exc_value, exc_traceback = exc_info\n ...\n else:\n # use `x`, the function result\n\nTODO: .cancel(), timeout for wait().\n\n### Method `LateFunction.__init__(self, func, name=None, retry_delay=None)`\n\nInitialise a LateFunction.\n\nParameters:\n* `func` is the callable for later execution.\n* `name`, if supplied, specifies an identifying name for the LateFunction.\n* `retry_local`: time delay before retry of this function on RetryError.\n Default from `later.retry_delay`.\n\n## Class `LatePool`\n\nA context manager after the style of subprocess.Pool\nbut with deferred completion.\n\nExample usage:\n\n L = Later(4) # a 4 thread Later\n with LatePool(L) as LP:\n # several calls to LatePool.defer, perhaps looped\n LP.defer(func, *args, **kwargs)\n LP.defer(func, *args, **kwargs)\n # now we can LP.join() to block for all LateFunctions\n #\n # or iterate over LP to collect LateFunctions as they complete\n for LF in LP:\n result = LF()\n print(result)\n\n### Method `LatePool.__init__(self, L=None, priority=None, delay=None, when=None, pfx=None, block=False)`\n\nInitialise the LatePool.\n\nParameters:\n* `L`: Later instance, default from default.current.\n* `priority`, `delay`, `when`, `name`, `pfx`:\n default values passed to Later.submit.\n* `block`: if true, wait for LateFunction completion\n before leaving __exit__.\n\n## Class `Later`\n\nA management class to queue function calls for later execution.\n\nMethods are provided for submitting functions to run ASAP or\nafter a delay or after other pending functions. These methods\nreturn LateFunctions, a subclass of cs.result.Result.\n\nA Later instance' close method closes the Later for further\nsubmission.\nShutdown does not imply that all submitted functions have\ncompleted or even been dispatched.\nCallers may wait for completion and optionally cancel functions.\n\nTODO: __enter__ returns a SubLater, __exit__ closes the SubLater.\n\nTODO: drop global default Later.\n\n### Method `Later.__init__(self, capacity, name=None, inboundCapacity=0, retry_delay=None)`\n\nInitialise the Later instance.\n\nParameters:\n* `capacity`: resource contraint on this Later; if an int, it is used\n to size a Semaphore to constrain the number of dispatched functions\n which may be in play at a time; if not an int it is presumed to be a\n suitable Semaphore-like object, perhaps shared with other subsystems.\n* `name`: optional identifying name for this instance.\n* `inboundCapacity`: if >0, used as a limit on the number of\n undispatched functions that may be queued up; the default is 0 (no\n limit). Calls to submit functions when the inbound limit is reached\n block until some functions are dispatched.\n* `retry_delay`: time delay for requeued functions.\n Default: `DEFAULT_RETRY_DELAY`.\n\n## Function `retry(retry_interval, func, *a, **kw)`\n\nCall the callable `func` with the supplied arguments.\n\nIf it raises `RetryError`,\nrun `time.sleep(retry_interval)`\nand then call again until it does not raise `RetryError`.\n\n## Class `RetryError`\n\nMRO: `builtins.Exception`, `builtins.BaseException` \nException raised by functions which should be resubmitted to the queue.\n\n## Class `SubLater`\n\nA class for managing a group of deferred tasks using an existing `Later`.\n\n### Method `SubLater.__init__(self, L)`\n\nInitialise the `SubLater` with its parent `Later`.\n\nTODO: accept discard=False param to suppress the queue and\nassociated checks.\n\n\n\n# Release Log\n\n*Release 20191007*:\nDrop pipeline functionality, moved to new cs.pipeline module.\n\n*Release 20181231*:\nNew SubLater class to provide a grouping for deferred functions and an iteration to collect them as they complete.\nDrop WorkerThreadPool (leaks idle Threads, brings little benefit).\nLater: drop worker queue thread and semaphore, just try a dispatch on submit or complete.\nLater: drop tracking code. Drop capacity context manager, never used.\n\n*Release 20181109*:\nUpdates for cs.asynchron renamed to cs.result.\nLater: no longer subclass MultiOpenMixin, users now call close to end submission, shutdown to terminate activity and wait to await finalisation.\nClean lint, add docstrings, minor bugfixes.\n\n*Release 20160828*:\nUse \"install_requires\" instead of \"requires\" in DISTINFO.\nAdd LatePool, a context manager after the flavour of subprocess.Pool.\nPython 2 fix.\nRename NestingOpenCloseMixin to MultiOpenMixin - easier to type, say and remember, not to mention being more accurate.\nAdd RetryError exception for use by Later.retriable.\nLateFunction: support RetryError exception from function, causing requeue.\nLateFunction: accept retry_delay parameter, used to delay function retry.\nLater.defer_iterable: accept `test_ready` callable to support deferring iteration until the callable returns truthiness.\nNew function retry(retry_interval, func, *a, **kw) to call func until it does not raise RetryError.\nLater: wrap several methods in @MultiOpenMixin.is_opened.\nAssorted bugfixes and improvements.\n\n*Release 20150115*:\nFirst PyPI release.", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://bitbucket.org/cameron_simpson/css/commits/all", "keywords": "python3", "license": "GNU General Public License v3 or later (GPLv3+)", "maintainer": "", "maintainer_email": "", "name": "cs.later", "package_url": "https://pypi.org/project/cs.later/", "platform": "", "project_url": "https://pypi.org/project/cs.later/", "project_urls": { "Homepage": "https://bitbucket.org/cameron_simpson/css/commits/all" }, "release_url": "https://pypi.org/project/cs.later/20191007/", "requires_dist": null, "requires_python": "", "summary": "Queue functions for execution later in priority and time order.", "version": "20191007" }, "last_serial": 5936655, "releases": { "20150115": [ { "comment_text": "", "digests": { "md5": "d2f39b53753c22e0603c61bfd624b9de", "sha256": "e148c6c57753733a8c31b991910c5d8754e9127494d48deacefb5fb47be3a3d9" }, "downloads": -1, "filename": "cs.later-20150115.tar.gz", "has_sig": false, "md5_digest": "d2f39b53753c22e0603c61bfd624b9de", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11621, "upload_time": "2015-01-18T06:17:08", "url": "https://files.pythonhosted.org/packages/cd/50/b83712eab7c82583f8edf0cf1cfb663b8ec27704853374bb336f21beebb8/cs.later-20150115.tar.gz" } ], "20160828": [ { "comment_text": "", "digests": { "md5": "8de15335f58f17a715196bad4dd263dd", "sha256": "bda6b523ddc5a7b8ab5b10db5f34783b831e941cde74f5d19bb7301fdd505f15" }, "downloads": -1, "filename": "cs.later-20160828.tar.gz", "has_sig": false, "md5_digest": "8de15335f58f17a715196bad4dd263dd", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13257, "upload_time": "2016-08-28T06:07:00", "url": "https://files.pythonhosted.org/packages/06/9e/52f9018f14b194f374a5b12178cb99116870fbb0cce5670f73e61170ace8/cs.later-20160828.tar.gz" } ], "20181109": [ { "comment_text": "", "digests": { "md5": "86a37ca6b2837a9d47fb200f34a53332", "sha256": "de1011e89792dfd9b35f9954076843d2ef49675710c8afb33ed315e9220b0d88" }, "downloads": -1, "filename": "cs.later-20181109.tar.gz", "has_sig": false, "md5_digest": "86a37ca6b2837a9d47fb200f34a53332", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14984, "upload_time": "2018-11-09T01:56:56", "url": "https://files.pythonhosted.org/packages/f2/55/de05f8f269b89b3a2627c7ab70015aa3b6304b7a9821fe8e9e891cc52e67/cs.later-20181109.tar.gz" } ], "20181231": [ { "comment_text": "", "digests": { "md5": "602bf0abe8f9763df2ced4501cc33573", "sha256": "ba1ebcbb2166ecdde81684e22d8fd45bb0aae4f10bc3c5dda0e672bc740686bb" }, "downloads": -1, "filename": "cs.later-20181231.tar.gz", "has_sig": false, "md5_digest": "602bf0abe8f9763df2ced4501cc33573", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14454, "upload_time": "2018-12-31T10:31:47", "url": "https://files.pythonhosted.org/packages/fa/7e/30c5029e2b441b80a2471342098977b1975c915fc34034951b5e22c7f3f1/cs.later-20181231.tar.gz" } ], "20191007": [ { "comment_text": "", "digests": { "md5": "879f4472dbda54405a559c9b8f094ddd", "sha256": "e084e5f16a075dbea33bc3ebd3331489245701815adf847d7bb2a0bf2cef5f0e" }, "downloads": -1, "filename": "cs.later-20191007.tar.gz", "has_sig": false, "md5_digest": "879f4472dbda54405a559c9b8f094ddd", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15376, "upload_time": "2019-10-07T02:34:42", "url": "https://files.pythonhosted.org/packages/b5/76/03039d93b996e0bf27c71137f239ca2a950612f7d7c0f4822e6d166f8f01/cs.later-20191007.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "879f4472dbda54405a559c9b8f094ddd", "sha256": "e084e5f16a075dbea33bc3ebd3331489245701815adf847d7bb2a0bf2cef5f0e" }, "downloads": -1, "filename": "cs.later-20191007.tar.gz", "has_sig": false, "md5_digest": "879f4472dbda54405a559c9b8f094ddd", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15376, "upload_time": "2019-10-07T02:34:42", "url": "https://files.pythonhosted.org/packages/b5/76/03039d93b996e0bf27c71137f239ca2a950612f7d7c0f4822e6d166f8f01/cs.later-20191007.tar.gz" } ] }