[Django] #29183: "cache" template tag should not render empty strings on failure

6 views
Skip to first unread message

Django

unread,
Mar 3, 2018, 1:26:56 PM3/3/18
to django-...@googlegroups.com
#29183: "cache" template tag should not render empty strings on failure
-------------------------------------+-------------------------------------
Reporter: NicolasLM | Owner: nobody
Type: | Status: new
Uncategorized |
Component: Core | Version: 2.0
(Cache system) | Keywords: cache, template,
Severity: Normal | memcached, pylibmc
Triage Stage: | Has patch: 0
Unreviewed |
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 1
UI/UX: 0 |
-------------------------------------+-------------------------------------
The cache template tag renders an empty string when a connection errors
happens while fetching from the cache.

I believe that the "cache" template tag should try to fetch from the
cache, but fall back to being a noop in case of error.

**Example:**

An included template contains an expensive calculation wrapped in a cache
tag:
{{{
<div class="content">
{% cache 600 cleaned_article article.id %}{{ article.content |
clean_article | safe }}{% endcache %}
</div>
}}}

If any error happens while fetching from the cache, the included template
is rendered as an empty string and the following warning is printed in
logs:
{{{
[2018-03-03 17:36:08,140 WARNI waitress django.template] Exception raised
while rendering {% include %} for template 'reader/home.html'. Empty
string rendered instead.
Traceback (most recent call last):
File "/usr/local/lib/python3.6/site-
packages/django/template/loader_tags.py", line 194, in render
return template.render(context)
File "/usr/local/lib/python3.6/site-packages/django/template/base.py",
line 177, in render
return self._render(context)
File "/usr/local/lib/python3.6/site-packages/django/test/utils.py", line
98, in instrumented_test_render
return self.nodelist.render(context)
File "/usr/local/lib/python3.6/site-packages/django/template/base.py",
line 943, in render
bit = node.render_annotated(context)
File "/usr/local/lib/python3.6/site-packages/django/template/base.py",
line 910, in render_annotated
return self.render(context)
File "/usr/local/lib/python3.6/site-
packages/django/template/defaulttags.py", line 211, in render
nodelist.append(node.render_annotated(context))
File "/usr/local/lib/python3.6/site-packages/django/template/base.py",
line 910, in render_annotated
return self.render(context)
File "/usr/local/lib/python3.6/site-
packages/django/templatetags/cache.py", line 45, in render
value = fragment_cache.get(cache_key)
File "/usr/local/lib/python3.6/site-
packages/django/core/cache/backends/memcached.py", line 73, in get
val = self._cache.get(key)
pylibmc.ConnectionError: error 3 from
memcached_get(:1:template.cache.cleaned_articl): (0x7faf5c0cee70)
CONNECTION FAILURE, ::rec() returned zero, server has disconnected, host:
memcached:11211 -> libmemcached/io.cc:484
}}}

Cache settings:
{{{
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
'TIMEOUT': 24 * 60 * 60,
'LOCATION': 'memcached:11211',
'OPTIONS': {
'binary': True,
'behaviors': {
'no_block': True,
'tcp_nodelay': True,
'tcp_keepalive': True,
'connect_timeout': 2000, # ms
'send_timeout': 750 * 1000, # us
'receive_timeout': 750 * 1000, # us
'_poll_timeout': 2000, # ms
'ketama': True,
'remove_failed': 1,
'retry_timeout': 2,
'dead_timeout': 30,
}
}
}
}
}}}

**Additional information:**
Django 2.0.2
Python 3.6.4
Linux 4.9.82

Both the Django application and Memcached run on Docker containers on the
same host. The error happens after a restart of Memcached (but no restart
of the Django container) because pylibmc reuses connections between
requests and it cannot detect that connections should be discarded because
of the Docker userland proxy.

--
Ticket URL: <https://code.djangoproject.com/ticket/29183>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Mar 5, 2018, 1:01:51 PM3/5/18
to django-...@googlegroups.com
#29183: "cache" template tag should not render empty strings on failure
-------------------------------------+-------------------------------------
Reporter: Nicolas Le Manchet | Owner: nobody
Type: Uncategorized | Status: new
Component: Core (Cache system) | Version: 2.0
Severity: Normal | Resolution:
Keywords: cache, template, | Triage Stage:
memcached, pylibmc | Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Tim Graham):

* easy: 1 => 0


Comment:

The behavior is different on the master branch. As of
e62165b898785e890661953c3b2c9c36d98aee57, `{% include %}` no longer
silences exceptions. Do you want to propose a different behavior (such as
`{% cache %}` silencing the exception)? I'm not sure whether or not there
would be consensus to do that, but you could write to the
DevelopersMailingList to get feedback.

--
Ticket URL: <https://code.djangoproject.com/ticket/29183#comment:1>

Django

unread,
Mar 8, 2018, 1:38:48 PM3/8/18
to django-...@googlegroups.com
#29183: "cache" template tag should not render empty strings on failure
-------------------------------------+-------------------------------------
Reporter: Nicolas Le Manchet | Owner: nobody
Type: Uncategorized | Status: closed

Component: Core (Cache system) | Version: 2.0
Severity: Normal | Resolution: invalid

Keywords: cache, template, | Triage Stage:
memcached, pylibmc | Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Tim Graham):

* status: new => closed
* resolution: => invalid


Comment:

Marking as invalid since the cache template tag doesn't have the reported
behavior.

--
Ticket URL: <https://code.djangoproject.com/ticket/29183#comment:2>

Reply all
Reply to author
Forward
0 new messages