johnnadratowski / golang-neo4j-bolt-driver

Golang Bolt driver for Neo4j
MIT License
213 stars 72 forks source link

Improvment for problem "Couldn't read expected bytes for message length" #32

Closed cullberg closed 7 years ago

cullberg commented 7 years ago

Hi! I have a fix for partial reads where the io.read does not read the full buffer. Using "ReadFull" instead of "Read" fixes the issue where only one byte is read on the socket.

encoding/decoder.go Line 44 "io.ReadFull(d.r,lengthBytes)" instead of "d.r.Read(lengthBytes)"

// Read out the object bytes to decode func (d Decoder) read() (*bytes.Buffer, error) { output := &bytes.Buffer{} for { lengthBytes := make([]byte, 2)

if numRead, err := io.ReadFull(d.r,lengthBytes); numRead != 2 {
        return nil, errors.Wrap(err, "Couldn't read expected bytes for message length. Read: %d Expected: 2.", numRead)
    }
johnnadratowski commented 7 years ago

@cullberg - Can you describe a scenario where this occurs? Maybe with a test showing this behavior?

cullberg commented 7 years ago

@johnnadratowski

It occurs is when the underlying socket only have 1 byte available and decoder.go wants to read 2 bytes. The io.Read function only promises to read whats available at that moment and not waiting to fill the buffer. In the decoder.readData function it is handled correctly.

From the io.go Read interface description: Read reads up to len(p) bytes into p. It returns the number of bytes read (0 <= n <= len(p)) and any error encountered. Even if Read returns n < len(p), it may use all of p as scratch space during the call. If some data is available but not len(p) bytes, Read conventionally returns what is available instead of waiting for more.

Since this is an OS dependent interface it is harder to write tests for it without modifying the code and i'm quite new to golang I must admit. How do you override the io.Read method from a testMethod? My hope was to be able to get the fix into this main project so I don't have to fork a new one.

The error occurs when you ask a LOT of questions towards the neo4j database and is not deterministic.

martin-flower commented 7 years ago

Thanks @cullberg - I have just received the same error Couldn't read expected bytes for message length. Read: 1 Expected: 2

johnnadratowski commented 7 years ago

@cullberg - Switched over to use io.ReadFull

Callmedachang commented 6 years ago

hi i just receive an error panic: An error occurred initializing connection An error occurred decoding ack failure message response Couldn't read expected bytes for message length. Read: 0 Expected: 2. Internal Error(*errors.errorString):EOF can you help me ?^_^