SCM

[#1011003] Npgsql CAN send incomplite message while parameters bindings.

View Trackers | Bugs | Download .csv | Monitor

Date:
2011-02-25 16:31
Priority:
3
State:
Open
Submitted by:
Alex A Ermoshenko (erax)
Assigned to:
Nobody (None)
Npgsql Version:
None
Category:
Group:
Resolution:
None
Summary:
Npgsql CAN send incomplite message while parameters bindings.

Detailed description
From Postgresql doc: Chapter 43. Frontend/Backend Protocol

43.1.1. Messaging Overview
...
Conversely, both servers and clients must take care never to send an incomplete message. This is commonly done by marshaling the entire message in a buffer before beginning to send it. If a communications failure occurs partway through sending or receiving a message, the only sensible response is to abandon the connection, since there is little hope of recovering message-boundary synchronization.


Npgsql client for buffering used System.IO.BufferedStream with default buffer size 4096 bytes. If size of parameterValueBytes is greater than 4KiB then BufferedStream AUTO flushed the incomplite message to bakcend.


What do you think, could that lead to unresponsive Npgsql client due to the fact that the backend is not responding to him?


Followup

Message
Date: 2011-03-04 01:38
Sender: Francisco Figueiredo jr.


I think that the case where the buffer is autoflushed wouldn't give problems as Npgsql would continue to send data to server and it would keep receiving the remaining bytes until the message is complete.

I think the problem would occur if while Npgsql is sending data, the connection is broken somehow. This way the server could keep waiting for data and could lock. Npgsql already had errors in past where some messages weren't being consumed properly which made Npgsql lock up.

About the unexpected EOF this is regarding an application finishing and there are connections in the pool. As they don't get a chance to be closed by sending the Close message to server, this message is logged.
I sill don't have any ideas about how to deal with open connections in the pool at the moment an app finishes. Maybe we could try something with finalize methods.

i hope this explanation helps a bit
Date: 2011-03-01 16:31
Sender: Alex A Ermoshenko

postgresql log files contains "unexpected EOF on client
connection"
Date: 2011-02-25 16:35
Sender: Alex A Ermoshenko

Reflected code of System.IO.BufferedStream:Write method:

public override void Write(byte[] array, int offset, int
count)
{
if (array == null)
{
throw new ArgumentNullException("array",
Environment.GetResourceString("ArgumentNull_Buffer"));
}
if (offset < 0)
{
throw new ArgumentOutOfRangeException("offset",
Environment.GetResourceString
("ArgumentOutOfRange_NeedNonNegNum"));
}
if (count < 0)
{
throw new ArgumentOutOfRangeException("count",
Environment.GetResourceString
("ArgumentOutOfRange_NeedNonNegNum"));
}
if ((array.Length - offset) < count)
{
throw new ArgumentException
(Environment.GetResourceString("Argument_InvalidOffLen"));
}
if (this._s == null)
{
__Error.StreamIsClosed();
}
if (this._writePos == 0)
{
if (!this._s.CanWrite)
{
__Error.WriteNotSupported();
}
if (this._readPos < this._readLen)
{
this.FlushRead();
}
else
{
this._readPos = 0;
this._readLen = 0;
}
}
if (this._writePos > 0)
{
int num = this._bufferSize - this._writePos;
if (num > 0)
{
if (num > count)
{
num = count;
}
Buffer.InternalBlockCopy(array, offset,
this._buffer, this._writePos, num);
this._writePos += num;
if (count == num)
{
return;
}
offset += num;
count -= num;
}
this._s.Write(this._buffer, 0, this._writePos);
this._writePos = 0;
}
// .erax: Auto-flushing HERE!!!
if (count >= this._bufferSize)
{
this._s.Write(array, offset, count);
}
else if (count != 0)
{
if (this._buffer == null)
{
this._buffer = new byte[this._bufferSize];
}
Buffer.InternalBlockCopy(array, offset,
this._buffer, 0, count);
this._writePos = count;
}
}

Attached Files:

Changes:

No Changes Have Been Made to This Item

Powered By FusionForge