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

Pipelining (MULTI/EXEC) support #8

Open
aramperes opened this issue Nov 1, 2020 · 3 comments
Open

Pipelining (MULTI/EXEC) support #8

aramperes opened this issue Nov 1, 2020 · 3 comments

Comments

@aramperes
Copy link
Contributor

RedisGraph has supported MULTI/EXEC to execute queries and mutations atomically for a while. The redis crate supports it through the redis::pipe().atomic() mode. It'd be nice to have implement pipelining on graphs in this crate.

I'm up for implementing this once #7 lands.

@malte-v
Copy link
Owner

malte-v commented Nov 1, 2020

Go ahead. Thank you for your contributions so far!

@aramperes
Copy link
Contributor Author

One thing to note is that using RedisGraph's --compact mode would be unsafe in pipelines. Right now, this crate will call CALL db.labels() if any of the label IDs in the result set are unknown. However, in pipelines, it's entirely possible that db.labels() no longer matches once the pipeline has completed.

For example, executing the following pipeline:

MULTI
GRAPH.QUERY test "CREATE (:L1 {prop: 1})-[:R1 {prop: 2}]->(:L2 {prop: 3})-[:R2 {prop: 4}]->(:L3 {prop: 5})" --compact
GRAPH.QUERY test "MATCH (x) RETURN x" --compact
GRAPH.DELETE test --compact
EXEC

The MATCH Result Set would have the IDs for L1, L2, L3, which are unknown to the client. Then calling db.labels() would return nothing (since the graph is now empty), and the Result Set converter would enter a perpetual loop:

redisgraph-rs/src/graph.rs

Lines 146 to 149 in 9b3f66b

Err(RedisGraphError::LabelNotFound) => {
self.update_labels()?;
self.get_result_set(response)
}

This also applies to relationship types and property keys, naturally.

@aramperes
Copy link
Contributor Author

aramperes commented Nov 1, 2020

let mut graph = Graph::open(conn, "test_graph".to_string()).unwrap();

let nodes: Vec<Node> = graph.pipe()
   .atomic() // Maybe make this the default? It isn't the default in `redis-rs` however
   .mutate("CREATE (:L1 {prop: 1})-[:R1 {prop: 2}]->(:L2 {prop: 3})-[:R2 {prop: 4}]->(:L3 {prop: 5})")
   .query("MATCH (x) RETURN x")
   .delete()
   .exec()?;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants