Bolt icon indicating copy to clipboard operation
Bolt copied to clipboard

Add pipelining

Open stefanak-michal opened this issue 3 years ago • 2 comments

Add support for pipelining bolt messages https://www.neo4j.com/docs/bolt/current/bolt/message/#pipelining

Messages may also be pipelined. In other words, clients may send multiple requests eagerly without first waiting for responses. When a failure occurs in this scenario, servers must ignore all subsequent requests until the client has explicitly acknowledged receipt of the failure. This prevents inadvertent execution of queries that may not be valid. More details of this process can be found in the sections below.

stefanak-michal avatar Jul 28 '22 12:07 stefanak-michal

I reverted added pipelining because the implementation wasn't very good. I'm still in the process of thinking how to do it properly. Currently I'm working on branch https://github.com/neo4j-php/Bolt/tree/traits_pipeline where I did some interesting changes in approach.

you can do this:

$res = iterator_to_array(
    $protocol
        ->begin()
        ->run('CREATE (a:Test) RETURN a, ID(a)')
        ->pull()
        ->rollback()
        ->getResponse()
);

Variable $res will be array with this indexes and context:

  • 0 - response from begin
  • 1 - response from run
  • 2 - record message from pull
  • 3 - meta message from pull
  • 4 - response from rollback

You can chain all methods beside hello and goodbye.

Reading data from database output buffer is continuously and getResponse is using yield for every readed message from buffer. Also getResponse has parameter limit which you can use to limit how many messages to read from buffer (maybe also add skip?).

Any ideas or feedback?

stefanak-michal avatar Aug 02 '22 06:08 stefanak-michal

https://github.com/neo4j-php/Bolt/commit/01b9c0a0584cdec6fc0749915eceb762ef590e2d

Added new \Bolt\protocol\Response class for all readed messages from host. This class contains called bolt message, result signature and response content. https://github.com/neo4j-php/Bolt/blob/traits_pipeline/src/protocol/Response.php

Removed throwing MessageException and IgnoredException because handling of these can be based on Response instance in implementation of this library.

Changed protocol method for reading response, now it has two methods: getResponse for one Response and getResponses to get Iterator.

Usage with getResponse

$protocol
    ->run('RETURN 1 AS num')
    ->pull();

$runResponse = $protocol->getResponse(); // \Bolt\protocol\Response(RUN, SUCCESS, [content])
$pullRecord = $protocol->getResponse(); // \Bolt\protocol\Response(PULL, RECORD, [content])
$pullMeta = $protocol->getResponse(); // \Bolt\protocol\Response(PULL, SUCCESS, [content])

Usage with getResponses

$gen = $protocol
    ->run('RETURN 1 AS num')
    ->pull()
    ->getResponses();

foreach ($gen as $response) {
    // logic
}

stefanak-michal avatar Aug 02 '22 10:08 stefanak-michal