<div><div><div><br></div><div class="gmail_quote">On Thu, Aug 27, 2009 at 8:28 AM, Kapil Thangavelu <span dir="ltr">&lt;<a href="mailto:kapil.foss@gmail.com">kapil.foss@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<br><br><div class="gmail_quote"><div><div></div><div class="h5">On Thu, Aug 27, 2009 at 7:48 AM, Stuart Bishop <span dir="ltr">&lt;<a href="mailto:stuart.bishop@canonical.com" target="_blank">stuart.bishop@canonical.com</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div>On Thu, Aug 27, 2009 at 4:56 PM, Gustavo Niemeyer&lt;<a href="mailto:gustavo@niemeyer.net" target="_blank">gustavo@niemeyer.net</a>&gt; wrote:<br>
&gt; Hey Stuart,<br>
&gt;<br>
&gt;&gt; Has anyone looked into making Storm objects pickleable? I want to<br>
&gt;&gt; stuff expensive query results into memcached.<br>
&gt;&gt;<br>
&gt;&gt; I&#39;m using ZStorm so can just use the name to refer to the Store. I can<br>
&gt;&gt; put together a MaterializedResultSet class supporting a lot of the API<br>
&gt;&gt; from a materialized list of Storm objects. I think getting the Storm<br>
&gt;&gt; objects themselves pickled is going to be the tricky bit.<br>
&gt;<br>
&gt; Pickling itself shouldn&#39;t be hard.  How do you envison an unpickled<br>
&gt; object should behave?<br>
<br>
</div>Its nice to know you don&#39;t forsee major roadblocks. I think the major<br>
difficulty is becoming familiar enough with the Storm internals - I&#39;ve<br>
never dealt with ObjectInfo and friends before.<br>
<br>
I&#39;d like it to behave like the original object as much as possible.<br>
The goal is drop in replacement of code like:<br>
<br>
   results = store.find(... complex and costly conditions ...)<br>
<br>
with something like:<br>
<br>
   results = cached(store, max_age,  ... complex and costly conditions ...)<br>
<br>
So unpickled objects can be updated and code able to traverse from the<br>
unpickled objects to objects loaded from the Store. For the Storm<br>
objects, I expect they would be indistinguishable from one loaded from<br>
the Store (assemble object, swap in the Store, inject into the cache).<br>
<br>
I don&#39;t think I need the result set to support operations like union,<br>
find,  or aggregates beyond count() so the result set can just be a<br>
list with a count() method.<br>
<div></div></blockquote><div><br></div><div><br></div></div></div><div>i have slightly different use cases for caching, i&#39;d like to be able to cache these independent of a store.</div><div>effectively separate from store, pickle, unpickle, and attach to store. analogous to sqlalchemy session</div>

<div>detach/merge functionality.</div><div><br></div><div>afaics this involves clearing out the instance object info, and possibly unhooking the event system from tracking variable changes. </div><div><br></div><div>cheers,</div>

<div><br></div><div>kapil</div><div></div></div></blockquote><div><br></div><div><br></div>i ended up making a base class to mimic the store merge/detach functionality along with the pickling support (inline below) that i needed. modifying the object when its detached is effectively an unknown op as there isn&#39;t a store to track it, although upon reattaching any subsequent modification and flushes will include the modifications while detached. hasn&#39;t been tested/used with references. <div>
<br></div><div>cheers,</div><div><br></div><div>kapil</div><div><br></div><div><div><br></div><div><div>from storm import properties, info</div><div><br></div><div>marker = object()</div><div><br></div><div>class StormPersistent( object ):</div>
<div><br></div><div>    def __getstate__( self ):</div><div>        d = {}</div><div>        for p,v in info.get_obj_info(self).variables.items():</div><div>            d[<a href="http://p.name">p.name</a>] = v.get()</div>
<div>        return d</div><div>        </div><div>    def __setstate__( self, o ):</div><div>        for p,v in info.get_obj_info( self ).variables.items():</div><div>            value = o.get( <a href="http://p.name">p.name</a>, marker )</div>
<div>            if value is marker: continue</div><div>            v.set( value, from_db=True )</div><div><br></div><div>    def detach( self ):</div><div>        obj_info = info.get_obj_info( self )</div><div>        store = obj_info.get(&#39;store&#39;)        </div>
<div>        assert not obj_info in store._dirty, &quot;Can&#39;t Detach Dirty Object&quot;</div><div>        store._remove_from_alive( obj_info )</div><div>        store._disable_change_notification( obj_info )</div><div>
        store._disable_lazy_resolving( obj_info )</div><div><br></div><div>    def attach( self, store ):</div><div>        obj_info = info.get_obj_info( self )</div><div>        obj_info[&#39;store&#39;] = store</div><div>
        store._enable_change_notification( obj_info )</div><div>        store._add_to_alive( obj_info )        </div></div></div><div>        store._enable_lazy_resolving( obj_info ) </div></div><br></div></div>