Skip to content

Commit

Permalink
Implement GetServerInfo
Browse files Browse the repository at this point in the history
This introduces the concept of idleness on logical connections.

When connections are picked from the pool and have been idle
for too long, they will be reset and removed if the reset fails.

This is currently only enabled for GetServerInfo but might be 
configurable in the future.
  • Loading branch information
fbiville authored May 10, 2022
1 parent 5213799 commit 88a7cd7
Show file tree
Hide file tree
Showing 24 changed files with 1,557 additions and 380 deletions.
11 changes: 11 additions & 0 deletions neo4j/driver_with_context.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ type DriverWithContext interface {
// is encrypted. This is a static check. The function can also be called on
// a closed Driver.
IsEncrypted() bool
// GetServerInfo attempts to obtain server information from the target Neo4j
// deployment
GetServerInfo(ctx context.Context) (ServerInfo, error)
}

// NewDriverWithContext is the entry point to the neo4j driver to create an instance of a Driver. It is the first function to
Expand Down Expand Up @@ -295,3 +298,11 @@ func (d *driverWithContext) Close(ctx context.Context) error {
func (d *driverWithContext) IsEncrypted() bool {
return !d.connector.SkipEncryption
}

func (d *driverWithContext) GetServerInfo(ctx context.Context) (_ ServerInfo, err error) {
session := d.NewSession(SessionConfig{})
defer func() {
err = deferredClose(ctx, session, err)
}()
return session.getServerInfo(ctx)
}
16 changes: 16 additions & 0 deletions neo4j/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
package neo4j

import (
"context"
"errors"
"fmt"
"github.com/neo4j/neo4j-go-driver/v5/neo4j/db"
Expand Down Expand Up @@ -170,3 +171,18 @@ func wrapError(err error) error {
}
return err
}

type ctxCloser interface {
Close(ctx context.Context) error
}

func deferredClose(ctx context.Context, closer ctxCloser, prevErr error) error {
err := closer.Close(ctx)
if err == nil {
return prevErr
}
if prevErr == nil {
return err
}
return fmt.Errorf("close error %v after previous error %w", err, prevErr)
}
26 changes: 24 additions & 2 deletions neo4j/internal/bolt/bolt3.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,11 @@ type bolt3 struct {
log log.Logger
err error // Last fatal error
minor int
idleDate time.Time
}

func NewBolt3(serverName string, conn net.Conn, logger log.Logger, boltLog log.BoltLogger) *bolt3 {
now := time.Now()
b := &bolt3{
state: bolt3_unauthorized,
conn: conn,
Expand All @@ -101,7 +103,8 @@ func NewBolt3(serverName string, conn net.Conn, logger log.Logger, boltLog log.B
logger: logger,
logName: log.Bolt3,
},
birthDate: time.Now(),
birthDate: now,
idleDate: now,
log: logger,
}
b.out = &outgoing{
Expand Down Expand Up @@ -135,6 +138,7 @@ func (b *bolt3) receiveMsg(ctx context.Context) interface{} {
b.state = bolt3_dead
return nil
}
b.idleDate = time.Now()
return msg
}

Expand Down Expand Up @@ -628,6 +632,10 @@ func (b *bolt3) Birthdate() time.Time {
return b.birthDate
}

func (b *bolt3) IdleDate() time.Time {
return b.idleDate
}

func (b *bolt3) Reset(ctx context.Context) {
defer func() {
b.log.Debugf(log.Bolt3, b.logId, "Resetting connection internal state")
Expand All @@ -645,11 +653,18 @@ func (b *bolt3) Reset(ctx context.Context) {
// Discard any pending stream
b.discardStream(ctx)

if b.state == bolt3_ready || b.state == bolt3_dead {
if b.state == bolt3_ready {
// No need for reset
return
}

b.ForceReset(ctx)
}

func (b *bolt3) ForceReset(ctx context.Context) {
if b.state == bolt3_dead {
return
}
// Send the reset message to the server
// Need to clear any pending error
b.err = nil
Expand Down Expand Up @@ -749,3 +764,10 @@ func (b *bolt3) SetBoltLogger(boltLogger log.BoltLogger) {
b.in.hyd.boltLogger = boltLogger
b.out.boltLogger = boltLogger
}

func (b *bolt3) Version() db.ProtocolVersion {
return db.ProtocolVersion{
Major: 3,
Minor: b.minor,
}
}
Loading

0 comments on commit 88a7cd7

Please sign in to comment.