Skip to content

Conversation

@p123-stack
Copy link
Collaborator

Connection Receive Timeout Configuration Hint Implementation

  • Implemented full support for the connection.recv_timeout_seconds (BOLT 4.3+) configuration hint across the Neo4j PHP Client, enabling the driver to respect server-supplied socket timeout directives.

BoltFactory Socket Timeout Application

  • Extracts connection.recv_timeout_seconds hint from server HELLO response

  • Applies timeout value to underlying socket connection via Connection::setTimeout()

  • Enables socket-level read timeouts on all authenticated connections

Timeout Exception Handling & Recovery

  • BoltMessage detects socket timeout exceptions and closes broken connections.

  • Converts timeout exceptions to Neo4jException with Neo.ClientError.Cluster.NotALeader error code

  • Session retry logic catches NotALeader errors and closes connection pool to force routing table refresh

  • Neo4jConnectionPool invalidates cached routing table, triggering fresh fetch from available servers

  • Implicitly marks timed-out server as unavailable and removes from routing table

Feature Declaration

  • GetFeatures declares support for ConfHint:connection.recv_timeout_seconds in testkit backend

  • Enables compliance testing against official Neo4j test suite

@transistive transistive self-requested a review November 28, 2025 06:37
Copy link
Collaborator

@transistive transistive left a comment

Choose a reason for hiding this comment

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

Great work! I have some minor questions that we have to resolve. Let's also ensure static analysis is happy

*/
public function discardUnconsumedResults(): void
{
if (!$this->isOpen()) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Let's move this into the same if statement.

It is worth inspecting why we have to make this check, as if the conneciton is closed, the serverstate should not be in STREAMING or TX_STREAMING state in the first place

$config->setServerAgent($response['server']);

// Apply recv_timeout hint if present
if (array_key_exists('connection.recv_timeout_seconds', $response['hints'])) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is a great subtle detail that we were able to pick up using the tests!

$this->tsxConfig->getTimeout(),
$this->isInstantTransaction ? $this->bookmarkHolder : null, // let the begin transaction pass the bookmarks if it is a managed transaction
$this->isInstantTransaction ? $this->config->getAccessMode() : null, // let the begin transaction decide if it is a managed transaction
null, // mode is never sent in RUN messages - it comes from session configuration
Copy link
Collaborator

Choose a reason for hiding this comment

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

Are we sure? $this->config is a session configuration object.

TEST_DRIVER_REPO: /opt/project
TEST_BACKEND_HOST: testkit_backend
TEST_STUB_HOST: testkit
BOLT_LISTEN_ADDR: "0.0.0.0:9001"
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can you add a comment where this config variable is being used?

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 this pull request may close these issues.

3 participants