Skip to content

Instantly share code, notes, and snippets.

@sublee
Last active May 13, 2016 02:34
Show Gist options
  • Save sublee/4b5796ad7a56bf2342fefe5d40b0332b to your computer and use it in GitHub Desktop.
Save sublee/4b5796ad7a56bf2342fefe5d40b0332b to your computer and use it in GitHub Desktop.
Wrong callback issue with gcouchbase

When I ignore GreenletExit during getting foo, getting bar on the same greenlet returns the result of foo instead of bar. It's a critical issue because we could not believe the result of any operations.

This example reproduces the case of "wrong callback". I tested this with couchbase-2.8.0. But I've been experiencing the issue from long time ago.

from gcouchbase.bucket import Bucket
import gevent
bucket = Bucket('couchbase://localhost/default')
bucket.upsert('foo', 'foo')
bucket.upsert('bar', 'bar')
def load_foo_and_bar_forever():
while True:
try:
r = bucket.get('foo')
except gevent.GreenletExit:
continue
else:
assert r.value == 'foo', r
try:
r = bucket.get('bar')
except gevent.GreenletExit:
continue
else:
assert r.value == 'bar', r
def kill_greenlet_forever(g):
while True:
gevent.sleep(0.1)
g.kill()
g = gevent.spawn(load_foo_and_bar_forever)
gevent.joinall([g, gevent.spawn(kill_greenlet_forever, g)])
from gcouchbase.bucket import Bucket
import gevent
bucket = Bucket('couchbase://localhost/default')
bucket.upsert('foo', 'foo')
bucket.upsert('bar', 'bar')
def load_foo_and_bar_within_timeout_forever():
while True:
try:
with gevent.Timeout(0.0000001):
r = bucket.get('foo')
except gevent.Timeout:
continue
else:
assert r.value == 'foo', r
try:
with gevent.Timeout(0.0000001):
r = bucket.get('bar')
except gevent.Timeout:
continue
else:
assert r.value == 'bar', r
g = gevent.spawn(load_foo_and_bar_forever)
g.get()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment