{ "info": { "author": "", "author_email": "", "bugtrack_url": null, "classifiers": [ "Intended Audience :: Developers" ], "description": "# Resource Locker\nOne at a time, please!\n\n[![CircleCI](https://circleci.com/gh/ARMmbed/resource_locker.svg?style=shield&circle-token=992df378a72010c9b4ed32c14c1a354cda9664d2)](https://circleci.com/gh/ARMmbed/resource_locker)\n[![Coverage](https://img.shields.io/badge/coverage-100%25-brightgreen.svg)](https://circleci.com/gh/ARMmbed/resource_locker)\n[![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](https://github.com/ARMmbed/resource_locker)\n\n_Resource Locker_ assumes arbitrary resources, each with their own deterministic, unique identifier.\nThe usage state is retained in a lock server (e.g. a single redis instance, redlock cluster, or similar).\nResources are assumed to be discoverable and filterable by the clients that intend to use them.\nThis reduces the need to categorise and filter resources on the client's behalf, in comparison to\na resource allocation system with a database of all resources (in which typically only the resource\nserver is performing discovery).\n\nA comparison of approaches:\n\n| feature | locks only | resource server |\n|-|:-|-|\n| Collision protection | Y | Y |\n| Lease timeout | Y | Y |\n| Resource database | N | Y |\n| Server-side resource filtering | N | Y |\n| Arbitrary resource types | Y | Maybe (depends on db schema) |\n| Pool growth/reduction | N (SoC*, other service) | Maybe (ideally SoC, but often mixed in) |\n| Discovery queries | O(C**) | O(1) |\n\n(*separation of concerns, **number of clients)\n\nIn practise, the intent is for resource sharing between parallel testruns on a constrained resource pool.\nA separate service tracks resource presence, so discovery (querying for them) is assumed to be trivial.\n\n## Install\nThe usual:\n\n`pipenv install resource_locker`\n\nor\n\n`pipenv install -e git+https://github.com/ARMmbed/resource_locker.git#egg=resource_locker`\n\n## Usage\n\n### Locking\n```python\n# some resource thing\ndevices = list_connected_devices()\n\nfrom resource_locker import Lock, R, P\nfrom operator import attrgetter\nreq1 = R(*devices, need=2, key_gen=attrgetter('id'))\nreq2 = R(P('this one thing'))\nwith Lock(req1, req2, 'other thing') as obtained:\n print(obtained[0][0]) # first requirement, first device\n print(obtained[0][1]) # first requirement, second device\n print(obtained[2][0]) # `other thing`\n\n # alternatively\n req1[1] # second device\n req2[0] # 'this one thing'\n```\n#### Configuration\nLock backend can be configured as follows:\n\n```python\nfrom redis import StrictRedis\nfrom resource_locker import RedisLockFactory\nfrom resource_locker import Lock\ncustom = RedisLockFactory(client=StrictRedis(db=7))\nLock('a', lock_factory=custom)\n```\n\n### Reporting\nThe `RedisReporter` class can be used to track lock usage automatically:\n\n```python\nimport time\nfrom resource_locker import reporter\nfrom resource_locker import Lock\nfrom resource_locker import P\nwith Lock(P('a', model='T1000'), reporter_class=reporter.RedisReporter):\n time.sleep(1)\nreporter.Query().all_tags() # ['key', 'model']\nreporter.Query().all_values('model') # ['T1000']\nreporter.Query().all_aspects('model', 'T1000') # ...\n\n{'lock_acquire_count': 1,\n 'lock_acquire_wait': 0.008001565933228,\n 'lock_release_count': 1,\n 'lock_release_wait': 1.000413179397583,\n 'lock_request_count': 1}\n```\n\n#### Configuration\nReporter backend can be configured as follows:\n```python\nfrom functools import partial\nfrom redis import StrictRedis\nfrom resource_locker import reporter\nfrom resource_locker import Lock\nclient = StrictRedis(db=9)\ncustom_reporter = partial(reporter.RedisReporter, client=client)\nLock(reporter_class=custom_reporter)\n```\n\n## Related reading\n[Distributed Lock Manager](https://en.wikipedia.org/wiki/Distributed_lock_manager)\n| [Pareto Efficiency](https://en.wikipedia.org/wiki/Pareto_efficiency)\n| [Ordered Locking](http://www.informit.com/articles/article.aspx?p=30188&seqNum=7)\n| [Simultaneous Locking](http://www.informit.com/articles/article.aspx?p=30188&seqNum=6)\n\n\n", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/ARMmbed/resource_locker", "keywords": "", "license": "Apache 2.0", "maintainer": "", "maintainer_email": "", "name": "resource-locker", "package_url": "https://pypi.org/project/resource-locker/", "platform": "", "project_url": "https://pypi.org/project/resource-locker/", "project_urls": { "Homepage": "https://github.com/ARMmbed/resource_locker" }, "release_url": "https://pypi.org/project/resource-locker/1.0.0/", "requires_dist": [ "redlock", "python-redis-lock", "redis", "retrying" ], "requires_python": ">3.4", "summary": "Local resource allocation with shared/distributed locks", "version": "1.0.0" }, "last_serial": 4953627, "releases": { "1.0.0": [ { "comment_text": "", "digests": { "md5": "061dfc7688afb51b037df1e30ae38628", "sha256": "c9eed24557f9125eb03d23be94c931b16f8f51c46c098cec831a09491767b94f" }, "downloads": -1, "filename": "resource_locker-1.0.0-py3-none-any.whl", "has_sig": false, "md5_digest": "061dfc7688afb51b037df1e30ae38628", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">3.4", "size": 29395, "upload_time": "2019-01-24T10:22:13", "url": "https://files.pythonhosted.org/packages/49/48/6fd5f2fb0200da48616605d607142677cab0e5b54746e9e05b6690cd60c3/resource_locker-1.0.0-py3-none-any.whl" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "061dfc7688afb51b037df1e30ae38628", "sha256": "c9eed24557f9125eb03d23be94c931b16f8f51c46c098cec831a09491767b94f" }, "downloads": -1, "filename": "resource_locker-1.0.0-py3-none-any.whl", "has_sig": false, "md5_digest": "061dfc7688afb51b037df1e30ae38628", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">3.4", "size": 29395, "upload_time": "2019-01-24T10:22:13", "url": "https://files.pythonhosted.org/packages/49/48/6fd5f2fb0200da48616605d607142677cab0e5b54746e9e05b6690cd60c3/resource_locker-1.0.0-py3-none-any.whl" } ] }