Thank.<div>That works.<br><br><div class="gmail_quote">On Mon, Jul 20, 2009 at 4:24 AM, Drew Smathers <span dir="ltr">&lt;<a href="mailto:drew.smathers@gmail.com">drew.smathers@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;">
<div><div></div><div class="h5">On Fri, Jul 17, 2009 at 3:14 AM, Daniel<br>
Yang&lt;<a href="mailto:daniel.yang.zhenyu@gmail.com">daniel.yang.zhenyu@gmail.com</a>&gt; wrote:<br>
&gt; Hi team,<br>
&gt; I am doing some experiments on  Storm(twisted integration) and Nevow to see<br>
&gt; how they can work together.<br>
&gt; I went across a RuntimeError when I kept refreshing a page. It said:<br>
&gt; ------------------------------------------------log--------------------------------------------------------------<br>
&gt; 2009-07-17 14:58:42+0800 [-] [Failure instance: Traceback: &lt;type<br>
&gt; &#39;exceptions.RuntimeError&#39;&gt;: Resolving lazy values with the Twisted wrapper<br>
&gt; is not possible right now! Please refetch your object using<br>
&gt; store.get/store.find<br>
&gt; --- &lt;exception caught here&gt; ---<br>
&gt; /Library/Python/2.5/site-packages/Twisted-8.2.0_r27097-py2.5-macosx-10.5-i386.egg/twisted/internet/defer.py:323:_runCallbacks<br>
&gt; /Users/Daniel/Documents/workspace/NovaWeb/src/web/FromLocation.py:47:cb_all<br>
&gt; /Library/Python/2.5/site-packages/storm-0.14-py2.5-macosx-10.5-i386.egg/storm/properties.py:60:__get__<br>
&gt; /Library/Python/2.5/site-packages/storm-0.14-py2.5-macosx-10.5-i386.egg/storm/variables.py:178:get<br>
&gt; /Library/Python/2.5/site-packages/storm-0.14-py2.5-macosx-10.5-i386.egg/storm/event.py:53:emit<br>
&gt; /Library/Python/2.5/site-packages/storm-0.14-py2.5-macosx-10.5-i386.egg/storm/twisted/store.py:238:_resolve_lazy_value<br>
&gt; ]<br>
&gt; ------------------------------------------------log--------------------------------------------------------------<br>
&gt; (latest storm and Nevow, Twisted.Python 2.5.1, Osx 10.5.7)<br>
&gt; I am using StorePool to manage connections:<br>
&gt; ------------------------------------------------code--------------------------------------------------------------<br>
&gt;<br>
&gt; from storm.databases.sqlite import SQLite<br>
&gt;<br>
&gt; from storm.uri import URI<br>
&gt;<br>
&gt; from storm.twisted.store import StorePool<br>
&gt;<br>
&gt; database = SQLite(URI(&#39;sqlite:///test.db&#39;))<br>
&gt;<br>
&gt; pool = StorePool(database, 5, 10)<br>
&gt;<br>
&gt; pool.start()<br>
&gt;<br>
&gt; ------------------------------------------------code--------------------------------------------------------------<br>
&gt;<br>
&gt;<br>
&gt; On this page, I have 2 renders to access database(sqlite) with storm(People<br>
&gt; list and Shop list):<br>
&gt;<br>
&gt; ------------------------------------------------code--------------------------------------------------------------<br>
&gt;<br>
&gt; def render_PeopleList(self, ctx, data):<br>
&gt;<br>
&gt; pat = inevow.IQ(ctx).patternGenerator(&#39;PeopleItem&#39;)<br>
&gt;<br>
&gt; def cb_find(results, s):<br>
&gt;<br>
&gt; results.config(offset=0, limit=10)<br>
&gt;<br>
&gt; return results.all().addCallback(cb_all, s)<br>
&gt;<br>
&gt; def cb_all(items, s):<br>
&gt;<br>
&gt; #recycle the store.<br>
&gt;<br>
&gt; pool.put(s)<br>
&gt;<br>
&gt; ps = []<br>
&gt;<br>
&gt; for item in items:<br>
&gt;<br>
&gt; p = pat()<br>
&gt;<br>
&gt; p.fillSlots(&#39;nickname&#39;, item.nickname)<br>
&gt;<br>
&gt; ps.append(p)<br>
&gt;<br>
&gt; return ctx.tag[ ps ]<br>
&gt;<br>
&gt; def cb_get(s):<br>
&gt;<br>
&gt; return s.find(People).addBoth(cb_find, s)<br>
&gt;<br>
&gt; return pool.get().addCallback(cb_get).addErrback(lambda error:<br>
&gt; log.msg(error))<br>
&gt;<br>
&gt; ------------------------------------------------code--------------------------------------------------------------<br>
&gt; and shop render is pretty much like this.<br>
&gt;<br>
&gt; In file &quot;storm/twisted/store.py:238&quot;, I notice the _resolve_lazy_value<br>
&gt; function does nothing but raising an error.<br>
&gt; Do anyone have any idea of what is the problem?<br>
&gt; Thanks.<br>
<br>
<br>
</div></div>This is the problem:<br>
<br>
  pool.put(s)<br>
  ... doing something with object from store `s&#39;<br>
<br>
Once you put a store back in the pool this will effectively rollback<br>
the store.  Now being in a new transaction, referring to an attribute<br>
on the object will try to load the most recent data from the store to<br>
enforce &quot;serializable&quot; semantics.  twisted-integration can&#39;t manage<br>
this because attribute access isn&#39;t can&#39;t be deferred in the store&#39;s<br>
thread -- without necessitating a very awkward API.<br>
<br>
I think some good practices to avoid lazy value errors are:<br>
<br>
1. Do everything you need to with objects before putting store back in<br>
pool and then discard those objects<br>
2. Re-fetch objects if you have done any inserts/updates (in same tx)<br>
before referencing attributes on them<br>
3. If you need to keep references lying around (caching as an<br>
example), create read-only version of those objects which aren&#39;t<br>
attached to store.<br>
<br>
Lastly, unrelated to you core problem, but this code looks like a unit<br>
test for twisted-integration. The tests are written to be compatible<br>
with older versions of Python, so you may consider using<br>
inlineCallbacks() to make your life easier if your deployment target<br>
is 2.5&gt;.  There is also a transact() method which takes care of<br>
putting the store back in pool after your function exits.  An example<br>
using inlineCallbacks() and transact():<br>
<br>
from twisted.internet.defer import inlineCallbacks, returnValue<br>
<br>
@inlineCallbacks<br>
def transaction(store, offset, limit):<br>
    dr = yield store.find(People)<br>
    dr.config(offset=offset, limit=limit)<br>
    items = yield dr.all()<br>
    for item in items:<br>
        ... do stuff with item<br>
    # commit tx if you&#39;ve changed objects<br>
    yield store.commit()<br>
    returnValue(ctx_tag[ps])<br>
<br>
pool.transact(transaction, 0, 10)<br>
<br>
--<br>
\\\\\/\&quot;/\\\\\\\\\\\<br>
\\\\/ // //\/\\\\\\\<br>
\\\/  \\// /\ \/\\\\<br>
\\/ /\/ / /\/ /\ \\\<br>
\/ / /\/ /\  /\\\ \\<br>
/ /\\\  /\\\ \\\\\/\<br>
\/\\\\\/\\\\\/\\\\\\<br>
               d.p.s<br>
</blockquote></div><br><br clear="all"><br>-- <br>-----------------------------------------------<br>Yours<br>Faithfully<br><br>Daniel Yang<br>
</div>