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

Driver agent may discard statements before they have executed #28

Closed
johannessen opened this issue Jan 29, 2021 · 2 comments · Fixed by #38
Closed

Driver agent may discard statements before they have executed #28

johannessen opened this issue Jan 29, 2021 · 2 comments · Fixed by #38

Comments

@johannessen
Copy link
Collaborator

The Neo4j driver API doesn’t guarantee that the server has completed executing a statement by the time the run() method returns. If you require a statement to have executed by a certain point, for example to check for errors, you need to use the result in some form. For the Perl driver, this is documented at Neo4j::Driver::Transaction.

REST::Neo4p::Agent::Neo4j::Driver currently doesn’t do that in run_in_session() or run_in_transaction():

try {
  $self->{_last_result} = $tx->run($qry, $params);
};
$self->maybe_throw_neo4p_error;

Statement execution might not even have begun on the server by the time maybe_throw_neo4p_error() is called. This may mask error reporting in certain cases.

When used with HTTP JSON, this is not an issue, because the result is always detached immediately. This is different for Bolt and Jolt.

When running the test suite on Bolt, the following test in 050_v2_schema.t fails because of this:

throws_ok { $n2->set_property({ name => "Fred" }) } 'REST::Neo4p::ConflictException', 'setting non-unique name property throws conflict exception';
# expecting: REST::Neo4p::ConflictException
# found: normal exit
@johannessen
Copy link
Collaborator Author

A simple way to fix this issue is to add a call to detach() as shown below. However, detach() is experimental because I’ve been on the fence regarding whether or not to keep it. For this reason, I’m not opening a PR right away.

run_in_session():

 try {
   $self->{_last_result} = $self->session->run($qry, $params);
+  $self->{_last_result}->detach;
 };

run_in_transaction():

 try {
   $self->{_last_result} = $tx->run($qry, $params);
+  $self->{_last_result}->detach;
 };

I think this particular issue is probably evidence enough that the detach() method is useful and should in fact be kept. What do you think?

@johannessen
Copy link
Collaborator Author

Actually, a call to has_next() ought to be better for this particular purpose, because unlike detach(), it doesn’t force a premature retrieval of the entire list of result records from the server.

I should probably add a better explanation of these side-effects to my documentation…

johannessen added a commit that referenced this issue Dec 11, 2024
It's necessary to call a method on the result within the try block. Any method will do; has_next() is one of the cheapest ones to call.

Resolves #28.
@johannessen johannessen linked a pull request Dec 11, 2024 that will close this issue
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

Successfully merging a pull request may close this issue.

1 participant