Login

Tag "cache"

78 snippets

Snippet List

Delete template fragment cache

Template: {% load cache %} {% cache 1800 posts blog.pk %} {# Show posts #} {% endcache %} Code: def view(request, pk): # Code blog = get_object_or_404(Blog, pk=pk) delete_template_fragment_cache('posts', blog.pk) # Code

  • template
  • cache
  • fragment
Read More

Test and Restart Memcached Server

Request-phase cache middleware that checks to make sure the Cache server is running. Starting it if it is not. This is run for every request, it checks to see if it can get a defined item out of the cache, if that fails it tries to set it. Failing that it decides the server is probably crashed, so goes though and attempts to connect to the server. Failing a connection it will launch a new server. This is probably not useful on large scale multi server deployments as they likely have their own testing for when services crash, but I am using it in a shared hosting environment where I have to run my own copy of memcache manually and cannot setup proper services testing, so I use this to just make sure the cache server is still running.

  • middleware
  • cache
  • memcached
Read More

Clean-ish memcached key generation

Based on [snippet #1212](http://djangosnippets.org/snippets/1212/) along with it's comments. Replaced the for loop with translate. example usage: from django.core.cache import cache from mysnippet import cache_key_clean expensive_func = lambda x: 'x{0}x'.format(x) input_string = "I wanted a nice value." key = cache_key_clean(input_string) result = cache.get(key) if result is None: result = expensive_func(input_string) cache.set(key, result)

  • memcache
  • cache
Read More

MintCache (simple version)

This is intended as an alternative to http://www.djangosnippets.org/snippets/155/ Put this in your own cache.py and import it instead of django.core.cache and use it the same way. We left out the "add" function but it shouldn't be too hard to make if you want it. From the above post: "The purpose of this caching scheme is to avoid the dog-pile effect. Dog-piling is what normally happens when your data for the cache takes more time to generate than your server is answering requests per second. In other words if your data takes 5 seconds to generate and you are serving 10 requests per second, then when the data expires the normal cache schemes will spawn 50 attempts a regenerating the data before the first request completes. The increased load from the 49 redundant processes may further increase the time it takes to generate the data. If this happens then you are well on your way into a death spiral MintCache works to prevent this scenario by using memcached to to keep track of not just an expiration date, but also a stale date The first client to request data past the stale date is asked to refresh the data, while subsequent requests are given the stale but not-yet-expired data as if it were fresh, with the undertanding that it will get refreshed in a 'reasonable' amount of time by that initial request."

  • cache
  • memcached
  • caching
  • mintcache
Read More

Cache Backend using memcached including prefix settings

Django later than 1.3 (not sure of exact version) wasn't using prefix settings in cache tags or functions used in views. Just for whole page caching. This is small custom cache snippet based on memcached.CacheClass. Feel free adding any comments.

  • memcache
  • cache
  • memcached
  • cache-backend
  • prefix
Read More

Method Caching

A very simple decorator that caches both on-class and in memcached: @method_cache(3600) def some_intensive_method(self): return # do intensive stuff` Alternatively, if you just want to keep it per request and forgo memcaching, just do: @method_cache() def some_intensive_method(self): return # do intensive stuff`

  • memcache
  • cache
  • decorator
  • memcached
  • decorators
  • caching
Read More

caching parsed templates

Put this code somewhere in one of your INSTALLED_APPS `__init__.py` file. This code will replace the django.template.loader.get_template with cached version. Standard get_template function from django reads and parses the template code every time it's called. This version calls (if DEBUG set to False) it only once per template. After that it gets a Template object from template_cache dictionary. On django http server with template code like that: {% extends "index.html" %} {% block content %} {% if form.has_errors %} <p>Your username and password didn't match. Please try again.</p> {% endif %} <form method="post" action="."> <table> <tr><td><label for="id_username">Username:</label></td><td>{{ form.username }}</td></tr> <tr><td><label for="id_password">Password:</label></td><td>{{ form.password }}</td></tr> </table> <input type="submit" value="login" /> <input type="hidden" name="next" value="{{ next }}" /> </form> {% endblock %} ab -n 100 on mac os x 10.5 core 2 duo 2 ghz with 2 GB of RAM gives forge-macbook:~ forge$ ab -n 100 http://127.0.0.1:8000/login/ This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0 Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Copyright 2006 The Apache Software Foundation, http://www.apache.org/ Benchmarking 127.0.0.1 (be patient).....done Server Software: WSGIServer/0.1 Server Hostname: 127.0.0.1 Server Port: 8000 Document Path: /login/ Document Length: 934 bytes Concurrency Level: 1 Time taken for tests: 0.432934 seconds Complete requests: 100 Failed requests: 0 Write errors: 0 Total transferred: 120200 bytes HTML transferred: 93400 bytes Requests per second: 230.98 [#/sec] (mean) Time per request: 4.329 [ms] (mean) Time per request: 4.329 [ms] (mean, across all concurrent requests) Transfer rate: 270.25 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 0 0.0 0 0 Processing: 3 3 1.5 4 12 Waiting: 3 3 1.2 3 12 Total: 3 3 1.5 4 12 Percentage of the requests served within a certain time (ms) 50% 4 66% 4 75% 4 80% 4 90% 4 95% 5 98% 10 99% 12 100% 12 (longest request) without template caching, and forge-macbook:~ forge$ ab -n 100 http://127.0.0.1:8000/login/ This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0 Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Copyright 2006 The Apache Software Foundation, http://www.apache.org/ Benchmarking 127.0.0.1 (be patient).....done Server Software: WSGIServer/0.1 Server Hostname: 127.0.0.1 Server Port: 8000 Document Path: /login/ Document Length: 934 bytes Concurrency Level: 1 Time taken for tests: 0.369860 seconds Complete requests: 100 Failed requests: 0 Write errors: 0 Total transferred: 120200 bytes HTML transferred: 93400 bytes Requests per second: 270.37 [#/sec] (mean) Time per request: 3.699 [ms] (mean) Time per request: 3.699 [ms] (mean, across all concurrent requests) Transfer rate: 316.34 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 0 0.0 0 0 Processing: 3 3 0.9 3 9 Waiting: 2 3 0.9 3 8 Total: 3 3 0.9 3 9 Percentage of the requests served within a certain time (ms) 50% 3 66% 3 75% 3 80% 3 90% 3 95% 5 98% 8 99% 9 100% 9 (longest request) with caching enabled. In both cases DEBUG is set to False.

  • template
  • cache
  • performance
  • optimization
Read More

JSON instead of pickle for memcached

Standard memcache client uses pickle as a serialization format. It can be handy to use json, especially when another component (e.g. backend) doesn't know pickle, but json yes.

  • memcache
  • cache
  • json
  • memcached
  • pickle
Read More

Effective content caching for mass-load site using redirect feature

Hi All, I would like to share my idea and experience in using http redirect feature to organize effective content caching and avoid site blocking on mass requests to not yet cached content. First of all, I should explain that I don't mean usual template-based pages, whose caching in django is enough in almost all cases. My speech is concerning to content such as dynamically created images, external files and other content which may require almost unpredictable long time period to be ready, up to about 10 seconds. Anyway, the content which is already in cache, can be returned immediately. The question is - what *should* happen if the requested content is *not yet present* in the cache? The HTML content is not a problem in this case - we can return intermediate page with meta information to ask a client to retry the content after some period of time. But non-HTML content, such as image, or json, is a problem. The usual *blocking* behavior of the django caching subsystem is not appropriate in a case when the content preparation process takes *more than several fractions* of a second. The whole period while the content is preparing (painting, getting from the external resource and so on) *hundreds* of users will *ask not yet cached* content until all available application server connections will be *occupied* by waiting requests and new user will wait for the content even if the content requested by him is actually ready to be returned. The celery package resolves this problem *partially*, allowing to schedule cache update before cache expiration in asynchronous manner (I am using threadpool package for this purpose instead), and avoiding blocking on content preparation procedure, but the problem with not yet available content remains unresolved. We might schedule periodic cache update to avoid such a situation, but this way leads to unnecessary resource load and may be inappropriate at all in some cases, f.e. for the service like CloudMade or Google "staticmap" painting map content basing on the request parameters. My solution is *using HTTP Redirect feature* . Ideal solution would be available if most of HTTP clients supported Retry-After header in the HTTP Redirect response. Unfortunately, no one of most popular clients (neither Mozilla, nor IE, nor Chrome) does it. Really they ask redirected URL immediately after receiving the redirection response, and ignore Retry-After header at all. Anyway, I hope that they *will* support this feature, but this is not enough right now. So, instead of delegating waiting job to the client side, we need to organize waiting on the server. For this purpose I have created small separate application server with it's *own connection pool*, and delegated waiting task to him (see the snippet). This server needs one URL (/retry_after in the example) looking to the view above, installed in the url.py, and additional DEFAULT_RETRY_TIMEOUT parameter in the settings.py. The view uses request GET parameters, so Django will not try to cache it's results. The only task for this server is to *suspend* redirected requests until requested time is *really arrived*, and then redirect the request to the original URL. To make possible to process many requests simultaneously, it breaks waiting and redirects too long time requests to the self basing on the default timeout. Using this server is simple. We will instantiate the 'retry' server on the separate URL as a *separate application server* and will redirect all requests required to be delayed to this server, passing original URL and the time moment when the requested content should be ready, as parameters. The main server which prepares and returns the content, is *never waiting*. It returns prepared content from the cache, if it is found there, or *starts* content preparation process in *asynchronous* manner using threads, celery package, or any other appropriate technique, and *immediately redirects* the request to the 'retry' server The following is a fragment of the code using 'retry' server: ... # Create your views here. def jams(request,z,x,y): jams_timeout = settings.JAMS_TIMEOUT retry_after_server = settings.RETRY_AFTER_SERVER try: jams_ts,jams_png = request_jams(z,x,y) except Http404,ex: return HttpResponseNotFound() if not jams_png: if settings.DEBUG: logger.debug("JAMS NOT YET READY FOR: %s" % str((z,x,y))) # Tell a client to retrieve jams later time_after = time.time() + settings.DEFAULT_RETRY_TIMEOUT if settings.DEBUG: logger.debug("SEND RETRY AFTER FOR: %s" % str((z,x,y))) loc = reverse(jams,args=(z,x,y)) if request.get_host(): loc = request.build_absolute_uri(loc) r = HttpResponseRedirect( retry_after_server + '?' + urlencode({'redirect': loc,'retry_after':int(time_after)}) ) r['Retry-After'] = settings.DEFAULT_RETRY_TIMEOUT return r # return a png got from the cache if settings.DEBUG: logger.debug("RETURNING JAMS FOR: %s" % str((z,x,y,http_date(jams_ts),http_date(time.time())))) r = HttpResponse(jams_png) r['Content-Type'] = "image/png" r['Content-Length'] = len(jams_png) r['Content-Location'] = request.path # extra data for cache negotiation # Common and ConditionalGet Django Middleware will do the rest r['ETag'] = '"%s"' % md5_constructor(jams_png).hexdigest() r['Last-Modified'] = http_date(jams_ts) r['Expires'] = http_date(jams_ts + jams_timeout) return r ... At the application level, the request_jams() call tries to get content from the cache, and starts content update process asynchronously if required. It returns content got from the cache, and timestamp when the content has been created last time, or pair of None,None values, if the requested content is not available immediately. The line starting from 'r = HttpResponseRedirect' redirects the request to the 'retry' server, if the content is not available immediately. I am using nginx as a 'front-end' proxy server which passes requests to two separate fastcgi daemons - 'retry' and main django application servers separating requests by prefix. The following is a fragment of the nginx.conf configuration file for the nginx server: server { ... location /jams { fastcgi_pass unix:/var/tmp/jams.sock; ... } location /retry_after { fastcgi_pass unix:/var/tmp/retry.sock; ... } ... } As you can see, two locations are passed to *different* application server instances in the production environment, so they *don't block each other*. Really they both are implemented inside one django project, and started from the same directory as fastcgi daemon instances with different starting parameters (sockets to listen, log files etc.). I've used such structure to configure and debug my server easy, either just starting one developer server for both locations, or to have a possibility to start production server in described 'split' mode on the other hand. You can see that the both servers (jams and retry) use the same DEFAULT_RETRY_TIMEOUT setting from the settings.py file. The DEFAULT_RETRY_TIMEOUT plays role of load balancing parameter for requests which wait finishing asynchronous job. After the retry timeout is passed, the control returns to the client by the redirection response (or, for smart clients, the client itself waits the retry timeout before requesting the resource again), so the server may cleanup resources temporary acquired by these requests. Additional bonus of using such technique is stability of server processor load. Even in prime time, the server load is stable and controlled: number of the application instances and number of threads in the thread pool (evaluating asynchronous jobs) for each instance is fixed by configuration, nginx load per request is minimal, and concurrent requests are balanced (between server, network, and clients) by the retry timeout and redirect responses. You can see the result of the work on the our site, f.e. [on this page](http://www.doroga.tv/nnov/apps/map/), where all (transparent version) jam tiles are painting such a manner. The only difference for the production server environment is that some top zooms of most popular regions are refreshed by the special daemon (also written using django as a 'management command') which forces tiles to be refreshed in the cache even no one client requests it right now — to decrease response time for the jams map after long 'sleep' period.

  • cache
  • load
  • redirect
  • nginx
  • content
  • mass
Read More

Cachable Class Method Decorator

This decorator does automatic key generation and simplifies caching. Can be used with any class, not just model subclasses. Also see [Stales Cache Decorator](http://www.djangosnippets.org/snippets/1131/).

  • cache
  • decorator
Read More

Get the Django decorator/middleware cache key for given URL

This mimicks the keys used internally by the @cache_page decorators and site-wide CacheMiddleware. Now you can poke them, prod them, delete them, do what you like with them (eg, delete after you update some content and you want a specific URL refreshed).

  • cache
  • key
Read More
Author: s29
  • 2
  • 2