Change Local Memory Cache to Use LRU #28977

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

Change Local Memory Cache to Use LRU #28977

Grant Jenks
Hi all--

Long time user, first time poster, here. Thank you all for Django!

The current local memory cache (locmem) in Django uses a pseudo-random culling strategy. Rather than random, the OrderedDict data type can be used to implement an LRU eviction policy. A prototype implementation is already used by functools.lru_cache and Python 3 now supports OrderedDict.move_to_end and OrderedDict.popitem to ease the implementation.

I have created an example set of changes at https://github.com/grantjenks/django/tree/ticket_28977 in commit https://github.com/grantjenks/django/commit/b06574f6713d4b7d367d7a11e0268fb62f5fd1d1

Is there a consensus as to the value of these changes?

Sincerely,
Grant Jenks

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/1f9d2225-18e8-46f3-9311-b07177c4baca%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Change Local Memory Cache to Use LRU #28977

Josh Smeaton
To lend some weight to this, I've implemented an LRU loc mem cache and have done some benchmarking. There are some graphs in the readme: https://github.com/kogan/django-lrucache-backend - which I've written a little about https://devblog.kogan.com/blog/a-smarter-local-memory-django-cache-backend (I don't think my particular implementation is useful to core, as it relies on a 3rd party C lib, but using OrderedDict is cool!).

You can also get a very nice bump in throughput if you eliminate the `validate_key` check, which does a character by character check of the key to avoid issues with particular characters in memcache.

We don't want to be promoting locmemcache too much, but that said, if we can provide a better default then we should in my opinion.

On Friday, 5 January 2018 10:12:39 UTC+11, Grant Jenks wrote:
Hi all--

Long time user, first time poster, here. Thank you all for Django!

The current local memory cache (locmem) in Django uses a pseudo-random culling strategy. Rather than random, the OrderedDict data type can be used to implement an LRU eviction policy. A prototype implementation is already used by functools.lru_cache and Python 3 now supports OrderedDict.move_to_end and OrderedDict.popitem to ease the implementation.

I have created an example set of changes at <a href="https://github.com/grantjenks/django/tree/ticket_28977" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fgrantjenks%2Fdjango%2Ftree%2Fticket_28977\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNF4G4MFpOnCooaGn7gF8oHZcKYgdw&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fgrantjenks%2Fdjango%2Ftree%2Fticket_28977\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNF4G4MFpOnCooaGn7gF8oHZcKYgdw&#39;;return true;">https://github.com/grantjenks/django/tree/ticket_28977 in commit <a href="https://github.com/grantjenks/django/commit/b06574f6713d4b7d367d7a11e0268fb62f5fd1d1" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fgrantjenks%2Fdjango%2Fcommit%2Fb06574f6713d4b7d367d7a11e0268fb62f5fd1d1\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHoXe5qhxdrU2CgH_Cq8MgtcfwQZA&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fgrantjenks%2Fdjango%2Fcommit%2Fb06574f6713d4b7d367d7a11e0268fb62f5fd1d1\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHoXe5qhxdrU2CgH_Cq8MgtcfwQZA&#39;;return true;">https://github.com/grantjenks/django/commit/b06574f6713d4b7d367d7a11e0268fb62f5fd1d1

Is there a consensus as to the value of these changes?

Sincerely,
Grant Jenks

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/fdb91901-c378-4258-9201-d24a9f5f103e%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Change Local Memory Cache to Use LRU #28977

Adam Johnson-2
I'm +1 for moving to LRU too, the eviction algorithm has always looked weird to me. And Josh's library shows there are valid uses of local memory caching in applications - perhaps moreso these days than when Django added caching and memcached was the latest thing.
 
You can also get a very nice bump in throughput if you eliminate the `validate_key` check

+1 to adding an option to disable the check as well. If you're using a LocMemCache in production, you probably don't care about compatibility with memcached, because you'll be using it for different types of data.

On 5 January 2018 at 02:53, Josh Smeaton <[hidden email]> wrote:
To lend some weight to this, I've implemented an LRU loc mem cache and have done some benchmarking. There are some graphs in the readme: https://github.com/kogan/django-lrucache-backend - which I've written a little about https://devblog.kogan.com/blog/a-smarter-local-memory-django-cache-backend (I don't think my particular implementation is useful to core, as it relies on a 3rd party C lib, but using OrderedDict is cool!).

You can also get a very nice bump in throughput if you eliminate the `validate_key` check, which does a character by character check of the key to avoid issues with particular characters in memcache.

We don't want to be promoting locmemcache too much, but that said, if we can provide a better default then we should in my opinion.

On Friday, 5 January 2018 10:12:39 UTC+11, Grant Jenks wrote:
Hi all--

Long time user, first time poster, here. Thank you all for Django!

