{ "info": { "author": "Andreas Gabriel", "author_email": "gabriel@hrz.uni-marburg.de", "bugtrack_url": null, "classifiers": [ "Framework :: Zope2", "Programming Language :: Python", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": "Introduction\n============\n\n`unimr.memcachedlock` implements a distributed \"soft\" locking\nmechanism using memcached. It provides factory functions and\ndecorators for a primitive locking, a reentrant locking and a special\nlocking for zeo-clients.\n\nThe native locking methods of python's threading module supports\nthread safe locking and therefore, provides only full locking support\nfor single zope installations. However, zeo-clients have no locking\nmechanism beetween each other for concurrent write operations on\nidentical objects (e.g. Catalog) and are unnecessarily stressed to\nresolve ConflictErrors on heavy load. The reason for this problem is\nthe optimistic concurrency control of the ZODB which primarly prepares\nthe changes of an object (in many cases expensive calculations) and\nthereafter checks the validity of the object for the write\nprocess. The higher the number of writes on the same object\nthe higher the risk that a concurrent zeo-client has already\ninvalidated the object while another zeo-client has still this object\nin use. The client with the invalidated object is constrained to roll\nback its changes and to recalculate the changes based on the refreshed\nobject. At worst, this state goes in circles and results in a\nConflictError. The optimistic concurrency control therefore perfectly\nfits only concurrent write operations on distinct objects.\n\nMemcache locking overcomes this problem because it extends the regular\nconcurrency mechanism by a shared locking beetween all involved\nzeo-clients by serializing the concurrent write operations before a\nConflictError is provoked. This mechanism is also known as\n`pessimistic concurrency control`.\n\n\nRisks \n===== \n\nThere is no risk of loosing data within a zope environment because\nmemcachedlock will always fall back to zope's transaction control.\n\n\nUsage\n=====\n\n`unimr.memcachedlock` easily serializes concurrent writes\n\n>>> from unimr.memcachedlock import memcachedlock\n...\n... # define an invariant unique key of an instance\n... def get_key(fun,*args,**kargs):\n... fun, instance = args[0:2]\n... return '/'.join(instance.getPhysicalPath())\n\n\n>>> # lock decorator\n... @memcachedlock.lock(get_key)\n... def concurrent_write(self, *args, **kw):\n... \"\"\" method which produces many conflict errors (bottle neck)\"\"\"\n... # ...\n\n\nor for recursive function calls\n\n\n>>> # rlock decorator\n... @memcachedlock.rlock(get_key)\n... def concurrent_write(self, *args, **kw):\n... \"\"\" method which produces many conflict errors (bottle neck)\"\"\"\n... # ...\n\n\nor for function calls of zeo-clients providing a special ConflictError\nhandling to interact properly with the optimistic concurrency control\n\n\n>>> # zlock decorator\n... @memcachedlock.zlock(get_key)\n... def concurrent_write(self, *args, **kw):\n... \"\"\" method which produces many conflict errors (bottle neck)\"\"\"\n... # ...\n\n\nThe decorators ``@memcachedlock.lock``, ``@memcachedlock.rlock`` or\n``@memcachedlock.zlock`` take exactly one argument\n\n get_key\n function which returns an invariant unique key of an instance\n known by all zeo-clients (required)\n\n\nand two optional keywords:\n\n \n timeout\n livetime in seconds of the lock (default: 30)\n \n interval\n retrial interval of the lock check in seconds (default: 0.05)\n\n\nCatalog Patch\n=============\n\n`unimr.memcachedlock` already includes a patch for zope's Catalog to\nenable locking for the catalog_object method. Uncomment corresponding\nlines in configure.zcml of this package.\n\n\nConfiguring memcached servers\n=============================\n\nYou can configure one ore mor memcached servers by adding the\nenvironment variable MEMCACHEDLOCK_SERVERS to the\nbuildout.cfg as follows (default server: 127.0.0.1:11211):\n\n\n::\n\n\n [instance]\n ...\n zope-conf-additional = \n \n MEMCACHEDLOCK_SERVERS :,:\n \n\n\nTodo\n====\n\n - Tests ...\n - Pessimistic concurrency control implementation by means of native zeo server protocol.\n\nChangelog\n=========\n\n\n2010-09-23: 0.1 - RC2\n---------------------\n\n* ConflictError handling for zeo clients enhanced\n\n\n2009-05-08: 0.1 - RC1\n---------------------\n\n* Initial release", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://svn.plone.org/svn/collective/unimr.memcachedlock", "keywords": "ZEO Zope Memcached Lock", "license": "GPL", "maintainer": null, "maintainer_email": null, "name": "unimr.memcachedlock", "package_url": "https://pypi.org/project/unimr.memcachedlock/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/unimr.memcachedlock/", "project_urls": { "Download": "UNKNOWN", "Homepage": "https://svn.plone.org/svn/collective/unimr.memcachedlock" }, "release_url": "https://pypi.org/project/unimr.memcachedlock/0.1rc2-r144828/", "requires_dist": null, "requires_python": null, "summary": "Memcached based locking factory functions to provide shared locking (e.g. bet. zeo-clients)", "version": "0.1rc2-r144828" }, "last_serial": 801228, "releases": { "0.1dev-r85026": [ { "comment_text": "", "digests": { "md5": "9c4848eace369aafa04938ee0dd9b7a5", "sha256": "ae9d8c6290024fb9b86bafcb9022225e3769f947e07b72fd8b0d1adf88248528" }, "downloads": -1, "filename": "unimr.memcachedlock-0.1dev_r85026-py2.4.egg", "has_sig": false, "md5_digest": "9c4848eace369aafa04938ee0dd9b7a5", "packagetype": "bdist_egg", "python_version": "2.4", "requires_python": null, "size": 15072, "upload_time": "2009-04-24T23:55:02", "url": "https://files.pythonhosted.org/packages/ca/61/16932245c585198b3891432dd116f31693629102a1382fcd709c31e9872b/unimr.memcachedlock-0.1dev_r85026-py2.4.egg" }, { "comment_text": "", "digests": { "md5": "4cf6fc3e48af4c0ae3bb16138db37fe2", "sha256": "96db0582f8a763df14b4dfd6100e769eb75fd38de558c0462820c9d0ffc7a2b8" }, "downloads": -1, "filename": "unimr.memcachedlock-0.1dev-r85026.tar.gz", "has_sig": false, "md5_digest": "4cf6fc3e48af4c0ae3bb16138db37fe2", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7089, "upload_time": "2009-04-24T23:54:52", "url": "https://files.pythonhosted.org/packages/4f/a2/cee5a84ac2d3095b7b1527afbb1daeb815966352a0f427a31ed868eda49c/unimr.memcachedlock-0.1dev-r85026.tar.gz" } ], "0.1rc1-r85726": [ { "comment_text": "", "digests": { "md5": "832aa33ed408e276150d14fcb2a9ba27", "sha256": "a9b5a7101343f65afad999b1e2c86ebd336707fbbaf05d5db9e70b9a180b1b00" }, "downloads": -1, "filename": "unimr.memcachedlock-0.1rc1_r85726-py2.4.egg", "has_sig": false, "md5_digest": "832aa33ed408e276150d14fcb2a9ba27", "packagetype": "bdist_egg", "python_version": "2.4", "requires_python": null, "size": 15009, "upload_time": "2009-05-08T17:58:12", "url": "https://files.pythonhosted.org/packages/20/36/e9c4863f8926093b1945d854bdf701a8fa61246010ace98eaf4a9c009377/unimr.memcachedlock-0.1rc1_r85726-py2.4.egg" }, { "comment_text": "", "digests": { "md5": "ad762f3d5325d259d62462682fe31144", "sha256": "ee7b10135cad90863874230ea0971f55f888dec35b84420ff73109beb14cbcf9" }, "downloads": -1, "filename": "unimr.memcachedlock-0.1rc1-r85726.tar.gz", "has_sig": false, "md5_digest": "ad762f3d5325d259d62462682fe31144", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7143, "upload_time": "2009-05-08T17:58:02", "url": "https://files.pythonhosted.org/packages/23/6f/e07916b86a02358bf2748a2265bea1658ceac8daf7a4b4e9f616e1d8368a/unimr.memcachedlock-0.1rc1-r85726.tar.gz" } ], "0.1rc2-r144828": [ { "comment_text": "", "digests": { "md5": "23da6d7510c5575088dcfe68b579ae29", "sha256": "0d15da4a1dd94df9889ac5eae654c24749f1d447bbd2412904d3258c0c269441" }, "downloads": -1, "filename": "unimr.memcachedlock-0.1rc2_r144828-py2.4.egg", "has_sig": false, "md5_digest": "23da6d7510c5575088dcfe68b579ae29", "packagetype": "bdist_egg", "python_version": "2.4", "requires_python": null, "size": 15180, "upload_time": "2010-09-23T14:28:12", "url": "https://files.pythonhosted.org/packages/27/b4/27b8217b50544269253da1c5dc434d1ab7a4162f6ccbbeeef405176629fa/unimr.memcachedlock-0.1rc2_r144828-py2.4.egg" }, { "comment_text": "", "digests": { "md5": "b06a1ab488dfc881634ecb211ede1a9b", "sha256": "088d199bb65aa9759de1c388fd4d52b7739b03297a8745574dfe12147a81877c" }, "downloads": -1, "filename": "unimr.memcachedlock-0.1rc2-r144828.tar.gz", "has_sig": false, "md5_digest": "b06a1ab488dfc881634ecb211ede1a9b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7179, "upload_time": "2010-09-23T14:27:46", "url": "https://files.pythonhosted.org/packages/1a/e6/bd712eb9856f8707df70c2e438868dc6988cccdc84a9bca1e99c49721e70/unimr.memcachedlock-0.1rc2-r144828.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "23da6d7510c5575088dcfe68b579ae29", "sha256": "0d15da4a1dd94df9889ac5eae654c24749f1d447bbd2412904d3258c0c269441" }, "downloads": -1, "filename": "unimr.memcachedlock-0.1rc2_r144828-py2.4.egg", "has_sig": false, "md5_digest": "23da6d7510c5575088dcfe68b579ae29", "packagetype": "bdist_egg", "python_version": "2.4", "requires_python": null, "size": 15180, "upload_time": "2010-09-23T14:28:12", "url": "https://files.pythonhosted.org/packages/27/b4/27b8217b50544269253da1c5dc434d1ab7a4162f6ccbbeeef405176629fa/unimr.memcachedlock-0.1rc2_r144828-py2.4.egg" }, { "comment_text": "", "digests": { "md5": "b06a1ab488dfc881634ecb211ede1a9b", "sha256": "088d199bb65aa9759de1c388fd4d52b7739b03297a8745574dfe12147a81877c" }, "downloads": -1, "filename": "unimr.memcachedlock-0.1rc2-r144828.tar.gz", "has_sig": false, "md5_digest": "b06a1ab488dfc881634ecb211ede1a9b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7179, "upload_time": "2010-09-23T14:27:46", "url": "https://files.pythonhosted.org/packages/1a/e6/bd712eb9856f8707df70c2e438868dc6988cccdc84a9bca1e99c49721e70/unimr.memcachedlock-0.1rc2-r144828.tar.gz" } ] }