{ "info": { "author": "Eric Florenzano", "author_email": "floguy@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Environment :: Web Environment", "Framework :: Django", "Intended Audience :: Developers", "Programming Language :: Python", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": "django-newcache\n===============\n\nNewcache is an improved memcached cache backend for Django. It provides four\nmajor advantages over Django's built-in cache backend:\n\n * It supports pylibmc.\n * It allows for a function to be run on each key before it's sent to memcached.\n * It supports setting cache keys with infinite timeouts.\n * It mitigates the thundering herd problem.\n\nIt also has some pretty nice defaults. By default, the function that's run on\neach key is one that hashes, versions, and flavors the key. More on that \nlater.\n\n\nHow to Install\n--------------\n\nThe simplest way is to just set it as your cache backend in your settings.py, \nlike so::\n\n CACHE_BACKEND = 'newcache://127.0.0.1:11211/?binary=true'\n\nNote that we've passed an additional argument, binary, to the backend. This\nis because pylibmc supports using binary mode to talk to memcached. This is a\ncompletely optional parameter, and can be omitted safely to use the old text \nmode. It is ignored when using python-memcached.\n\n\nDefault Behavior\n----------------\n\nEarlier we said that by default it hashes, versions, and flavors each key. What\ndoes this mean? Let's go through each item in detail.\n\nKeys in memcached come with many restrictions, both on their length and on \ntheir contents. Practically speaking, this means that you can't put spaces\nin your keys, and they can't be very long. One simple solution to this is to\ncreate an sha1 hash of whatever key you want, and use the hash as your key\ninstead. That is what we do in newcache. It not only allows for long keys, \nbut it also lets us put spaces or other characters in our key as well.\n\nSometimes it's necessary to clear the entire cache. We can do this using \nmemcached's flushing mechanisms, but sometimes a cache is shared by many things\ninstead of just one web app. It's a shame to have everything lose its\nfresh cache just because one web app needed to clear its cache. For this, we\nintroduce a simple technique called versioning. A version number is added to\neach cache key, and when this version is incremented, all the old cache keys\nwill become invalid because they have an incorrect version.\n\nThis is exposed as a new setting, CACHE_VERSION, and it defaults to 1.\n\nFinally, we found that as we split our site out into development, staging, and\nproduction, we didn't want them to share the same cache. But we also didn't\nwant to spin up a new memcached instance for each one. So we came up with the\nidea of flavoring the cache. The concept is simple--add a FLAVOR setting and\nmake it something like 'dev', 'prod', or 'test'. With newcache, this flavor\nstring will be added to each key, ensuring that there are no collisions.\n\nConcretely, this is what happens::\n\n # CACHE_VERSION = 2\n # FLAVOR = 'staging'\n cache.get('games')\n # ... would actually call ...\n cache.get('staging-2-9cfa7aefcc61936b70aaec6729329eda')\n\n\nChanging the Default\n--------------------\n\nAll of the above is simply the default, you may provide your own callable\nfunction to be run on each key, by supplying the CACHE_KEY_MODULE setting. It\nmust provide a get_key function which takes any instance of basestring and \noutput a str.\n\n\nThundering Herd Mitigation\n--------------------------\n\nThe thundering herd problem manifests itself when a cache key expires, and many\nthings rush to get or generate the data stored for that key all at once. This \nis doing a lot of unnecessary work and can cause service outages if the\ndatabase cannot handle the load. To solve this problem, we really only want \none thread or process to fetch this data.\n\nOur method of solving this problem is to shove the old (expired) value back \ninto the cache for a short time while the first process/thread goes and updates\nthe key. This is done in a completely transparent way--no changes should need\nto be made in the application code.\n\nWith this cache backend, we have provided an extra 'herd' keyword argument to \nthe set, add, and set_many methods--which is set to True by default. What this \ndoes is transform your cache value into a tuple before saving it to the cache. \nEach value is structured like this:\n\n (A herd marker, your original value, the expiration timestamp)\n\nThen when it actually sets the cache, it sets the real timeout to a little bit\nlonger than the expiration timestamp. Actually, this \"little bit\" is \nconfigurable using the CACHE_HERD_TIMEOUT setting, but it defaults to 60 \nseconds.\n\nNow every time we read a value from the cache, we automatically unpack it and \ncheck whether it's expired. If it has expired, we put it back in the cache for \nCACHE_HERD_TIMEOUT seconds, but (and this is the key) we act as if it were a \ncache miss (so we return None, or whatever the default was for the call.)\n\n*Note*: If you want to set a value to be used as a counter (with incr and\n decr) then you'll want to bypass the herd mechanism.", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "http://github.com/ericflo/django-newcache", "keywords": null, "license": "BSD", "maintainer": null, "maintainer_email": null, "name": "django-newcache", "package_url": "https://pypi.org/project/django-newcache/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/django-newcache/", "project_urls": { "Download": "UNKNOWN", "Homepage": "http://github.com/ericflo/django-newcache" }, "release_url": "https://pypi.org/project/django-newcache/0.2.4/", "requires_dist": null, "requires_python": null, "summary": "Improved memcached cache backend for Django", "version": "0.2.4" }, "last_serial": 790158, "releases": { "0.1": [ { "comment_text": "", "digests": { "md5": "0fc0ccdcb92bbba67aab5e453d5a4807", "sha256": "bfd00388c7e58907505aa604214d6a4ce40fe85dab40aae3d5ced4dc699b5ff0" }, "downloads": -1, "filename": "django-newcache-0.1.tar.gz", "has_sig": false, "md5_digest": "0fc0ccdcb92bbba67aab5e453d5a4807", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 3061, "upload_time": "2010-07-14T11:07:36", "url": "https://files.pythonhosted.org/packages/8f/56/1ad9965bb94ef7c2d16c9614408d2aaad6b25ff3f0a27386b0937359443e/django-newcache-0.1.tar.gz" } ], "0.1.1": [ { "comment_text": "", "digests": { "md5": "35d18947337baa3e6d8530ec03ba6f63", "sha256": "098e3c19aa0e37893f99fe822a5de4b50222c31db5b298ea472c103d06797a4b" }, "downloads": -1, "filename": "django-newcache-0.1.1.tar.gz", "has_sig": false, "md5_digest": "35d18947337baa3e6d8530ec03ba6f63", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 3069, "upload_time": "2010-07-14T11:28:40", "url": "https://files.pythonhosted.org/packages/1e/90/2afb3ee9120638208116b771901eeeaa89bf13557cd864c724d9689fe9b3/django-newcache-0.1.1.tar.gz" } ], "0.1.2": [ { "comment_text": "", "digests": { "md5": "b3108bf702947a58d7336909a681aed9", "sha256": "bfc36a38838b8835860e8902bcba9fcde7cf28b6b4cc317da984d2e6c44b7589" }, "downloads": -1, "filename": "django-newcache-0.1.2.tar.gz", "has_sig": false, "md5_digest": "b3108bf702947a58d7336909a681aed9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 3066, "upload_time": "2010-07-14T11:38:08", "url": "https://files.pythonhosted.org/packages/cc/2a/1d8530230b3432f4b016620e93612cee0fbd2afbf220911221f8d802e7db/django-newcache-0.1.2.tar.gz" } ], "0.2.0": [ { "comment_text": "", "digests": { "md5": "25263a1fb8133d2484f981a6c864a9a7", "sha256": "feb234c71c488ae54e07900327715330304eeef86ff8ad497e99d27d71b81391" }, "downloads": -1, "filename": "django-newcache-0.2.0.tar.gz", "has_sig": false, "md5_digest": "25263a1fb8133d2484f981a6c864a9a7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 3986, "upload_time": "2010-07-18T01:41:44", "url": "https://files.pythonhosted.org/packages/d7/16/21c45ed233921cca21c1cbfa11b411c7b7a97907e967006d900720a957d7/django-newcache-0.2.0.tar.gz" } ], "0.2.1": [ { "comment_text": "", "digests": { "md5": "8ced3baf5bc293caef55533386e32b42", "sha256": "297b20a49ba0308b845a8cfc53e5243870aaaa9d648ae5291d0f2cbf67afd44d" }, "downloads": -1, "filename": "django-newcache-0.2.1.tar.gz", "has_sig": false, "md5_digest": "8ced3baf5bc293caef55533386e32b42", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6311, "upload_time": "2010-07-18T02:17:42", "url": "https://files.pythonhosted.org/packages/a4/06/6504633ef698175d8f022335a197e3d22133afad3a4f46b262ad4f2efd92/django-newcache-0.2.1.tar.gz" } ], "0.2.2": [ { "comment_text": "", "digests": { "md5": "61ccc67b998afd63ae998ab464edb99f", "sha256": "587604f18121d91f10d2e67bd9279eb993e2f16f282757fec06084ac4a0c7a5b" }, "downloads": -1, "filename": "django-newcache-0.2.2.tar.gz", "has_sig": false, "md5_digest": "61ccc67b998afd63ae998ab464edb99f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6068, "upload_time": "2010-07-21T20:49:56", "url": "https://files.pythonhosted.org/packages/59/1a/e9104b5f5a6f8a7a4300def007f4373d6f55fe04eafc4c9e29d8f3f19760/django-newcache-0.2.2.tar.gz" } ], "0.2.3": [ { "comment_text": "", "digests": { "md5": "992bd3d628f9e1675955f7db641b3054", "sha256": "a74c92f8fcd7bf0d5e0e484b2389274a740f7054722b5cb63ed714eead2eef22" }, "downloads": -1, "filename": "django-newcache-0.2.3.tar.gz", "has_sig": false, "md5_digest": "992bd3d628f9e1675955f7db641b3054", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6288, "upload_time": "2010-07-23T19:57:20", "url": "https://files.pythonhosted.org/packages/b6/5e/fb372cb170734d9025ef84d019d4c485b997965ec9d5d5eefd4150b8f257/django-newcache-0.2.3.tar.gz" } ], "0.2.4": [ { "comment_text": "", "digests": { "md5": "de1cc1667e4cce9013b8a20a2e42fafb", "sha256": "713e10e77cf9144aaad92137b8e37490fdedf133314e336828de71c6d94caf92" }, "downloads": -1, "filename": "django-newcache-0.2.4.tar.gz", "has_sig": false, "md5_digest": "de1cc1667e4cce9013b8a20a2e42fafb", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6319, "upload_time": "2010-09-04T18:24:02", "url": "https://files.pythonhosted.org/packages/64/ec/8cdc3a41f14c3fa342901f57ab6597ce8711b0b91a8471a29d94e0ad7a79/django-newcache-0.2.4.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "de1cc1667e4cce9013b8a20a2e42fafb", "sha256": "713e10e77cf9144aaad92137b8e37490fdedf133314e336828de71c6d94caf92" }, "downloads": -1, "filename": "django-newcache-0.2.4.tar.gz", "has_sig": false, "md5_digest": "de1cc1667e4cce9013b8a20a2e42fafb", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6319, "upload_time": "2010-09-04T18:24:02", "url": "https://files.pythonhosted.org/packages/64/ec/8cdc3a41f14c3fa342901f57ab6597ce8711b0b91a8471a29d94e0ad7a79/django-newcache-0.2.4.tar.gz" } ] }