The current local memory cache (locmem) in Django uses a pseudo-random culling strategy. Rather than random, the OrderedDict data type can be used to implement an LRU eviction policy. A prototype implementation is already used by functools.lru_cache and Python 3 now supports OrderedDict.move_to_end and OrderedDict.popitem to ease the implementation.


Is there a consensus as to the value of these changes?

Sincerely,
Grant Jenks

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/fdb91901-c378-4258-9201-d24a9f5f103e%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--
Adam

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/CAMyDDM17cq0h%3DhD%3DFDkEK%2Bszf%2B952BVH4m%2Bm2fNTLWM-%2Bof68A%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Change Local Memory Cache to Use LRU #28977

Grant Jenks
Josh, it's nice to meet you here. I cited your django-lrucache-backend project in the original post of the Trac ticket. I'm also the author of DiskCache http://www.grantjenks.com/docs/diskcache/ which your project refs for benchmarks :) I added some benchmark data to the Trac ticket which may interest you.

Thank you, Josh and Adam, for the +1's. I've summarized the feedback and updated the ticket at https://code.djangoproject.com/ticket/28977 It's now marked as Accepted and Has patch. I've created a pull request at https://github.com/django/django/pull/9555 Please review when able.

Grant

Ps. As always the docs are excellent. Even the docs for contributing are extremely helpful!


On Friday, January 5, 2018 at 1:46:38 PM UTC-8, Adam Johnson wrote:
I'm +1 for moving to LRU too, the eviction algorithm has always looked weird to me. And Josh's library shows there are valid uses of local memory caching in applications - perhaps moreso these days than when Django added caching and memcached was the latest thing.
 
You can also get a very nice bump in throughput if you eliminate the `validate_key` check

+1 to adding an option to disable the check as well. If you're using a LocMemCache in production, you probably don't care about compatibility with memcached, because you'll be using it for different types of data.

On 5 January 2018 at 02:53, Josh Smeaton <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="U1L7sNG9DQAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">josh.s...@...> wrote:
To lend some weight to this, I've implemented an LRU loc mem cache and have done some benchmarking. There are some graphs in the readme: <a href="https://github.com/kogan/django-lrucache-backend" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fkogan%2Fdjango-lrucache-backend\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNF8UeHYJUZUrpVwQiE5XArFuLAk7Q&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fkogan%2Fdjango-lrucache-backend\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNF8UeHYJUZUrpVwQiE5XArFuLAk7Q&#39;;return true;">https://github.com/kogan/django-lrucache-backend - which I've written a little about <a href="https://devblog.kogan.com/blog/a-smarter-local-memory-django-cache-backend" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fdevblog.kogan.com%2Fblog%2Fa-smarter-local-memory-django-cache-backend\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFgkmocWazecITCtXQGAAkcBULMBQ&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fdevblog.kogan.com%2Fblog%2Fa-smarter-local-memory-django-cache-backend\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFgkmocWazecITCtXQGAAkcBULMBQ&#39;;return true;">https://devblog.kogan.com/blog/a-smarter-local-memory-django-cache-backend (I don't think my particular implementation is useful to core, as it relies on a 3rd party C lib, but using OrderedDict is cool!).

You can also get a very nice bump in throughput if you eliminate the `validate_key` check, which does a character by character check of the key to avoid issues with particular characters in memcache.

We don't want to be promoting locmemcache too much, but that said, if we can provide a better default then we should in my opinion.

On Friday, 5 January 2018 10:12:39 UTC+11, Grant Jenks wrote:
Hi all--

Long time user, first time poster, here. Thank you all for Django!

The current local memory cache (locmem) in Django uses a pseudo-random culling strategy. Rather than random, the OrderedDict data type can be used to implement an LRU eviction policy. A prototype implementation is already used by functools.lru_cache and Python 3 now supports OrderedDict.move_to_end and OrderedDict.popitem to ease the implementation.

I have created an example set of changes at <a href="https://github.com/grantjenks/django/tree/ticket_28977" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fgrantjenks%2Fdjango%2Ftree%2Fticket_28977\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNF4G4MFpOnCooaGn7gF8oHZcKYgdw&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fgrantjenks%2Fdjango%2Ftree%2Fticket_28977\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNF4G4MFpOnCooaGn7gF8oHZcKYgdw&#39;;return true;">https://github.com/grantjenks/django/tree/ticket_28977 in commit <a href="https://github.com/grantjenks/django/commit/b06574f6713d4b7d367d7a11e0268fb62f5fd1d1" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fgrantjenks%2Fdjango%2Fcommit%2Fb06574f6713d4b7d367d7a11e0268fb62f5fd1d1\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHoXe5qhxdrU2CgH_Cq8MgtcfwQZA&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fgrantjenks%2Fdjango%2Fcommit%2Fb06574f6713d4b7d367d7a11e0268fb62f5fd1d1\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHoXe5qhxdrU2CgH_Cq8MgtcfwQZA&#39;;return true;">https://github.com/grantjenks/django/commit/b06574f6713d4b7d367d7a11e0268fb62f5fd1d1

Is there a consensus as to the value of these changes?

Sincerely,
Grant Jenks

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to <a href="javascript:" target="_blank" gdf-obfuscated-mailto="U1L7sNG9DQAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">django-develop...@googlegroups.com.
To post to this group, send email to <a href="javascript:" target="_blank" gdf-obfuscated-mailto="U1L7sNG9DQAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">django-d...@googlegroups.com.
Visit this group at <a href="https://groups.google.com/group/django-developers" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://groups.google.com/group/django-developers&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/group/django-developers&#39;;return true;">https://groups.google.com/group/django-developers.
To view this discussion on the web visit <a href="https://groups.google.com/d/msgid/django-developers/fdb91901-c378-4258-9201-d24a9f5f103e%40googlegroups.com?utm_medium=email&amp;utm_source=footer" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://groups.google.com/d/msgid/django-developers/fdb91901-c378-4258-9201-d24a9f5f103e%40googlegroups.com?utm_medium\x3demail\x26utm_source\x3dfooter&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/d/msgid/django-developers/fdb91901-c378-4258-9201-d24a9f5f103e%40googlegroups.com?utm_medium\x3demail\x26utm_source\x3dfooter&#39;;return true;">https://groups.google.com/d/msgid/django-developers/fdb91901-c378-4258-9201-d24a9f5f103e%40googlegroups.com.

For more options, visit <a href="https://groups.google.com/d/optout" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;">https://groups.google.com/d/optout.



--
Adam

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/460cee35-9eb6-426a-8847-27ee398fcaea%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Change Local Memory Cache to Use LRU #28977

Josh Smeaton
Nice to meet you too. Your benchmarking code was extremely handy when I was profiling lru-cache-backend, so thank you!

Are you able to run the same benchmarks using this version of the cache to see how it performs in low/medium/high eviction scenarios? I think those benchmarks will be nicer than the simpler cache.get() ones you have on the ticket.

I'll get to reviewing that change some time this week regardless.



On Tuesday, 9 January 2018 08:58:55 UTC+11, Grant Jenks wrote:
Josh, it's nice to meet you here. I cited your django-lrucache-backend project in the original post of the Trac ticket. I'm also the author of DiskCache <a href="http://www.grantjenks.com/docs/diskcache/" target="_blank" rel="nofollow" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.grantjenks.com%2Fdocs%2Fdiskcache%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHmBdgKSecQCGiYBnsgbdgET08WfQ&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.grantjenks.com%2Fdocs%2Fdiskcache%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHmBdgKSecQCGiYBnsgbdgET08WfQ&#39;;return true;">http://www.grantjenks.com/docs/diskcache/ which your project refs for benchmarks :) I added some benchmark data to the Trac ticket which may interest you.

Thank you, Josh and Adam, for the +1's. I've summarized the feedback and updated the ticket at <a href="https://code.djangoproject.com/ticket/28977" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fcode.djangoproject.com%2Fticket%2F28977\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHQ0hGbYyb218MyfDEYKYOREfJAcw&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fcode.djangoproject.com%2Fticket%2F28977\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHQ0hGbYyb218MyfDEYKYOREfJAcw&#39;;return true;">https://code.djangoproject.com/ticket/28977 It's now marked as Accepted and Has patch. I've created a pull request at <a href="https://github.com/django/django/pull/9555" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fdjango%2Fdjango%2Fpull%2F9555\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNE-ctig5K2gfegpuUGPUUSHndBFEg&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fdjango%2Fdjango%2Fpull%2F9555\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNE-ctig5K2gfegpuUGPUUSHndBFEg&#39;;return true;">https://github.com/django/django/pull/9555 Please review when able.

Grant

Ps. As always the docs are excellent. Even the docs for contributing are extremely helpful!


On Friday, January 5, 2018 at 1:46:38 PM UTC-8, Adam Johnson wrote:
I'm +1 for moving to LRU too, the eviction algorithm has always looked weird to me. And Josh's library shows there are valid uses of local memory caching in applications - perhaps moreso these days than when Django added caching and memcached was the latest thing.
 
You can also get a very nice bump in throughput if you eliminate the `validate_key` check

+1 to adding an option to disable the check as well. If you're using a LocMemCache in production, you probably don't care about compatibility with memcached, because you'll be using it for different types of data.

