<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Mon, Feb 16, 2015 at 7:23 AM, Michael Van Canneyt <span dir="ltr"><<a href="mailto:michael@freepascal.org" target="_blank">michael@freepascal.org</a>></span> wrote:<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span>
On Sun, 15 Feb 2015, silvioprog wrote:<br>
</span><span><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
On Sun, Feb 15, 2015 at 7:11 AM, Michael Van Canneyt <<a href="mailto:michael@freepascal.org" target="_blank">michael@freepascal.org</a>> wrote:<br>
[...]<br>
      Very nice.<br>
<br>
      Some remarks:<br>
<br>
      - KeepConnection logic already existed. It is part of the fastcgi protocol.<br>
<br>
        Normally, the apache server must send a keepconnection option as part of the request.<br>
        See the 'FKeepConnectionAfterRequest' variable in TFCGIrequest, it is processed when<br>
        the FCGI_BEGIN_REQUEST block comes in and is checked after each request.<br>
<br>
        The fact that you apparently needed to introduce special processing means the proxy<br>
        module does not correctly set this option. To test, you can check the value of the flag<br>
        in the request handler.<br>
<br>
        I also suggest you look at the existing implementation of KeepConnection and see<br>
        where that needs to be changed, instead of introducing new KeepConnection handling.<br>
<br>
<br>
I saw, and it works fine in nginx, but ...<br>
<br>
      - if you really need to introduce  an additional flag, please put an extra flag in<br>
        ProtocolOptions. Something like 'poDefaultKeepConnection'.<br>
        Do not introduce new booleans 'options' when an option set exists...<br>
<br>
<br>
... in Apache, using proxy mode, keepconn always returns true. =/ So we need to add a 'poProxyKeepConnection' flag.<br>
</blockquote>
<br></span>
Wait, I do not understand. If keepconn always returns true, then all should work as-is ? Why do you need the flag ?<br>
<br>
What happens if you set enablereuse=off in the apache config ?</blockquote><div><br></div><div>I tried everything:<br></div><div><br></div><div>- KeepAlive Off;</div><div>- enablereuse=Off;</div><div><div>- SetEnv proxy-nokeepalive 0;</div></div><div>- disablereuse=On.<br></div><div><br></div><div>I tried environment variables too. I tried to add the FCGI_KEEP_CONN flag to 0, and even so Apache return True. I happens only in Apache,  it seems to be a bug, because I saw some people talking about this on StackOverflow. The "enablereuse" feature was recently implemented, so it possibly has bugs.</div><div><br></div><div>On nginx I've just removed the keepalive  from upstram and all worked fine.</div><div><br></div><div>The poProxyKeepConnection flag will make the custfcgi hibrid, because the programmer could choose between using the configuration via server or application. So, add that. It worth. =)</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
      - Don't change the constructor signature, that is bad practice.<br>
<br>
        A TComponent constructor must be Create(AOwner : TComponent);<br>
<br>
        if you really want to change it, just create another one:<br>
        Constructur CreateCustom(AOwner : TComponent; KeepConnection : Boolean);<br>
<br>
        For components, properties must always be settable after create,<br>
        otherwise streaming does not work correctly.<br>
<br>
<br>
Done. Please see the code in attached (some changes in mycustfcgi too).<br>
</blockquote>
<br></span>
Thank you.<span><br>
<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<br>
After your tips, now I'm able to implement the changes in original custfcgi and send a patch. One more question before continuing: after implementing the pool, we will still need RequestsArray?<br>
</blockquote>
<br></span>
Normally yes, even more so than in the current implementation. IMHO you will maybe need 2 arrays: Incoming (request), outgoing(response).<br></blockquote><div><br></div><div>Good.</div><div><br></div><div>But I don't know it we need two arrays, I think that a hash list will suit well, I'll explain it below ...</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
- New Request comes in. - No thread to handle request is available in pool.<br>
- Request is accepted and put in incoming requestsarray.<br>
- Check outgoing response array, send back any responses.<br>
- When Thread finishes a request, puts it in outgoing responses array.<br>
<br>
Details will depend heavily on the way the pool is handled.</blockquote></div><div><br></div><div>... I don't know if you tested the code that I sent you, but I've already done it, and in an unique array. =) The implemented structure works this way:</div><div><br></div><div>- the main acceptconn waits the first request;</div><div>- after receiving the first request, the execution comes from the main acceptconn, creating a new thread, that has an own acceptconn;</div><div>- the first open thread keep waiting for new requests in its own acceptconn, keeping the main acceptconn in 'stand-by'.</div><div><br></div><div>If an user make two or more later requests, it will call the acceptconn from the thread, and the main acceptconn will go on in stand-by. If a thread get in a long process (e.g: that 10 seconds loop), the main acceptconn it will call, that leaving from the stand-by status, creating a new thread, putting this new processing on it.</div><div><br></div><div>In short, if a request is short, only one thread is created and one acceptconn is used; if a new request takes some time to be processed, the application opens a new thread to process the other requests.</div><div><br></div><div>Another thing: IMHO, it is interesting to use hash lists instead of commom arrays. A hash list has a internal generic array, that implements the type of the array item according to the declared specialization. In some cases, we get more than 700 % of performance using hash lists instead of commons arrays. It happens due to the hash list uses a different logic to iterate items. Please, test this small comparation[1] (<span style="color:rgb(128,128,128);font-family:Consolas,Menlo,Monaco,'Lucida Console','Liberation Mono','DejaVu Sans Mono','Bitstream Vera Sans Mono',monospace,serif;font-size:12px;font-style:italic;line-height:21px">Commom: 00:00:07.554 vs Hash: 00:00:00.109</span>) in your PC (considering that we will use only the 'add', 'get' and 'delete' methods of the list), realising the big advantage in use hash list (you can compare them even with common arrays). We could make a TFCGIThreadedList, using a critical section to turn it thread-safe (on the comparition I showed you how to do it).</div><div><br></div><div>It is interesting to enjoy this big performance of the hash list, so, in HTTP 1.1, the requests occur asynchronously: when a user open any page from a site, the download of files JS, CSS, HTML, PNG etc. they are done simultaneously (my calc of 150,000 iterations was supposing that 10,000 users was accessing a social network, and each user downloading in average 15 page files - CSS, JS, HTML and ajax GETs -, simultaneously).</div><div><br></div><div>[1] <a href="http://pastebin.com/ZM1DSLkG" target="_blank">http://pastebin.com/ZM1DSLkG</a></div><div><br></div>-- <br><div>Silvio Clécio<br>My public projects - <a href="http://github.com/silvioprog" target="_blank">github.com/silvioprog</a></div>
</div></div>