On 15.02.2012 05:24, Alex Rousskov wrote:
On 02/14/2012 02:09 AM, Amos Jeffries wrote:
On 14/02/2012 7:03 p.m., Alex Rousskov wrote:
Hello,

This has been discussed before (see the old thread quoted below), and the bump-ssl-server-first feature is being bitten by this especially
badly.

The attached patch may not apply to trunk "as is" right now, but the changes should be clearly visible, and I would like to port it there and
get it committed if there are no better ideas for the fix.

Technical summary:

The ERR_ZERO_SIZE_OBJECT errors were visible to the client when the
destination had only one address because serverDestinations.shift()
made the list of destination empty and startConnectionOrFail() failed.

The new "wasIdle" state is remembered in the Connection object instead of FwdState itself because we need to maintain that information for a
pinned connection as well (and FwdState is not preserved between a
request that pins a connection and a request that uses the pinned
connection).

This may need more work. I am not sure the FTP and Gopher cases are
correct. The current code assumes that those protocols do not have pconn
[races].


Um. This patch is not doing what I thought you were arguing for it to do...

The implementation is different because my earlier idea of tying the
"avoidPconn" state to serverDestinations manipulations does not work for pinned connections. However, I am still solving the same problem, using
essentially the same flag. It is just placed differently so that both
FwdState and pinned connections can share it.

My bugs that you have found below (thank you!) may have clouded the
intent though.


Thought so :P. Audit assumed that was the aim.


* FwdState::startConnectionOrFail() pops one of those N pconn off the
idle list instead of opening a new connection.

Yes, this is a bug. Will fix by changing the last pop() argument to the
equivalent of:

    !wasUsed && checkRetriable()


So you implemented what I was ask
 You need to wrap that pop() call using
if(serverDestinations[0]->wasIdle) in order to get a brand new
connection on retries.

As discussed earlier, we cannot bypass the pop() call because we want to
close an old idle connection if we have to create a new one.


In this case an existing one has just closed/failed. So killing one will be a net negative on the connection count. Seems to just be a waste of one of those N other connections (without even checking its usability).

I'm not arguing for/against this, just pointing out the case here is not as bad as the expanding connection count we argued out earlier.



Also, I think this flag would work better if it were a generic flag to
say the FD was a pconn/pinned in the past. Making TcpOpener the only
place setting it to false, as a brand new connection is attached to its FD. The ServerData child components dont need to even know about it or
assume anything about races.

I do not think a "used to be a pconn" flag will work here because we
need to detect pconn race conditions and not just any connection reuse. Pconn race conditions become impossible (and, hence, failures should not
be retried using the same destination address) after we receive
something from the server and before the connection becomes idle again. Server kids are the only ones that know when we have received something.

In other words, we need a flag that helps us detect failed connections
that went through the following sequence of "states":

    * idle
    * eof

The new wasIdle flag keeps the first state, and Server kids clear that flag if they receive something from the server because it means the eof will not be reached immediately after the idle state. I do not see how we can avoid Server kid modifications, but it would be great if we can,
of course.

Okay. Leaves us a bit more complicated state to remember updating when making new server-facing components. But not a major issue.



I do not like the wasIdle name because, technically, the connection was
not idle after we started writing the request to the server, but I
failed to find a better name. Suggestions welcomed!

will have to ponder that. Something about the read being idle maybe?

Amos

Reply via email to