On 5 January 2018 at 02:53, Josh Smeaton <[hidden email]> wrote:
To lend some weight to this, I've implemented an LRU loc mem cache and have done some benchmarking. There are some graphs in the readme: <a href="https://github.com/kogan/django-lrucache-backend" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fkogan%2Fdjango-lrucache-backend\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNF8UeHYJUZUrpVwQiE5XArFuLAk7Q&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fkogan%2Fdjango-lrucache-backend\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNF8UeHYJUZUrpVwQiE5XArFuLAk7Q&#39;;return true;">https://github.com/kogan/django-lrucache-backend - which I've written a little about <a href="https://devblog.kogan.com/blog/a-smarter-local-memory-django-cache-backend" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fdevblog.kogan.com%2Fblog%2Fa-smarter-local-memory-django-cache-backend\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFgkmocWazecITCtXQGAAkcBULMBQ&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fdevblog.kogan.com%2Fblog%2Fa-smarter-local-memory-django-cache-backend\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFgkmocWazecITCtXQGAAkcBULMBQ&#39;;return true;">https://devblog.kogan.com/blog/a-smarter-local-memory-django-cache-backend (I don't think my particular implementation is useful to core, as it relies on a 3rd party C lib, but using OrderedDict is cool!).

You can also get a very nice bump in throughput if you eliminate the `validate_key` check, which does a character by character check of the key to avoid issues with particular characters in memcache.

We don't want to be promoting locmemcache too much, but that said, if we can provide a better default then we should in my opinion.

On Friday, 5 January 2018 10:12:39 UTC+11, Grant Jenks wrote:
Hi all--

Long time user, first time poster, here. Thank you all for Django!

The current local memory cache (locmem) in Django uses a pseudo-random culling strategy. Rather than random, the OrderedDict data type can be used to implement an LRU eviction policy. A prototype implementation is already used by functools.lru_cache and Python 3 now supports OrderedDict.move_to_end and OrderedDict.popitem to ease the implementation.

I have created an example set of changes at <a href="https://github.com/grantjenks/django/tree/ticket_28977" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fgrantjenks%2Fdjango%2Ftree%2Fticket_28977\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNF4G4MFpOnCooaGn7gF8oHZcKYgdw&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fgrantjenks%2Fdjango%2Ftree%2Fticket_28977\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNF4G4MFpOnCooaGn7gF8oHZcKYgdw&#39;;return true;">https://github.com/grantjenks/django/tree/ticket_28977 in commit <a href="https://github.com/grantjenks/django/commit/b06574f6713d4b7d367d7a11e0268fb62f5fd1d1" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fgrantjenks%2Fdjango%2Fcommit%2Fb06574f6713d4b7d367d7a11e0268fb62f5fd1d1\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHoXe5qhxdrU2CgH_Cq8MgtcfwQZA&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fgrantjenks%2Fdjango%2Fcommit%2Fb06574f6713d4b7d367d7a11e0268fb62f5fd1d1\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHoXe5qhxdrU2CgH_Cq8MgtcfwQZA&#39;;return true;">https://github.com/grantjenks/django/commit/b06574f6713d4b7d367d7a11e0268fb62f5fd1d1

Is there a consensus as to the value of these changes?

Sincerely,
Grant Jenks

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-develop...@googlegroups.com.
To post to this group, send email to [hidden email].
Visit this group at <a href="https://groups.google.com/group/django-developers" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://groups.google.com/group/django-developers&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/group/django-developers&#39;;return true;">https://groups.google.com/group/django-developers.
To view this discussion on the web visit <a href="https://groups.google.com/d/msgid/django-developers/fdb91901-c378-4258-9201-d24a9f5f103e%40googlegroups.com?utm_medium=email&amp;utm_source=footer" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://groups.google.com/d/msgid/django-developers/fdb91901-c378-4258-9201-d24a9f5f103e%40googlegroups.com?utm_medium\x3demail\x26utm_source\x3dfooter&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/d/msgid/django-developers/fdb91901-c378-4258-9201-d24a9f5f103e%40googlegroups.com?utm_medium\x3demail\x26utm_source\x3dfooter&#39;;return true;">https://groups.google.com/d/msgid/django-developers/fdb91901-c378-4258-9201-d24a9f5f103e%40googlegroups.com.

For more options, visit <a href="https://groups.google.com/d/optout" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;">https://groups.google.com/d/optout.



--
Adam

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/933c2a3e-896d-45c8-a1a9-17ef8abf42c5%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Change Local Memory Cache to Use LRU #28977

Grant Jenks
I was able to run the more extensive benchmarks under no-contention and high-contention scenarios with measurements at the 50th, 90th, 99th, and 100th percentiles. I updated the ticket at https://code.djangoproject.com/ticket/28977 with the results.

Under high-contention scenarios, the RWLock did serve a purpose, albeit a rather limited one. There's a small tradeoff to be had but I think it's easy to accept. Note that the benchmark does not include a miss-rate penalty which the LRU-eviction policy will almost certainly improve compared with the current random-eviction policy.

Grant


On Mon, Jan 8, 2018 at 2:25 PM, Josh Smeaton <[hidden email]> wrote:
Nice to meet you too. Your benchmarking code was extremely handy when I was profiling lru-cache-backend, so thank you!

Are you able to run the same benchmarks using this version of the cache to see how it performs in low/medium/high eviction scenarios? I think those benchmarks will be nicer than the simpler cache.get() ones you have on the ticket.

I'll get to reviewing that change some time this week regardless.




On Tuesday, 9 January 2018 08:58:55 UTC+11, Grant Jenks wrote:
Josh, it's nice to meet you here. I cited your django-lrucache-backend project in the original post of the Trac ticket. I'm also the author of DiskCache http://www.grantjenks.com/docs/diskcache/ which your project refs for benchmarks :) I added some benchmark data to the Trac ticket which may interest you.

Thank you, Josh and Adam, for the +1's. I've summarized the feedback and updated the ticket at https://code.djangoproject.com/ticket/28977 It's now marked as Accepted and Has patch. I've created a pull request at https://github.com/django/django/pull/9555 Please review when able.

Grant

Ps. As always the docs are excellent. Even the docs for contributing are extremely helpful!


On Friday, January 5, 2018 at 1:46:38 PM UTC-8, Adam Johnson wrote:
I'm +1 for moving to LRU too, the eviction algorithm has always looked weird to me. And Josh's library shows there are valid uses of local memory caching in applications - perhaps moreso these days than when Django added caching and memcached was the latest thing.
 
You can also get a very nice bump in throughput if you eliminate the `validate_key` check

+1 to adding an option to disable the check as well. If you're using a LocMemCache in production, you probably don't care about compatibility with memcached, because you'll be using it for different types of data.

On 5 January 2018 at 02:53, Josh Smeaton <[hidden email]> wrote:
To lend some weight to this, I've implemented an LRU loc mem cache and have done some benchmarking. There are some graphs in the readme: https://github.com/kogan/django-lrucache-backend - which I've written a little about https://devblog.kogan.com/blog/a-smarter-local-memory-django-cache-backend (I don't think my particular implementation is useful to core, as it relies on a 3rd party C lib, but using OrderedDict is cool!).

You can also get a very nice bump in throughput if you eliminate the `validate_key` check, which does a character by character check of the key to avoid issues with particular characters in memcache.

We don't want to be promoting locmemcache too much, but that said, if we can provide a better default then we should in my opinion.

On Friday, 5 January 2018 10:12:39 UTC+11, Grant Jenks wrote:
Hi all--

Long time user, first time poster, here. Thank you all for Django!

The current local memory cache (locmem) in Django uses a pseudo-random culling strategy. Rather than random, the OrderedDict data type can be used to implement an LRU eviction policy. A prototype implementation is already used by functools.lru_cache and Python 3 now supports OrderedDict.move_to_end and OrderedDict.popitem to ease the implementation.


Is there a consensus as to the value of these changes?

Sincerely,
Grant Jenks

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-develop...@googlegroups.com.
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/fdb91901-c378-4258-9201-d24a9f5f103e%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--
Adam

--
You received this message because you are subscribed to a topic in the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/django-developers/Gz2XqtoYmNk/unsubscribe.
To unsubscribe from this group and all its topics, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/933c2a3e-896d-45c8-a1a9-17ef8abf42c5%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/CAG0JsGw%3DdFr33sTp93JuEHBBbLnjYfO0w5kG4%3Dnab58F7Omcsg%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Change Local Memory Cache to Use LRU #28977

Adam Johnson-2
Grant, you're a star. I think the tradeoff is acceptable too.

On 10 January 2018 at 17:05, Grant Jenks <[hidden email]> wrote:
I was able to run the more extensive benchmarks under no-contention and high-contention scenarios with measurements at the 50th, 90th, 99th, and 100th percentiles. I updated the ticket at https://code.djangoproject.com/ticket/28977 with the results.

Under high-contention scenarios, the RWLock did serve a purpose, albeit a rather limited one. There's a small tradeoff to be had but I think it's easy to accept. Note that the benchmark does not include a miss-rate penalty which the LRU-eviction policy will almost certainly improve compared with the current random-eviction policy.

Grant


On Mon, Jan 8, 2018 at 2:25 PM, Josh Smeaton <[hidden email]> wrote:
Nice to meet you too. Your benchmarking code was extremely handy when I was profiling lru-cache-backend, so thank you!

Are you able to run the same benchmarks using this version of the cache to see how it performs in low/medium/high eviction scenarios? I think those benchmarks will be nicer than the simpler cache.get() ones you have on the ticket.

I'll get to reviewing that change some time this week regardless.




On Tuesday, 9 January 2018 08:58:55 UTC+11, Grant Jenks wrote:
Josh, it's nice to meet you here. I cited your django-lrucache-backend project in the original post of the Trac ticket. I'm also the author of DiskCache http://www.grantjenks.com/docs/diskcache/ which your project refs for benchmarks :) I added some benchmark data to the Trac ticket which may interest you.

Thank you, Josh and Adam, for the +1's. I've summarized the feedback and updated the ticket at https://code.djangoproject.com/ticket/28977 It's now marked as Accepted and Has patch. I've created a pull request at https://github.com/django/django/pull/9555 Please review when able.

Grant

Ps. As always the docs are excellent. Even the docs for contributing are extremely helpful!


