{ "info": { "author": "Jaesup Kwak", "author_email": "", "bugtrack_url": null, "classifiers": [ "Development Status :: 3 - Alpha", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Operating System :: POSIX", "Operating System :: Unix", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: Implementation :: CPython", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": "===========\nredisrwlock\n===========\n\nDistributed reader-writer lock for python using redis as server\n\nFeatures:\n\n* Reader-writer lock (can have multiple readers or one exclusive writer)\n* Stale locks collected (run as separate process, ``python3 -m redisrwlock``)\n* Deadlock detection\n\nNote: Deadlock detection and garbage/staleness collection is done in\nclient side, which can cause excessive I/O with redis server. Tune\nwith ``retry_interval`` and consider running the stale lock collection\nappropriately for your purpose.\n\nDependencies:\n\n* python 3.5.2\n* redis-py 2.10.5\n* redis 3.2.6\n* [test] Coverage.py 4.2\n\nInstall\n=======\n\n.. code-block:: console\n\n pip install redisrwlock\n\nUsages\n======\n\nTry lock with timeout=0\n-----------------------\n\nWith timeout=0, RwlockClinet.lock acts as so called try_lock.\n\n.. code-block:: python\n\n from redisrwlock import Rwlock, RwlockClient\n\n client = RwlockClient()\n rwlock = client.lock('N1', Rwlock.READ, timeout=0)\n if rwlock.status == Rwlock.OK:\n # Processings of resource named 'N1' with READ lock\n # ...\n client.unlock(rwlock)\n elif rwlock.status == Rwlock.FAIL:\n # Retry locking or quit\n\nWaiting until lock success or deadlock\n--------------------------------------\n\nWith timout > 0, RwlockClient.lock waits until lock successfully or\ndeadlock detected and caller is chosen as victim.\n\n.. code-block:: python\n\n from redisrwlock import Rwlock, RwlockClient\n\n client = RwlockClient()\n rwlock = client.lock('N1', Rwlock.READ, timeout=Rwlock.FOREVER)\n if rwlock.status == Rwlock.OK:\n # Processings of resource named 'N1' with READ lock\n # ...\n client.unlock(rwlock)\n elif rwlock.status == Rwlock.DEADLOCK:\n # 1. unlock if holding any other locks\n # 2. Retry locking or quit\n\nRemoving stale locks\n--------------------\n\nWhen a client exits without unlock, redis keys for the client's locks\nremain in server and block other clients from successful locking.\n`redisrwlock` run in command line removes such garbage locks, waits\nin server.\n\n.. code-block:: console\n\n python3 -m redisrwlock\n\nYou can repeat this gc periodically by specifying -r or --repeat option.\n\nTests\n=====\n\nUnittest\n--------\n\n1. Runnig unittest in test directory:\n\n .. code-block:: console\n\n cd test\n python3 -m unittest -q\n\n2. or in project top directory:\n\n .. code-block:: console\n\n python3 -m unittest discover test -q\n\nExamples below are assuming you run unittest in project top directory.\n\nCoverage\n--------\n\n.. code-block:: console\n\n coverage erase\n coverage run -a -m unittest discover test -q\n coverage html\n\nAbove simple coverage run will report lower coverage than expected\nbecause the tests use subprocess. Codes run by subprocess are not\ncovered in report by default.\n\nSubprocess coverage\n-------------------\n\nNeed some preperation:\n\n1. Edit `sitecustomize.py` (under python intallation's `site-packages`\n directory), add 2 lines\n\n .. code-block:: python\n\n import coverage\n coverage.process_startup()\n\n2. Edit `.coveragerc` (default name of coverage.py's config file)\n\n .. code-block:: cfg\n\n [run]\n branch = True\n [html]\n directory = htmlcov\n\nThen, run coverage with environment variable\n``COVERAGE_PROCESS_START``\\={path/to/coveragerc}\n\n.. code-block:: console\n\n coverage erase\n COVERAGE_PROCESS_START=.coveragerc coverage run -a -m unittest discover test -q\n coverage html\n\nTODOs\n=====\n\n* TODO: command line option to specify redis-server\n* TODO: high availability! redis sentinel or replication?", "description_content_type": null, "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/veshboo/redisrwlock", "keywords": "redis,rwlock", "license": "BSD", "maintainer": "", "maintainer_email": "", "name": "redisrwlock", "package_url": "https://pypi.org/project/redisrwlock/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/redisrwlock/", "project_urls": { "Homepage": "https://github.com/veshboo/redisrwlock" }, "release_url": "https://pypi.org/project/redisrwlock/0.1.2/", "requires_dist": null, "requires_python": "", "summary": "Distributed reader-writer lock (rwlock) for python using redis", "version": "0.1.2" }, "last_serial": 2554913, "releases": { "0.1.2": [ { "comment_text": "", "digests": { "md5": "d2fedaaf23d039035e20214dae02a23a", "sha256": "350ceb0b4483738224cfbdea258a649e7b0670b710da6e9ceebea7ae26f82873" }, "downloads": -1, "filename": "redisrwlock-0.1.2.tar.gz", "has_sig": false, "md5_digest": "d2fedaaf23d039035e20214dae02a23a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11697, "upload_time": "2017-01-05T02:02:45", "url": "https://files.pythonhosted.org/packages/2b/69/06152288a240d2fd6e840f240095c1884bfed26da499fbfd876656ae22f7/redisrwlock-0.1.2.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "d2fedaaf23d039035e20214dae02a23a", "sha256": "350ceb0b4483738224cfbdea258a649e7b0670b710da6e9ceebea7ae26f82873" }, "downloads": -1, "filename": "redisrwlock-0.1.2.tar.gz", "has_sig": false, "md5_digest": "d2fedaaf23d039035e20214dae02a23a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11697, "upload_time": "2017-01-05T02:02:45", "url": "https://files.pythonhosted.org/packages/2b/69/06152288a240d2fd6e840f240095c1884bfed26da499fbfd876656ae22f7/redisrwlock-0.1.2.tar.gz" } ] }