[prev in list] [next in list] [prev in thread] [next in thread] 

List:       boost-users
Subject:    Re: [Boost-users] Understanding fibers
From:       Stian Zeljko Vrba via Boost-users <boost-users () lists ! boost ! org>
Date:       2018-12-18 6:58:05
Message-ID: HE1PR05MB47135184A8D44235A765B042B4BD0 () HE1PR05MB4713 ! eurprd05 ! prod ! outlook ! com
[Download RAW message or body]

[Attachment #2 (text/plain)]

Hi,


thanks for the clarifications!


> Asio itself doesn't catch any exceptions -- if a handler throws then it will be \
> propagated out and into the method that calls io_context.run() -- if this doesn't \
> have a try-catch block wrapped around it by the user then the thread and the app \
> will be terminated.


Yes, I was aware of that, I just wrote it imprecisely. What I meant is what you wrote \
😊 (i.e., that coroutine machinery arranges for correct exception propagation from \
the callee to the caller).


Unrelated: do you have advice on error-handling patterns? Given two "loops", one that \
reads data from a socket and another that writes data to a socket. Currently, I \
handle errors with the following pattern:


error_code ec;

something_async(…, ec);

if (!HandleError(ec, "something_async"))

return; // shared_from_this() pattern


where HandleError is defined as


bool HandleError(const error_code& ec, const char* what)
{
    if (IsCanceled() || !_socket.is_open() || ec == \
boost::system::errc::operation_canceled)  return false;
    if (!ec)
        return true;
    throw Failure(WeakSelf(), ec, what);
}

(IsCanceled() returns the state of an internal Boolean flag.)

because 1) the same io service thread is running multiple workers, 2) I need to know \
_which_ worker failed because the worker is associated with "extra data" in the \
io_service thread and this data may contain "restart" policy (e.g. reconnect on \
broken connection). Also, the outer loop will cancel the worker in case Failure() has \
been thrown.

But this seems to combine the worst of two worlds, as both exceptions and error codes \
are used. If I don't pass error_code to async calls, asio will throw system_error, \
but that one is not descriptive enough for my purposes.

Is there a way to automate this, or some other recommended "pattern" to use?

-- Stian


________________________________
From: Boost-users <boost-users-bounces@lists.boost.org> on behalf of Gavin Lambert \
                via Boost-users <boost-users@lists.boost.org>
Sent: Monday, December 17, 2018 10:28 PM
To: boost-users@lists.boost.org
Cc: Gavin Lambert
Subject: Re: [Boost-users] Understanding fibers

On 18/12/2018 02:07, Stian Zeljko Vrba wrote:
> 1. The above is inside a _/coroutine/_ and invoked as a callback? (my
> guess: the caller – asio thread – arranges/provides a catch context
> that the exception propagates into)
> 2. The above is inside a _/fiber/_ and called by yielding to the fiber
> scheduler? (my guess: the fiber scheduler does not provide an outer
> catch context, so the program crashes).
> 
> Is this correct?

Yes, both of those are somewhat correct.  Though there are some missing
links.

With coroutines, you're yielding to a specific other coroutine -- if
that coroutine throws, then the exception is thrown out of the yield
point just as if it were a regular function call.

Asio itself doesn't catch any exceptions -- if a handler throws then it
will be propagated out and into the method that calls io_context.run()
-- if this doesn't have a try-catch block wrapped around it by the user
then the thread and the app will be terminated.

Fibers aren't allowed to propagate exceptions into the fiber scheduler,
since you can't customise the exception handling there -- but if you
don't call your fiber code directly but instead wrap it in a
packaged_task, this gives you a future and also wraps the code in a
try-catch block such that if the code throws an exception it will store
the exception into the future (where it can be rethrown at the consuming
site) instead of terminating.  (Thread-based futures work the same way.)
_______________________________________________
Boost-users mailing list
Boost-users@lists.boost.org
https://lists.boost.org/mailman/listinfo.cgi/boost-users