On Friday, January 5, 2018 at 1:46:38 PM UTC-8, Adam Johnson wrote:
I'm +1 for moving to LRU too, the eviction algorithm has always looked weird to me. And Josh's library shows there are valid uses of local memory caching in applications - perhaps moreso these days than when Django added caching and memcached was the latest thing.
 
You can also get a very nice bump in throughput if you eliminate the `validate_key` check

+1 to adding an option to disable the check as well. If you're using a LocMemCache in production, you probably don't care about compatibility with memcached, because you'll be using it for different types of data.

On 5 January 2018 at 02:53, Josh Smeaton <[hidden email]> wrote:
To lend some weight to this, I've implemented an LRU loc mem cache and have done some benchmarking. There are some graphs in the readme: https://github.com/kogan/django-lrucache-backend - which I've written a little about https://devblog.kogan.com/blog/a-smarter-local-memory-django-cache-backend (I don't think my particular implementation is useful to core, as it relies on a 3rd party C lib, but using OrderedDict is cool!).

You can also get a very nice bump in throughput if you eliminate the `validate_key` check, which does a character by character check of the key to avoid issues with particular characters in memcache.

We don't want to be promoting locmemcache too much, but that said, if we can provide a better default then we should in my opinion.

On Friday, 5 January 2018 10:12:39 UTC+11, Grant Jenks wrote:
Hi all--

Long time user, first time poster, here. Thank you all for Django!

The current local memory cache (locmem) in Django uses a pseudo-random culling strategy. Rather than random, the OrderedDict data type can be used to implement an LRU eviction policy. A prototype implementation is already used by functools.lru_cache and Python 3 now supports OrderedDict.move_to_end and OrderedDict.popitem to ease the implementation.


Is there a consensus as to the value of these changes?

Sincerely,
Grant Jenks

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-develop...@googlegroups.com.
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/fdb91901-c378-4258-9201-d24a9f5f103e%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--
Adam

--
You received this message because you are subscribed to a topic in the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/django-developers/Gz2XqtoYmNk/unsubscribe.
To unsubscribe from this group and all its topics, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/933c2a3e-896d-45c8-a1a9-17ef8abf42c5%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/CAG0JsGw%3DdFr33sTp93JuEHBBbLnjYfO0w5kG4%3Dnab58F7Omcsg%40mail.gmail.com.

For more options, visit https://groups.google.com/d/optout.



--
Adam

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/CAMyDDM2vdZ2a1YoeO26dYtDg%3Dz7mzfpFmb1fvfue6wWuFiEKUw%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Change Local Memory Cache to Use LRU #28977

Josh Smeaton
Yup, good analysis, good numbers, thanks for running those. I'm happy with those results and think we should proceed.

On Thursday, 11 January 2018 05:11:56 UTC+11, Adam Johnson wrote:
Grant, you're a star. I think the tradeoff is acceptable too.

On 10 January 2018 at 17:05, Grant Jenks <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="J5zMed7WEQAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">grant...@...> wrote:
I was able to run the more extensive benchmarks under no-contention and high-contention scenarios with measurements at the 50th, 90th, 99th, and 100th percentiles. I updated the ticket at <a href="https://code.djangoproject.com/ticket/28977" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fcode.djangoproject.com%2Fticket%2F28977\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHQ0hGbYyb218MyfDEYKYOREfJAcw&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fcode.djangoproject.com%2Fticket%2F28977\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHQ0hGbYyb218MyfDEYKYOREfJAcw&#39;;return true;">https://code.djangoproject.com/ticket/28977 with the results.

Under high-contention scenarios, the RWLock did serve a purpose, albeit a rather limited one. There's a small tradeoff to be had but I think it's easy to accept. Note that the benchmark does not include a miss-rate penalty which the LRU-eviction policy will almost certainly improve compared with the current random-eviction policy.

Grant


On Mon, Jan 8, 2018 at 2:25 PM, Josh Smeaton <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="J5zMed7WEQAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">josh.s...@...> wrote:
Nice to meet you too. Your benchmarking code was extremely handy when I was profiling lru-cache-backend, so thank you!

Are you able to run the same benchmarks using this version of the cache to see how it performs in low/medium/high eviction scenarios? I think those benchmarks will be nicer than the simpler cache.get() ones you have on the ticket.

I'll get to reviewing that change some time this week regardless.




On Tuesday, 9 January 2018 08:58:55 UTC+11, Grant Jenks wrote:
Josh, it's nice to meet you here. I cited your django-lrucache-backend project in the original post of the Trac ticket. I'm also the author of DiskCache <a href="http://www.grantjenks.com/docs/diskcache/" rel="nofollow" target="_blank" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.grantjenks.com%2Fdocs%2Fdiskcache%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHmBdgKSecQCGiYBnsgbdgET08WfQ&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.grantjenks.com%2Fdocs%2Fdiskcache%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHmBdgKSecQCGiYBnsgbdgET08WfQ&#39;;return true;">http://www.grantjenks.com/docs/diskcache/ which your project refs for benchmarks :) I added some benchmark data to the Trac ticket which may interest you.

