<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; color: rgb(0, 0, 0); font-size: 14px; font-family: Calibri, sans-serif;">
<div>Same here; I've done pretty big memcache (and similar technologies) scale caching & invalidations at Y! before so here to help…</div>
<div><br>
</div>
<span id="OLK_SRC_BODY_SECTION">
<div style="font-family:Calibri; font-size:11pt; text-align:left; color:black; BORDER-BOTTOM: medium none; BORDER-LEFT: medium none; PADDING-BOTTOM: 0in; PADDING-LEFT: 0in; PADDING-RIGHT: 0in; BORDER-TOP: #b5c4df 1pt solid; BORDER-RIGHT: medium none; PADDING-TOP: 3pt">
<span style="font-weight:bold">From: </span>Morgan Fainberg <<a href="mailto:m@metacloud.com">m@metacloud.com</a>><br>
<span style="font-weight:bold">Reply-To: </span>"OpenStack Development Mailing List (not for usage questions)" <<a href="mailto:openstack-dev@lists.openstack.org">openstack-dev@lists.openstack.org</a>><br>
<span style="font-weight:bold">Date: </span>Thursday, January 23, 2014 at 4:17 PM<br>
<span style="font-weight:bold">To: </span>"OpenStack Development Mailing List (not for usage questions)" <<a href="mailto:openstack-dev@lists.openstack.org">openstack-dev@lists.openstack.org</a>><br>
<span style="font-weight:bold">Subject: </span>Re: [openstack-dev] [oslo] memoizer aka cache<br>
</div>
<div><br>
</div>
<div>
<div>
<div dir="ltr">Yes! There is a reason Keystone has a very small footprint of caching/invalidation done so far.  It really needs to be correct when it comes to proper invalidation logic.  I am happy to offer some help in determining logic for caching/invalidation
 with Dogpile.cache in mind as we get it into oslo and available for all to use.