[Attachment #3 (text/html)]

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<style type="text/css" style="display:none;"><!-- P {margin-top:0;margin-bottom:0;} \
--></style> </head>
<body dir="ltr">
<div id="divtagdefaultwrapper" \
style="font-size:12pt;color:#000000;font-family:Calibri,Helvetica,sans-serif;" \
dir="ltr"> <div id="divtagdefaultwrapper" style="color: rgb(0, 0, 0); font-family: \
Calibri,Helvetica,sans-serif,&quot;EmojiFont&quot;,&quot;Apple Color \
Emoji&quot;,&quot;Segoe UI Emoji&quot;,NotoColorEmoji,&quot;Segoe UI \
Symbol&quot;,&quot;Android Emoji&quot;,EmojiSymbols; font-size: 12pt;" dir="ltr"> <p \
style="margin-top:0;margin-bottom:0">Hi,</p> <p \
style="margin-top:0;margin-bottom:0"><br> </p>
<p style="margin-top:0;margin-bottom:0">thanks for the clarifications!</p>
<p style="margin-top:0;margin-bottom:0"><br>
</p>
<p style="margin-top:0;margin-bottom:0"></p>
<div>&gt; Asio itself doesn't catch any exceptions -- if a handler throws then it \
will be propagated out and into the method that calls io_context.run() -- if this \
doesn't have a try-catch block wrapped around it by the user then the thread and the \
app will be  terminated.</div>
<br>
<p></p>
<p style="margin-top:0;margin-bottom:0">Yes, I was aware of that, I just wrote it \
imprecisely. What I meant is what you wrote <span>😊 (i.e., that coroutine \
machinery arranges for correct exception propagation from the callee to the \
caller).</span></p> <p style="margin-top:0;margin-bottom:0"><span><br>
</span></p>
<p style="margin-top:0;margin-bottom:0">U<span>nrelated: do you have advice on \
error-handling patterns? Given two &quot;loops&quot;, one that reads data from a \
socket and another that writes data to a socket. Currently, I handle errors with the \
following pattern:</span></p> <p style="margin-top:0;margin-bottom:0"><span><br>
</span></p>
<blockquote style="padding: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: \
0px;" dir="ltr"> <p style="margin-top:0;margin-bottom:0"><span>error_code \
ec;</span></p> <p style="margin-top:0;margin-bottom:0"><span>something_async(…, \
ec);</span></p> <p style="margin-top:0;margin-bottom:0"><span>if (!HandleError(ec, \
&quot;something_async&quot;))</span></p> <blockquote style="padding: 0px; margin-top: \
0px; margin-right: 0px; margin-bottom: 0px;" dir="ltr"> <p \
style="margin-top:0;margin-bottom:0"><span>return; // shared_from_this() \
pattern</span></p> <p style="margin-top:0;margin-bottom:0"><span><br>
</span></p>
</blockquote>
</blockquote>
<span>
<p style="margin-top:0;margin-bottom:0">where HandleError is defined as</p>
<p style="margin-top:0;margin-bottom:0"><br>
</p>
<div style="margin-top:0;margin-bottom:0">
<blockquote style="padding: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: \
0px;" dir="ltr"> <div>bool HandleError(const error_code&amp; ec, const char* \
what)<br> {<br>
&nbsp;&nbsp;&nbsp; if (IsCanceled() || !_socket.is_open() || ec == \
boost::system::errc::operation_canceled)<br> \
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return false;<br> &nbsp;&nbsp;&nbsp; if \
(!ec)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return true;<br>
&nbsp; &nbsp; throw Failure(WeakSelf(), ec, what);<br>
}</div>
</blockquote>
<br>
</div>
<div style="margin-top:0;margin-bottom:0">(IsCanceled() returns the state of an \
internal Boolean flag.)</div> <div style="margin-top:0;margin-bottom:0"><br>
</div>
</span>because 1) the same io service thread is running multiple workers, 2) I need \
to know _which_ worker failed because the worker is associated with &quot;extra \
data&quot; in the io_service thread and this data may contain &quot;restart&quot; \
policy (e.g. reconnect on broken  connection). Also, the outer loop will cancel the \
worker in case Failure() has been thrown.</div> <div id="divtagdefaultwrapper" \
style="color: rgb(0, 0, 0); font-family: \
Calibri,Helvetica,sans-serif,&quot;EmojiFont&quot;,&quot;Apple Color \
Emoji&quot;,&quot;Segoe UI Emoji&quot;,NotoColorEmoji,&quot;Segoe UI \
Symbol&quot;,&quot;Android Emoji&quot;,EmojiSymbols; font-size: 12pt;" dir="ltr"> \
<br> </div>
<div id="divtagdefaultwrapper" style="color: rgb(0, 0, 0); font-family: \
Calibri,Helvetica,sans-serif,&quot;EmojiFont&quot;,&quot;Apple Color \
Emoji&quot;,&quot;Segoe UI Emoji&quot;,NotoColorEmoji,&quot;Segoe UI \
Symbol&quot;,&quot;Android Emoji&quot;,EmojiSymbols; font-size: 12pt;" dir="ltr"> But \
this seems to combine the worst of two worlds, as both exceptions and error codes are \
used. If I don't pass error_code to async calls, asio will throw system_error, but \
that one is not descriptive enough for my purposes.</div> <div \
id="divtagdefaultwrapper" style="color: rgb(0, 0, 0); font-family: \
Calibri,Helvetica,sans-serif,&quot;EmojiFont&quot;,&quot;Apple Color \
Emoji&quot;,&quot;Segoe UI Emoji&quot;,NotoColorEmoji,&quot;Segoe UI \
Symbol&quot;,&quot;Android Emoji&quot;,EmojiSymbols; font-size: 12pt;" dir="ltr"> \
<br> </div>
<div id="divtagdefaultwrapper" style="color: rgb(0, 0, 0); font-family: \
Calibri,Helvetica,sans-serif,&quot;EmojiFont&quot;,&quot;Apple Color \
Emoji&quot;,&quot;Segoe UI Emoji&quot;,NotoColorEmoji,&quot;Segoe UI \
Symbol&quot;,&quot;Android Emoji&quot;,EmojiSymbols; font-size: 12pt;" dir="ltr"> Is \
there a way to automate this, or some other recommended &quot;pattern&quot; to \
use?</div> <div id="divtagdefaultwrapper" style="color: rgb(0, 0, 0); font-family: \
Calibri,Helvetica,sans-serif,&quot;EmojiFont&quot;,&quot;Apple Color \
Emoji&quot;,&quot;Segoe UI Emoji&quot;,NotoColorEmoji,&quot;Segoe UI \
Symbol&quot;,&quot;Android Emoji&quot;,EmojiSymbols; font-size: 12pt;" dir="ltr"> \
<br> </div>
<div id="divtagdefaultwrapper" style="color: rgb(0, 0, 0); font-family: \
Calibri,Helvetica,sans-serif,&quot;EmojiFont&quot;,&quot;Apple Color \
Emoji&quot;,&quot;Segoe UI Emoji&quot;,NotoColorEmoji,&quot;Segoe UI \
                Symbol&quot;,&quot;Android Emoji&quot;,EmojiSymbols; font-size: \
                12pt;" dir="ltr">