Thank you, Josh and Adam, for the +1's. I've summarized the feedback and updated the ticket at <a href="https://code.djangoproject.com/ticket/28977" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fcode.djangoproject.com%2Fticket%2F28977\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHQ0hGbYyb218MyfDEYKYOREfJAcw&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fcode.djangoproject.com%2Fticket%2F28977\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHQ0hGbYyb218MyfDEYKYOREfJAcw&#39;;return true;">https://code.djangoproject.com/ticket/28977 It's now marked as Accepted and Has patch. I've created a pull request at <a href="https://github.com/django/django/pull/9555" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fdjango%2Fdjango%2Fpull%2F9555\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNE-ctig5K2gfegpuUGPUUSHndBFEg&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fdjango%2Fdjango%2Fpull%2F9555\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNE-ctig5K2gfegpuUGPUUSHndBFEg&#39;;return true;">https://github.com/django/django/pull/9555 Please review when able.

Grant

Ps. As always the docs are excellent. Even the docs for contributing are extremely helpful!


On Friday, January 5, 2018 at 1:46:38 PM UTC-8, Adam Johnson wrote:
I'm +1 for moving to LRU too, the eviction algorithm has always looked weird to me. And Josh's library shows there are valid uses of local memory caching in applications - perhaps moreso these days than when Django added caching and memcached was the latest thing.
 
You can also get a very nice bump in throughput if you eliminate the `validate_key` check

+1 to adding an option to disable the check as well. If you're using a LocMemCache in production, you probably don't care about compatibility with memcached, because you'll be using it for different types of data.

On 5 January 2018 at 02:53, Josh Smeaton <[hidden email]> wrote:
To lend some weight to this, I've implemented an LRU loc mem cache and have done some benchmarking. There are some graphs in the readme: <a href="https://github.com/kogan/django-lrucache-backend" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fkogan%2Fdjango-lrucache-backend\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNF8UeHYJUZUrpVwQiE5XArFuLAk7Q&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fkogan%2Fdjango-lrucache-backend\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNF8UeHYJUZUrpVwQiE5XArFuLAk7Q&#39;;return true;">https://github.com/kogan/django-lrucache-backend - which I've written a little about <a href="https://devblog.kogan.com/blog/a-smarter-local-memory-django-cache-backend" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fdevblog.kogan.com%2Fblog%2Fa-smarter-local-memory-django-cache-backend\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFgkmocWazecITCtXQGAAkcBULMBQ&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fdevblog.kogan.com%2Fblog%2Fa-smarter-local-memory-django-cache-backend\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFgkmocWazecITCtXQGAAkcBULMBQ&#39;;return true;">https://devblog.kogan.com/blog/a-smarter-local-memory-django-cache-backend (I don't think my particular implementation is useful to core, as it relies on a 3rd party C lib, but using OrderedDict is cool!).

You can also get a very nice bump in throughput if you eliminate the `validate_key` check, which does a character by character check of the key to avoid issues with particular characters in memcache.

We don't want to be promoting locmemcache too much, but that said, if we can provide a better default then we should in my opinion.

On Friday, 5 January 2018 10:12:39 UTC+11, Grant Jenks wrote:
Hi all--

Long time user, first time poster, here. Thank you all for Django!

The current local memory cache (locmem) in Django uses a pseudo-random culling strategy. Rather than random, the OrderedDict data type can be used to implement an LRU eviction policy. A prototype implementation is already used by functools.lru_cache and Python 3 now supports OrderedDict.move_to_end and OrderedDict.popitem to ease the implementation.

I have created an example set of changes at <a href="https://github.com/grantjenks/django/tree/ticket_28977" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fgrantjenks%2Fdjango%2Ftree%2Fticket_28977\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNF4G4MFpOnCooaGn7gF8oHZcKYgdw&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fgrantjenks%2Fdjango%2Ftree%2Fticket_28977\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNF4G4MFpOnCooaGn7gF8oHZcKYgdw&#39;;return true;">https://github.com/grantjenks/django/tree/ticket_28977 in commit <a href="https://github.com/grantjenks/django/commit/b06574f6713d4b7d367d7a11e0268fb62f5fd1d1" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fgrantjenks%2Fdjango%2Fcommit%2Fb06574f6713d4b7d367d7a11e0268fb62f5fd1d1\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHoXe5qhxdrU2CgH_Cq8MgtcfwQZA&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fgrantjenks%2Fdjango%2Fcommit%2Fb06574f6713d4b7d367d7a11e0268fb62f5fd1d1\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHoXe5qhxdrU2CgH_Cq8MgtcfwQZA&#39;;return true;">https://github.com/grantjenks/django/commit/b06574f6713d4b7d367d7a11e0268fb62f5fd1d1