<div><br>
</div>
<div>--Morgan</div>
<div><br>
</div>
</div>
<div class="gmail_extra"><br>
<br>
<div class="gmail_quote">On Thu, Jan 23, 2014 at 2:54 PM, Joshua Harlow <span dir="ltr">
<<a href="mailto:harlowja@yahoo-inc.com" target="_blank">harlowja@yahoo-inc.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Sure, no cancelling cases of conscious usage, but we need to be careful<br>
here and make sure its really appropriate. Caching and invalidation<br>
techniques are right up there in terms of problems that appear easy and<br>
simple to initially do/use, but doing it correctly is really really hard<br>
(especially at any type of scale).<br>
<br>
-Josh<br>
<div class="im"><br>
On 1/23/14, 1:35 PM, "Renat Akhmerov" <<a href="mailto:rakhmerov@mirantis.com">rakhmerov@mirantis.com</a>> wrote:<br>
<br>
><br>
>On 23 Jan 2014, at 08:41, Joshua Harlow <<a href="mailto:harlowja@yahoo-inc.com">harlowja@yahoo-inc.com</a>> wrote:<br>
><br>
>> So to me memoizing is typically a premature optimization in a lot of<br>
>>cases. And doing it incorrectly leads to overfilling the python<br>
>>processes memory (your global dict will have objects in it that can't be<br>
>>garbage collected, and with enough keys+values being stored will act<br>
>>just like a memory leak; basically it acts as a new GC root object in a<br>
>>way) or more cache invalidation races/inconsistencies than just<br>
</div>
>>recomputing the initial valueŠ<br>
<div class="HOEnZb">
<div class="h5">><br>
>I agree with your concerns here. At the same time, I think this thinking<br>
>shouldn¹t cancel cases of conscious usage of caching technics. A decent<br>
>cache implementation would help to solve lots of performance problems<br>
>(which eventually becomes a concern for any project).<br>
><br>
>> Overall though there are a few caching libraries I've seen being used,<br>
>>any of which could be used for memoization.<br>
>><br>
>> -<br>
>><a href="https://github.com/openstack/oslo-incubator/tree/master/openstack/common/" target="_blank">https://github.com/openstack/oslo-incubator/tree/master/openstack/common/</a><br>
>>cache<br>
>> -<br>
>><a href="https://github.com/openstack/oslo-incubator/blob/master/openstack/common/" target="_blank">https://github.com/openstack/oslo-incubator/blob/master/openstack/common/</a><br>
>>memorycache.py<br>
><br>
>I looked at the code. I have lots of question to the implementation (like<br>
>cache eviction policies, whether or not it works well with green threads,<br>
>but I think it¹s a subject for a separate discussion though). Could you<br>
>please share your experience of using it? Were there specific problems<br>
>that you could point to? May be they are already described somewhere?<br>
><br>
>> - dogpile cache @ <a href="https://pypi.python.org/pypi/dogpile.cache" target="_blank">
https://pypi.python.org/pypi/dogpile.cache</a><br>
><br>
>This one looks really interesting in terms of claimed feature set. It<br>
>seems to be compatible with Python 2.7, not sure about 2.6. As above, it<br>
>would be cool you told about your experience with it.<br>
><br>
><br>
>> I am personally weary of using them for memoization, what expensive<br>
>>method calls do u see the complexity of this being useful? I didn't<br>
>>think that many method calls being done in openstack warranted the<br>
>>complexity added by doing this (premature optimization is the root of<br>
>>all evil...). Do u have data showing where it would be<br>
>>applicable/beneficial?<br>
><br>
>I believe there¹s a great deal of use cases like caching db objects or<br>
>more generally caching any heavy objects involving interprocess<br>
>communication. For instance, API clients may be caching objects that are<br>
>known to be immutable on the server side.<br>
><br>
><br>
>><br>
>> Sent from my really tiny device...<br>
>><br>
>>> On Jan 23, 2014, at 8:19 AM, "Shawn Hartsock" <<a href="mailto:hartsock@acm.org">hartsock@acm.org</a>> wrote:<br>
>>><br>
>>> I would like to have us adopt a memoizing caching library of some kind<br>
>>> for use with OpenStack projects. I have no strong preference at this<br>
>>> time and I would like suggestions on what to use.<br>
>>><br>
>>> I have seen a number of patches where people have begun to implement<br>
>>> their own caches in dictionaries. This typically confuses the code and<br>
>>> mixes issues of correctness and performance in code.<br>
>>><br>
>>> Here's an example:<br>
>>><br>
>>> We start with:<br>
>>><br>
>>> def my_thing_method(some_args):<br>
>>>   # do expensive work<br>
>>>   return value<br>
>>><br>
>>> ... but a performance problem is detected... maybe the method is<br>
>>> called 15 times in 10 seconds but then not again for 5 minutes and the<br>
>>> return value can only logically change every minute or two... so we<br>
>>> end up with ...<br>
>>><br>
>>> _GLOBAL_THING_CACHE = {}<br>
>>><br>
>>> def my_thing_method(some_args):<br>
>>>   key = key_from(some_args)<br>
>>>    if key in _GLOBAL_THING_CACHE:<br>
>>>        return _GLOBAL_THING_CACHE[key]<br>
>>>    else:<br>
>>>         # do expensive work<br>
>>>         _GLOBAL_THING_CACHE[key] = value<br>
>>>         return value<br>
>>><br>
>>> ... which is all well and good... but now as a maintenance programmer<br>
>>> I need to comprehend the cache mechanism, when cached values are<br>
>>> invalidated, and if I need to debug the "do expensive work" part I<br>
>>> need to tease out some test that prevents the cache from being hit.<br>
>>> Plus I've introduced a new global variable. We love globals right?<br>
>>><br>
>>> I would like us to be able to say:<br>
>>><br>
>>> @memoize(seconds=10)<br>
>>> def my_thing_method(some_args):<br>
>>>   # do expensive work<br>
>>>   return value<br>
>>><br>
>>> ... where we're clearly addressing the performance issue by<br>
>>> introducing a cache and limiting it's possible impact to 10 seconds<br>
>>> which allows for the idea that "do expensive work" has network calls<br>
>>> to systems that may change state outside of this Python process.<br>
>>><br>
>>> I'd like to see this done because I would like to have a place to<br>
>>> point developers to during reviews... to say: use "common/memoizer" or<br>
>>> use "Bob's awesome memoizer" because Bob has worked out all the cache<br>
>>> problems already and you can just use it instead of worrying about<br>
>>> introducing new bugs by building your own cache.<br>
>>><br>
>>> Does this make sense? I'd love to contribute something... but I wanted<br>
>>> to understand why this state of affairs has persisted for a number of<br>
>>> years... is there something I'm missing?<br>
>>><br>
>>> --<br>
>>> # Shawn.Hartsock - twitter: @hartsock - <a href="http://plus.google.com/+ShawnHartsock" target="_blank">
plus.google.com/+ShawnHartsock</a><br>
>>><br>
>>> _______________________________________________<br>
>>> OpenStack-dev mailing list<br>
>>> <a href="mailto:OpenStack-dev@lists.openstack.org">OpenStack-dev@lists.openstack.org</a><br>
>>> <a href="http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev" target="_blank">
http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev</a><br>
>><br>
>> _______________________________________________<br>
>> OpenStack-dev mailing list<br>
>> <a href="mailto:OpenStack-dev@lists.openstack.org">OpenStack-dev@lists.openstack.org</a><br>
>> <a href="http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev" target="_blank">
http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev</a><br>
><br>
><br>
>_______________________________________________<br>
>OpenStack-dev mailing list<br>
><a href="mailto:OpenStack-dev@lists.openstack.org">OpenStack-dev@lists.openstack.org</a><br>
><a href="http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev" target="_blank">http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev</a><br>
<br>
<br>
_______________________________________________<br>
OpenStack-dev mailing list<br>
<a href="mailto:OpenStack-dev@lists.openstack.org">OpenStack-dev@lists.openstack.org</a><br>
<a href="http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev" target="_blank">http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev</a><br>
</div>
</div>
</blockquote>
</div>
<br>
</div>
</div>
</div>
</span>
</body>
</html>