I am opening this issue to discuss the level of integration with gremlin-python we will provide in this package. As @leifurhauks suggested, if were to implement a couple of custom classes, we would achieve an "async style" Gremlin sytanx:
resp = await g.V().has('key', 'val')
Well, almost. Currently, in order to actually submit the generated script and bindings we need to call another method signaling that the traversal is finished and needs to be submitted. In the current gremlin-python implementation this is achieved by calling next
, which forms part of a kind of strange iterator machinery built into the gremlin_python.Traversal
class that relies on another class gremlin_python.Traverser
, which is instantiated by doing an extra iteration over the results the RemoteConnection
object. So guess in the end, we can achieve something like:
resp = await g.V().has('key', 'val').next()
async for msg in resp:
...
This is great and slick, and I think the driver should implement this. However, I wonder how integrated this async style Gremlin should be with Goblin. I have several concerns. Maybe they are unfounded, but I figured I would open an issue to do a bit of discussion.
So, first of all, I wonder if in some cases we will need a bit more control over the scripts we submit. Imagine we want submit arbitrary groovy code to the server, or, do something like transaction control. This is a bit more difficult to achieve if we are relying on all of the internals of the GLV.
Currently, we simply use the GLV to generate strings and bindings, which is quite flexible. For example, something like:
traversal = g.addV(...)
script = "graph.tx().rollback(); try {" + traversal.script + "graph.tx().commit()} except { graph.tx().rollback()"
resp = await conn.submit(script)
async for msg in resp:
...
I'm not sure how to achieve something like this using the GLV. I know that this example is pretty ugly, but I can see things like this coming up.
Also, I'm thinking about how we provide queries. If a use wants to just user the GLV, fine, but I had kind of hoped that goblin could provide its own machinery for user built queries that are bound to the session elements and feature some limitations as well as some convenience methods. For example, as it is currently:
resp = session.traversal(MyElementType).has('key', 'val').out().all()
So here, we can note that MyElementType provides the traversal with some initial information about the type of traversal being build i.e., the element type (vertex vs. edge) and element label. Furthermore, instead of calling next
(which I think is kind of confusing), we call all
, which says we want all of the results returned by the db. We could easily provide other methods that return lists and scalars (like in sqlalchemy): one
, first
, one_or_none
.
I am sure there are more things to consider here...that's why I am looking for input @leifurhauks @jsenecal