-
Notifications
You must be signed in to change notification settings - Fork 8
all() method fails when more than 64 vertices of one type exist #25
Comments
I've just verified that this occurs when using tornado gen.couroutines as well |
Hmmm, I've haven't looked closely but this seems a bit strange. The error is coming from Titan. I'll take a closer look tomorrow if you haven't figured it out. |
Yeah, I've verified that it seems to be happening in Titan: revised source: #!/usr/bin/env python
from tornado import gen
from tornado.ioloop import IOLoop
from goblin import properties, connection
from goblin.models import Vertex
class MyVertex(Vertex):
prop1 = properties.Integer()
connection.setup('ws://localhost:8182')
@gen.coroutine
def clear():
result = yield connection.execute_query('g.V().drop().iterate()')
stream = yield result.read()
return stream
@gen.coroutine
def create(i):
result = yield MyVertex.create(prop1=i)
return result
@gen.coroutine
def find(vid):
result = yield MyVertex.get(vid)
return result
@gen.coroutine
def find_all(n):
result = yield connection.execute_query(
'g.V().hasLabel(x).limit(n)',
bindings={
'x': MyVertex.get_label(),
'n': n,
},
)
stream = yield result.read()
return stream
loop = IOLoop.current()
def smash(n):
print("Clearing old vertices")
loop.run_sync(clear)
print("Smashing {} vertices".format(n))
for i in range(n*2):
v = loop.run_sync(lambda: create(i))
loop.run_sync(lambda: find_all(n))
n = 60
while True:
smash(n)
n += 1 Output:
|
A good place to check out this kind of stuff is in the Gremlin-Users and Thinkaurelius google groups. It seems like this problem has happened to other people. Building and updating to Titan 1.1 seems to fix: |
I can't reproduce this on my machine. But, I have confirmed that your script continues to run ad infinitum with Titan 1.1. I also noticed a drastic performance increase when upgrading. |
Thanks for the heads up. I'll try the newer version |
It looks like you have chained two futures together. The first future returned a gremlinclient.connection.Stream when resolved. Each successive read() would then give you another future which then resolves as a namedtupe("Message", ["status_code", "data", "message", "metadata"]). If your results have more than 64 records, you would see stream.status_code equals to 206 (Partial Content). This means each call of Stream.read() would only give you 64 records. You need to continuously call read() until it resolves to None. If I am correct, you could try to break the two calls into two coroutines and call the second continuously and see if that works. |
The following example should work.
|
This 64-records partial response is a gremlin server config parameter and it can be changed in the corresponding yaml file such as gremlin-server.yaml: |
Ahh makes sense @wangxiaoyu thanks for the input! Unless there are objections I will go ahead and close this issue... |
I found out the correct way to chain coroutines, and the issue resolved. Thanks for all the help. |
Please help with this problem! @wangxiaoyu answer is not working for me. I still getting only 64 :( here is django code: def all(request, element_slug, for_django_view=None):
|
Hi @blackboxx. I'm not sure I understand the code sample you posted. To retrieve all vertices for a model class, the standard pattern would be something like (untested, based on docs): def get_all_users():
users = []
stream = yield from User.all() # or any defined model
# read until stream returns ``None``
while True:
resp = yield from stream.read()
if resp is None:
break
users += resp
return users # this could be something like raise gen.Return(users) if using Python 2.7 w/Tornado
users = loop.run_sync(get_all_users) # In Django view Let me know if that helps. |
Hello @davebshow and all!. raise BadYieldError("yielded unknown object %r" % (yielded,)) If I wrap 'get_all_users' function with @gen.corutinne, i get another error: TypeError: 'Future' object is not iterable But here is my example and it working, but with a problems: @gen.coroutine
def el_all():
all_elements = []
ea = El.all()
stream = yield ea
resp = []
while True:
try:
print("READING")
resp = yield stream.read()
print("OK READING")
except Exception:
pass
if resp is None:
print("!!!!RESP IS NONE", len(all_elements))
break
all_elements += resp
return all_elements then i just call in a view "result = loop.run_sync(el_all)"As a result im geting now not only 64 but different number, but not AGAIN not real number of objects, here is my terminal prints: run 1READING run againREADING another runREADING run againREADING and againREADING So tears on my eyes. |
Welcome to the async world and happy debugging. Since each of your resp is a future, they would resolve out of order. If you want to collect all of them, you need to make sure all of them have resolved and be added to run1 and 5: resp1 64 records, resp2 64 records, ... respFinal is None, while resp3 is not resolved. Then you break the loop, you got 128 records. run2: resp1 64 records, resp3 have 23 records, respFinal is None, resp2 is not resolved yet. 64+23=87 records. run3: respFinal is None, All others are not resolved. 0 records. run4: resp1 64 records, resp2 64 records, resp3 23 records, respFinal is None. 64+64+23=151 records. And I also doubt that the content of the resp might get overwritten in run1 or 5 since the number of the print out Honestly I don't know why my example code is not working for you in your first post. However I doubt one call to |
Hello @wangxiaoyu, I formatted code so it looks better. Please explain more, how you fetching all elements. |
I simplify your code
It is a lot like
|
@wangxiaoyu VERRY BIG THANK YOU! My brains now are working. I will write my working Example when create some. |
Hello @wangxiaoyu and all people. I'd really want to get all vertices, but still not able to do this. Please help with working example. |
@blackboxx, sorry to take so long getting back to you. What version of python are you using? |
@blackboxx , in your example code in this comment, I notice you've wrapped the call to |
@leifurhauks , im using python 3.5, and my problem is i getting 0, 64, 64 128 vertexes, instead of all |
Can you show me the output if you adjust your It would also help to know a bit more about your configuration:
I'm very busy outside work today / this weekend, but I will keep looking into this on Monday. |
@blackboxx , I think the way your loop terminates before all vertices have been processed may be caused by a bug in goblin. I would like to isolate and fix it, but it would really help to have the information I mentioned about your setup, so I can try to reproduce your results. Thanks for your input so far. Goblin is still in alpha stage, and we really appreciate feedback that helps us identify and fix problems. |
I am still a bit confused by this issue...I can run the following script using Python 2.7 and Titan 1.0 with the default config: from tornado import gen
from tornado.ioloop import IOLoop
from goblin import connection
from goblin.models import Vertex
from goblin.properties import Integer
class TestVertex(Vertex):
number = Integer()
@gen.coroutine
def doit():
results = []
for i in range(100):
yield TestVertex.create(number=i)
stream = yield TestVertex.all()
while True:
msg = yield stream.read()
if msg is None:
break
results += msg
raise gen.Return(results)
if __name__ == '__main__':
connection.setup('ws://localhost:8182')
loop = IOLoop.current()
resp = loop.run_sync(lambda: doit())
print("got {0} vertices".format(len(resp)))
connection.tear_down() Which outputs:
Occasionally I see the backend error:
However, upon building Titan 1.1 from the Github repo, I don't see this error at all, and can run this script repeatedly creating nodes in multiples of 100 without seeing any error... |
@blackboxx we really need to see the exception that's being caught in your example code before we can proceed any further. |
+1 @leifurhauks |
I've found that the all() method raises an exception dependably when there are more than 64 vertices of one type in the graph db. I stripped my code down to the bare minimum and created an executable python script to demonstrate the issue
Here is the source code
And here is the output:
Regardless of how many
This is a serious issue because it is preventing me from using goblin at the moment until this has been resolved.
The text was updated successfully, but these errors were encountered: