Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support bytecode-based requests for interactive engine #36

Merged
merged 5 commits into from
Dec 24, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 50 additions & 1 deletion python/graphscope/deploy/tests/test_demo_script.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ def test_multiple_session(data_dir):
sess.close()


def test_load_modern_graph(modern_graph_data_dir):
def test_query_modern_graph(modern_graph_data_dir):
image = get_gs_image_on_ci_env()
sess = graphscope.session(
show_log=True,
Expand All @@ -236,3 +236,52 @@ def test_load_modern_graph(modern_graph_data_dir):
for q in queries:
result = interactive.execute(q).all().result()[0]
assert result == 1


def test_traversal_modern_graph(modern_graph_data_dir):
from gremlin_python.process.traversal import Order
from gremlin_python.process.traversal import P

image = get_gs_image_on_ci_env()
sess = graphscope.session(
show_log=True,
num_workers=1,
k8s_gs_image=image,
k8s_coordinator_cpu=0.5,
k8s_coordinator_mem="2500Mi",
k8s_vineyard_cpu=0.1,
k8s_vineyard_mem="512Mi",
k8s_engine_cpu=0.1,
k8s_engine_mem="1500Mi",
k8s_vineyard_shared_mem="2Gi",
)
graph = load_modern_graph(sess, modern_graph_data_dir)
interactive = sess.gremlin(graph)
g = interactive.traversal_source()
assert g.V().has("name", "marko").count().toList()[0] == 1
assert g.V().has("person", "name", "marko").count().toList()[0] == 1
assert g.V().has("person", "name", "marko").outE("created").count().toList()[0] == 1
assert (
g.V().has("person", "name", "marko").outE("created").inV().count().toList()[0]
== 1
)
assert g.V().has("person", "name", "marko").out("created").count().toList()[0] == 1
assert (
g.V()
.has("person", "name", "marko")
.out("created")
.values("name")
.count()
.toList()[0]
== 1
)
assert (
g.V()
.hasLabel("person")
.has("age", P.gt(30))
.order()
.by("age", Order.desc)
.count()
.toList()[0]
== 2
)
29 changes: 28 additions & 1 deletion python/graphscope/interactive/query.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
from concurrent.futures import ThreadPoolExecutor

from gremlin_python.driver.client import Client
from gremlin_python.driver.driver_remote_connection import DriverRemoteConnection
from gremlin_python.process.anonymous_traversal import traversal

from graphscope.framework.loader import Loader

Expand All @@ -32,11 +34,15 @@ class InteractiveQuery(object):
"""`InteractiveQuery` class, is a simple wrapper around
`Gremlin-Python <https://pypi.org/project/gremlinpython/>`_,
which implements Gremlin within the Python language.
It also can expose gremlin endpoint which can be used by any other standard gremlin console.
It also can expose gremlin endpoint which can be used by
any other standard gremlin console, with the method `graph_url()`.

It also has a method called `subgraph` which can extract some fragments
from origin graph, produce a new, smaller but concise graph stored in vineyard,
which lifetime is independent from the origin graph.

User can either use `execute()` to submit a script, or use `traversal_source()`
to get a `GraphTraversalSource` for further traversal.
"""

def __init__(self, graphscope_session, object_id, front_ip, front_port):
Expand Down Expand Up @@ -141,6 +147,27 @@ def execute(self, query):
raise RuntimeError("Interactive query is closed.")
return self._client.submit(query)

def traversal_source(self):
"""Create a GraphTraversalSource and return.
Once `g` has been created using a connection, we can start to write
Gremlin traversals to query the remote graph.

Examples:

.. code:: python

sess = graphscope.session()
graph = load_modern_graph(sess, modern_graph_data_dir)
interactive = sess.gremlin(graph)
g = interactive.traversal_source()
print(g.V().both()[1:3].toList())
print(g.V().both().name.toList())

Returns:
`GraphTraversalSource`
"""
return traversal().withRemote(DriverRemoteConnection(self._graph_url, "g"))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the parameter "g" a hard-coded constant value?

Copy link
Collaborator Author

@siyuan0322 siyuan0322 Dec 23, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not exactly, but suffice for out scenario, just like the Client case before.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then could "g" will be used repeatly?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes if you are talking about using g repeatedly across graph instances.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What will happen on the same graph instance?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nothing happens, you can get two traversal source that works normally.
They are same if you look at the initialization of Client in

self._client = Client(self._graph_url, "g")


def close(self):
"""Close interactive instance and release resources"""
if not self.closed():
Expand Down