-- Stian</div>
<div id="divtagdefaultwrapper" style="color: rgb(0, 0, 0); font-family: \
Calibri,Helvetica,sans-serif,&quot;EmojiFont&quot;,&quot;Apple Color \
Emoji&quot;,&quot;Segoe UI Emoji&quot;,NotoColorEmoji,&quot;Segoe UI \
Symbol&quot;,&quot;Android Emoji&quot;,EmojiSymbols; font-size: 12pt;" dir="ltr"> \
<br> </div>
<div id="divtagdefaultwrapper" style="color: rgb(0, 0, 0); font-family: \
Calibri,Helvetica,sans-serif,&quot;EmojiFont&quot;,&quot;Apple Color \
Emoji&quot;,&quot;Segoe UI Emoji&quot;,NotoColorEmoji,&quot;Segoe UI \
Symbol&quot;,&quot;Android Emoji&quot;,EmojiSymbols; font-size: 12pt;" dir="ltr"> \
<br> <div style="color: rgb(0, 0, 0);">
<hr tabindex="-1" style="display:inline-block;width:98%">
<div id="divRplyFwdMsg" dir="ltr"><font color="#000000" face="Calibri, sans-serif" \
style="font-size:11pt"><b>From:</b> Boost-users \
&lt;boost-users-bounces@lists.boost.org&gt; on behalf of Gavin Lambert via \
Boost-users &lt;boost-users@lists.boost.org&gt;<br> <b>Sent:</b> Monday, December 17, \
2018 10:28 PM<br> <b>To:</b> boost-users@lists.boost.org<br>
<b>Cc:</b> Gavin Lambert<br>
<b>Subject:</b> Re: [Boost-users] Understanding fibers</font>
<div>&nbsp;</div>
</div>
<div class="BodyFragment"><font size="2"><span style="font-size:11pt;">
<div class="PlainText">On 18/12/2018 02:07, Stian Zeljko Vrba wrote:<br>
&gt;&nbsp; 1. The above is inside a _/coroutine/_ and invoked as a callback? (my<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; guess: the caller – asio thread – arranges/provides \
a catch context<br> &gt;&nbsp;&nbsp;&nbsp;&nbsp; that the exception propagates \
into)<br> &gt;&nbsp; 2. The above is inside a _/fiber/_ and called by yielding to the \
fiber<br> &gt;&nbsp;&nbsp;&nbsp;&nbsp; scheduler? (my guess: the fiber scheduler does \
not provide an outer<br> &gt;&nbsp;&nbsp;&nbsp;&nbsp; catch context, so the program \
crashes).<br> &gt; <br>
&gt; Is this correct?<br>
<br>
Yes, both of those are somewhat correct.&nbsp; Though there are some missing <br>
links.<br>
<br>
With coroutines, you're yielding to a specific other coroutine -- if <br>
that coroutine throws, then the exception is thrown out of the yield <br>
point just as if it were a regular function call.<br>
<br>
Asio itself doesn't catch any exceptions -- if a handler throws then it <br>
will be propagated out and into the method that calls io_context.run() <br>
-- if this doesn't have a try-catch block wrapped around it by the user <br>
then the thread and the app will be terminated.<br>
<br>
Fibers aren't allowed to propagate exceptions into the fiber scheduler, <br>
since you can't customise the exception handling there -- but if you <br>
don't call your fiber code directly but instead wrap it in a <br>
packaged_task, this gives you a future and also wraps the code in a <br>
try-catch block such that if the code throws an exception it will store <br>
the exception into the future (where it can be rethrown at the consuming <br>
site) instead of terminating.&nbsp; (Thread-based futures work the same way.)<br>
_______________________________________________<br>
Boost-users mailing list<br>
Boost-users@lists.boost.org<br>
<a class="OWAAutoLink" id="LPlnk315955" \
href="https://lists.boost.org/mailman/listinfo.cgi/boost-users" \
previewremoved="true">https://lists.boost.org/mailman/listinfo.cgi/boost-users</a><br>
 </div>
</span></font></div>
</div>
</div>
</div>
</body>
</html>



_______________________________________________
Boost-users mailing list
Boost-users@lists.boost.org
https://lists.boost.org/mailman/listinfo.cgi/boost-users

--===============5148912743515192089==--

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic