<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:Consolas;
        panose-1:2 11 6 9 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
pre
        {mso-style-priority:99;
        mso-style-link:"HTML Preformatted Char";
        margin:0in;
        margin-bottom:.0001pt;
        font-size:10.0pt;
        font-family:"Courier New",serif;}
tt
        {mso-style-priority:99;
        font-family:"Courier New",serif;}
p.msonormal0, li.msonormal0, div.msonormal0
        {mso-style-name:msonormal;
        mso-margin-top-alt:auto;
        margin-right:0in;
        mso-margin-bottom-alt:auto;
        margin-left:0in;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
span.HTMLPreformattedChar
        {mso-style-name:"HTML Preformatted Char";
        mso-style-priority:99;
        mso-style-link:"HTML Preformatted";
        font-family:Consolas;}
span.EmailStyle22
        {mso-style-type:personal-reply;
        font-family:"Calibri",sans-serif;
        color:windowtext;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-size:10.0pt;}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-US" link="blue" vlink="purple">
<div class="WordSection1">
<p class="MsoNormal">Liviu,<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Thanks again for the info. I think what you are saying is that the async operation is not launching a new process to handle the called function, but is performing the function in the original worker thread and only taking advantage of any
 suspend/resume or polling functionality already exposed by the underlying function itself.
<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">This is very different from the way I had hoped async would work. The documentation does not speak to the specific implementation of async, so it was all assumptions on my part. But to me when you say async it means a separate process or
 thread is being created to perform the function. This would allow that process to block on the connect or any other aspect of the called function as necessary without blocking call processing, which is the desired outcome of any async operation.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">I understand that the practicalities of the implementation in OpenSIPS may have required this design, but I must re-iterate that these limitations need to be documented very carefully as they are very important to understand when designing
 OpenSIPS scripts with async functionality and are not described anywhere. I could not find anywhere in the documentation that indicates that async operations can potentially still block the original worker thread and block call processing. The closest is:<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">“The current OpenSIPS worker will launch the asynchronous operation, after which it will continue to process other pending tasks”<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">But this provides no elaboration on what it means for the worker to “launch” the operation, and more importantly it does not indicate that the launching itself can block, which is the key issue here.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">As I said, this unfortunately makes async processing mostly useless for us. For both DB and REST queries if only the data transfer is async then it is only useful when the data being transferred is extremely large or prone to delays/jitter.
 Such transfers should be avoided during realtime processing whether async or not, as they will still delay the individual call even if not others. For small payloads, like the single JSON object common in REST responses, it is the connection itself that is
 the concern. Once connected, running the data transfer in async mode represents no real gain.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">As far as investigating why the server is not responding, of course we will always do this. But we cannot anticipate or fix every cause of remote system failure. In order to design a resilient system we cannot assume the remote server will
 always be there. We had believed async would allow call processing to proceed in failure cases like this without blocking.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><span style="color:black">Ben Newlin </span><o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<div style="border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal"><b><span style="font-size:12.0pt;color:black">From: </span></b><span style="font-size:12.0pt;color:black">Users <users-bounces@lists.opensips.org> on behalf of Liviu Chircu <liviu@opensips.org><br>
<b>Reply-To: </b>OpenSIPS users mailling list <users@lists.opensips.org><br>
<b>Date: </b>Wednesday, June 26, 2019 at 9:23 AM<br>
<b>To: </b>"users@lists.opensips.org" <users@lists.opensips.org><br>
<b>Subject: </b>Re: [OpenSIPS-Users] Rest Client Async operation<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<p><tt><span style="font-size:10.0pt">It's the same process doing both the connect and the transfer.  The problem is that libcurl, as it stands now,</span></tt><span style="font-size:10.0pt;font-family:"Courier New",serif"><br>
<tt>is not able to give me a file descriptor to poll on, until it connects [1].  See this section:</tt><br>
<br>
<tt>"When libcurl returns -1 in max_fd, it is because libcurl currently does something that isn't possible</tt><br>
<tt>for your application to monitor with a socket and unfortunately you can then not know exactly when the</tt><br>
<tt>current action is completed using select(). You then need to wait a while before you proceed and call</tt><br>
<tt>curl_multi_perform anyway. How long to wait? Unless curl_multi_timeout gives you a lower number, we</tt><br>
<tt>suggest 100 milliseconds or so, but you may want to test it out in your own particular conditions to</tt><br>
<tt>find a suitable value."</tt></span><o:p></o:p></p>
<p><tt><span style="font-size:10.0pt">Regarding your issue: I would investigate further the reason why the connect is hanging, and not getting</span></tt><span style="font-size:10.0pt;font-family:"Courier New",serif"><br>
<tt>rejected immediately when your server is down.  That would solve all your blocking issues.</tt></span><o:p></o:p></p>
<p><tt><span style="font-size:10.0pt">The same with MySQL connections which go down: only after the connection is up are we able to obtain</span></tt><span style="font-size:10.0pt;font-family:"Courier New",serif"><br>
<tt>its file descriptor to asynchronously poll on.  So if connect to DB_HOST:3306 hangs, so will OpenSIPS.</tt></span><o:p></o:p></p>
<p><tt><span style="font-size:10.0pt">Regards,</span></tt><o:p></o:p></p>
<p><tt><span style="font-size:10.0pt">[1]: <a href="https://curl.haxx.se/libcurl/c/curl_multi_fdset.html">
https://curl.haxx.se/libcurl/c/curl_multi_fdset.html</a></span></tt><o:p></o:p></p>
<pre>Liviu Chircu<o:p></o:p></pre>
<pre>OpenSIPS Developer<o:p></o:p></pre>
<pre><a href="http://www.opensips-solutions.com">http://www.opensips-solutions.com</a><o:p></o:p></pre>
<div>
<p class="MsoNormal">On 25.06.2019 18:41, Ben Newlin wrote:<o:p></o:p></p>
</div>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<p class="MsoNormal">but I guess my question would be why isn’t the entire operation run in async? Why must the connect be performed in the current process and only the transfer be in another process?<o:p></o:p></p>
</blockquote>
</div>
</body>
</html>