Is there a consensus as to the value of these changes?

Sincerely,
Grant Jenks

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-develop...@googlegroups.com.
To post to this group, send email to [hidden email].
Visit this group at <a href="https://groups.google.com/group/django-developers" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://groups.google.com/group/django-developers&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/group/django-developers&#39;;return true;">https://groups.google.com/group/django-developers.
To view this discussion on the web visit <a href="https://groups.google.com/d/msgid/django-developers/fdb91901-c378-4258-9201-d24a9f5f103e%40googlegroups.com?utm_medium=email&amp;utm_source=footer" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://groups.google.com/d/msgid/django-developers/fdb91901-c378-4258-9201-d24a9f5f103e%40googlegroups.com?utm_medium\x3demail\x26utm_source\x3dfooter&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/d/msgid/django-developers/fdb91901-c378-4258-9201-d24a9f5f103e%40googlegroups.com?utm_medium\x3demail\x26utm_source\x3dfooter&#39;;return true;">https://groups.google.com/d/msgid/django-developers/fdb91901-c378-4258-9201-d24a9f5f103e%40googlegroups.com.

For more options, visit <a href="https://groups.google.com/d/optout" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;">https://groups.google.com/d/optout.



--
Adam

--
You received this message because you are subscribed to a topic in the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this topic, visit <a href="https://groups.google.com/d/topic/django-developers/Gz2XqtoYmNk/unsubscribe" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://groups.google.com/d/topic/django-developers/Gz2XqtoYmNk/unsubscribe&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/d/topic/django-developers/Gz2XqtoYmNk/unsubscribe&#39;;return true;">https://groups.google.com/d/topic/django-developers/Gz2XqtoYmNk/unsubscribe.
To unsubscribe from this group and all its topics, send an email to <a href="javascript:" target="_blank" gdf-obfuscated-mailto="J5zMed7WEQAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">django-develop...@googlegroups.com.
To post to this group, send email to <a href="javascript:" target="_blank" gdf-obfuscated-mailto="J5zMed7WEQAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">django-d...@googlegroups.com.
Visit this group at <a href="https://groups.google.com/group/django-developers" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://groups.google.com/group/django-developers&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/group/django-developers&#39;;return true;">https://groups.google.com/group/django-developers.
To view this discussion on the web visit <a href="https://groups.google.com/d/msgid/django-developers/933c2a3e-896d-45c8-a1a9-17ef8abf42c5%40googlegroups.com?utm_medium=email&amp;utm_source=footer" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://groups.google.com/d/msgid/django-developers/933c2a3e-896d-45c8-a1a9-17ef8abf42c5%40googlegroups.com?utm_medium\x3demail\x26utm_source\x3dfooter&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/d/msgid/django-developers/933c2a3e-896d-45c8-a1a9-17ef8abf42c5%40googlegroups.com?utm_medium\x3demail\x26utm_source\x3dfooter&#39;;return true;">https://groups.google.com/d/msgid/django-developers/933c2a3e-896d-45c8-a1a9-17ef8abf42c5%40googlegroups.com.

For more options, visit <a href="https://groups.google.com/d/optout" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;">https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to <a href="javascript:" target="_blank" gdf-obfuscated-mailto="J5zMed7WEQAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">django-develop...@googlegroups.com.
To post to this group, send email to <a href="javascript:" target="_blank" gdf-obfuscated-mailto="J5zMed7WEQAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">django-d...@googlegroups.com.
Visit this group at <a href="https://groups.google.com/group/django-developers" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://groups.google.com/group/django-developers&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/group/django-developers&#39;;return true;">https://groups.google.com/group/django-developers.
To view this discussion on the web visit <a href="https://groups.google.com/d/msgid/django-developers/CAG0JsGw%3DdFr33sTp93JuEHBBbLnjYfO0w5kG4%3Dnab58F7Omcsg%40mail.gmail.com?utm_medium=email&amp;utm_source=footer" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://groups.google.com/d/msgid/django-developers/CAG0JsGw%3DdFr33sTp93JuEHBBbLnjYfO0w5kG4%3Dnab58F7Omcsg%40mail.gmail.com?utm_medium\x3demail\x26utm_source\x3dfooter&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/d/msgid/django-developers/CAG0JsGw%3DdFr33sTp93JuEHBBbLnjYfO0w5kG4%3Dnab58F7Omcsg%40mail.gmail.com?utm_medium\x3demail\x26utm_source\x3dfooter&#39;;return true;">https://groups.google.com/d/msgid/django-developers/CAG0JsGw%3DdFr33sTp93JuEHBBbLnjYfO0w5kG4%3Dnab58F7Omcsg%40mail.gmail.com.

For more options, visit <a href="https://groups.google.com/d/optout" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;">https://groups.google.com/d/optout.



--
Adam

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/ff65dfa6-fb7c-441e-8095-5cfc1a983f4e%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.