Sometimes this error appear: "RuntimeError: Result cannot be set twice"

69 views
Skip to first unread message

hovu96

unread,
Oct 26, 2011, 5:05:24 AM10/26/11
to appengine-...@googlegroups.com
I cannot reproduce this error with a simple code snipped but it appears sometimes in several apps:

Result cannot be set twice.
Traceback (most recent call last):
  File ".../webapp2.py", line 1511, in __call__
    rv = self.handle_exception(request, response, e)
  File ".../webapp2.py", line 1505, in __call__
    rv = self.router.dispatch(request, response)
  File ".../webapp2.py", line 1253, in default_dispatcher
    return route.handler_adapter(request, response)
  File ".../webapp2.py", line 1077, in __call__
    return handler.dispatch()
  File ".../webapp2.py", line 547, in dispatch
    return self.handle_exception(e, self.app.debug)
  File ".../webapp2.py", line 545, in dispatch
    return method(*args, **kwargs)
  File ".../ndb/context.py", line 1062, in add_context_wrapper
    ctx.flush().check_success()
  File ".../ndb/tasklets.py", line 273, in check_success
    self.wait()
  File ".../ndb/tasklets.py", line 257, in wait
    if not ev.run1():
  File ".../ndb/eventloop.py", line 190, in run1
    delay = self.run0()
  File ".../ndb/eventloop.py", line 179, in run0
    callback(*args, **kwds)
  File ".../ndb/eventloop.py", line 94, in help_multi_rpc_along
    c(*a, **k)
  File ".../ndb/tasklets.py", line 378, in _on_rpc_completion
    self._help_tasklet_along(gen, result)
  File ".../ndb/tasklets.py", line 326, in _help_tasklet_along
    self.set_result(result)
  File ".../ndb/tasklets.py", line 217, in set_result
    raise RuntimeError('Result cannot be set twice.')
RuntimeError: Result cannot be set twice.

I'm using NDB version 0.9 but this error appears in earlier versions too. Strangely I see the problem only since a few weeks. Before that everything has worked and I *think* that I have not made any relevant code changes.

I cannot post a simple code samples because this error appears in many situations.

Any idea what's going wrong?

Thanks!

Beech Horn

unread,
Oct 26, 2011, 5:07:21 AM10/26/11
to appengine-...@googlegroups.com
If you can post some example code that triggers this, I'll have a quick look through and see if there is anything obvious.

It appears that set_result is being called more than once on a future.

Vladimir Mihailenco

unread,
Oct 26, 2011, 5:28:49 AM10/26/11
to appengine-ndb-discuss
Confirm, just updated and see this exception almost everywhere...
Still can't reproduce, but probably future dump can help:

<Future 3275d10 created by tasklet_wrapper(tasklets.py:907) for
tasklet _get_tasklet(context.py:229); result None>
Created by tasklet_wrapper(tasklets.py:907)
called by run_queue(context.py:112)
called by action(context.py:151)
called by _on_idle(context.py:118)
called by run_idle(eventloop.py:129)
called by run0(eventloop.py:154)
called by run1(eventloop.py:190)
called by wait(tasklets.py:258)
called by check_success(tasklets.py:274)
called by get_result(tasklets.py:279)

Strange this is that result is None, but future is already done...

Vladimir Mihailenco

unread,
Oct 26, 2011, 5:33:26 AM10/26/11
to appengine-ndb-discuss
Forgot to say that this error happens only in production (GAE
instance), on dev_appserver same views do not produce any errors.

Vladimir Mihailenco

unread,
Oct 26, 2011, 8:37:36 AM10/26/11
to appengine-ndb-discuss
I am able to reproduce with such simple code:

@tracker.route('/test1/')
@context.toplevel
def test1():
class Foo(model.Model):
name = model.StringProperty(required=True)

@classmethod
@tasklets.tasklet
def get_by_ids_async(cls, ids):
keys = [model.Key(cls, id) for id in ids]
foos = yield model.get_multi_async(keys)
raise tasklets.Return(foos)

foos = yield Foo.get_by_ids_async([1, 2, 3])
logging.error('foos: %r' % foos)

raise tasklets.Return('OK')

Can someone check this on webapp?

Vladimir Mihailenco

unread,
Oct 26, 2011, 9:42:24 AM10/26/11
to appengine-ndb-discuss
My issue was solved changing runtime from python27 to python. Probably
I am doing something wrong (I followed Nick's tutorial:
http://blog.notdot.net/2011/10/Migrating-to-Python-2-7-part-1-Threadsafe),
but:

- with threadsafe: true I am getting a lot of deadlocks in futures.
- with threadsafe: false I am getting random RuntimeError('Result
cannot be set twice.') on some views.

Beech Horn

unread,
Oct 26, 2011, 9:42:45 AM10/26/11
to appengine-...@googlegroups.com
Can only reproduce on Python27 HRD threadsafe (please shout if you can replicate on another setup) as it doesn't seem to occur on Python25 M/S.

If you have an empty memcache then get it fails.

Once memcache is primed the errors stops occurring.

For now, you may wish to disable memcache as a temporary measure or rollback to 0.7 or below.

Guido van Rossum

unread,
Oct 26, 2011, 1:10:07 PM10/26/11
to appengine-...@googlegroups.com

I filed http://code.google.com/p/appengine-ndb-experiment/issues/detail?id=85
to track this. Please add further details there. I have formulated a
tentative theory there.

--
--Guido van Rossum (python.org/~guido)

Guido van Rossum

unread,
Oct 26, 2011, 3:34:55 PM10/26/11
to appengine-...@googlegroups.com

For anyone whom this is blocking, I've got a fix in the bug which you
can apply to ndb/eventloop.py to make the problem go away.

Guido van Rossum

unread,
Oct 27, 2011, 11:58:33 AM10/27/11
to appengine-...@googlegroups.com

Even better news: the fix has been submitted. I'll release 0.9.1 with
the fix shortly.

hovu96

unread,
Oct 28, 2011, 3:02:34 AM10/28/11
to appengine-...@googlegroups.com
This fix also works in my app, thanks!
Reply all
Reply to author
Forward
0 new messages