Hi, now I reproduce the bug, and I fixed it :)
Can you test the attached patch ?

Thank you,
Thierry


On Thu, 3 Sep 2015 11:55:05 +0200
Thierry FOURNIER <[email protected]> wrote:

> On Wed, 2 Sep 2015 10:55:21 -0400
> Michael Ezzell <[email protected]> wrote:
> 
> > You are NOT able to reproduce?  I misunderstood your previous comment.
> 
> 
> Yes I not reproduce.
> 
> 
> > Further testing suggests (to me) that this is a timing issue, where HAProxy
> > does not discover that the connection is established, if connection
> > establishment doesn't happen within a very, very short window after the
> > connection is attempted.
> > 
> > Previously, I only tested "client talks first" (http) using a different
> > machine as the server.
> > 
> > Consider the following new results:
> > 
> > server talks first (ssh) - connection to local machine - *works*
> > server talks first (ssh) - connection to a different machine on same LAN -
> > *works*
> > server talks first (ssh) - connection to a different machine across
> > Internet - *works*
> > client talks first (http) - connection to local machine - *works*
> > client talks first (http) - connection to a different machine on same
> > LAN - *does
> > not work*
> > client talks first (http) - connection to a different machine across
> > Internet - *does not work*
> > 
> > The difference here seems to be the timing of the connection establishment,
> > and the presence or absence of additional events.  (Note that when I say
> > "local machine" I do not mean 127.0.0.1; I am still using the local
> > machine's Ethernet IP when talking to services on the local machine.)
> > 
> > When you are testing, are you using a remote machine, so that there is a
> > brief delay in connection establishment?  If not, this may explain why you
> > do not see the same behavior, since local connections do not appear to have
> > the same problem.
> 
> 
> Thank you for your investigation. It make sense. I use always my own
> dev omputer for the functionnal tests. I will try to add some latency
> in the network. And I hope to reproduce your problem.
> 
>  
> > Most interesting, based on my "timing" theory, I found a workaround, which
> > seems very wrong in principle; so wrong, in fact, that I can't believe I
> > tried it; however, using the following tactic, I am able to make an
> > outgoing socket connection to a different machine, when client talks first.
> > 
> >         local sock = core.tcp();
> >         sock:settimeout(3);
> >         local written = sock:send("GET
> > /latest/meta-data/placement/availability-zone HTTP/1.0\r\nHost:
> > 169.254.169.254\r\n\r\n");
> >         local connected, con_err = sock:connect("169.254.169.254",80);
> >         ...
> > 
> > This strange code works.  I hope you will agree that writing to the socket
> > before connecting seems very wrong, and I was surprised to find that this
> > code works successfully when connecting to a different machine --
> >  presumably because I'm pre-loading the outbound buffer, so the server's
> > response to my request actually triggers an event that does not occur in a
> > condition where the client talks first and when there is a delay in
> > connection establishment, even a very brief delay.
> 
> 
> I agree, its ugly :) but I understand why its runnings. When the
> connection is established, the send buffer is filled, so HAProxy
> automatically send its data. In this case it is useless to wakeup the
> lua process when the connection is established. When the response data
> are receive the process run perfectly.
> 
> The patch that you have talk about (BUG/MEDIUM: lua: outgoing
> connection was broken since 1.6-dev2) doesn't fix correctly the bug :)
> 
> I look for this
> 
> Thierry
> 
>From d649453ddef55c2f36e72b76f95d46cacea39d9d Mon Sep 17 00:00:00 2001
From: Thierry FOURNIER <[email protected]>
Date: Fri, 4 Sep 2015 18:25:53 +0200
Subject: [PATCH] BUG/MEDIUM: lua: outgoing connection was broken since
 1.6-dev2 (bis)

See commit id bdc97a8795c52af94683db25a4984578e26f4857

Michael Ezzell reported that the following Lua code fails in
dev4 when the TCP is not established immediately (due to a little
bit of latency):

   function tricky_socket()
        local sock = core.tcp();
        sock:settimeout(3);
        core.log(core.alert,"calling connect()\n");
        local connected, con_err = sock:connect("x.x.x.x",80);
        core.log(core.alert,"returned from connect()\n");
        if con_err ~= nil then
          core.log(core.alert,"connect() failed with error: '" .. con_err .. "'\n");
        end

The problem is that the flags who want to wake up the applet are
resetted before each applet call, so the applet must set again the
flags if the connection is not established.
---
 src/hlua.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/src/hlua.c b/src/hlua.c
index 61e28d0..1e4d47c 100644
--- a/src/hlua.c
+++ b/src/hlua.c
@@ -1461,8 +1461,14 @@ static void hlua_socket_handler(struct appctx *appctx)
 		return;
 	}
 
-	if (!(c->flags & CO_FL_CONNECTED))
+	/* if the connection is not estabkished, inform the stream that we want
+	 * to be notified whenever the connection completes.
+	 */
+	if (!(c->flags & CO_FL_CONNECTED)) {
+		si_applet_cant_get(si);
+		si_applet_cant_put(si);
 		return;
+	}
 
 	/* This function is called after the connect. */
 	appctx->ctx.hlua.connected = 1;
-- 
2.1.4

Reply via email to