Boost logo

Boost :

Subject: Re: [boost] [afio] Formal review of Boost.AFIO
From: Niall Douglas (s_sourceforge_at_[hidden])
Date: 2015-08-27 20:28:11


On 27 Aug 2015 at 16:33, Gavin Lambert wrote:

> > If on the other hand you DO always want to delete and close the file
> > no matter what happened before you would write:
> >
> > auto a=async_file();
> > auto b=async_read(a);
> > auto c=async_truncate(b);
> > auto d=async_rmfile(depends(c, a));
> > auto e=async_close(d);
> >
> > The depends(precondition, input) function swaps the second future for
> > the first when the first completes. It is implemented as:
> >
> > precondition.then([input](future &&f) { return input; }
>
> That's handy but possibly a little unobvious (not that I can think of a
> better way to do it at the moment).
>
> (Also, what happens if the passed/returned future isn't ready yet? Does
> the caller cascade the wait / re-register itself as a continuation? Or
> is that an error?)

If the future is not ready, it schedules a continuation. If the
future is ready, it executes the continuation immediately (as per the
Concurrency TS).

> > It occurs to me that the above is exactly what should be on a first
> > page of a tutorial. To be honest, it never occurred to me the above
> > wasn't totally obvious. So I've logged that to
> > https://github.com/BoostGSoC13/boost.afio/issues/97.
> >
> > Thanks Gavin.
>
> Sounds good.
>
> I know error-checking is often elided from examples for brevity, but it
> does seem like it needs covering somewhere. Although I'm also being a
> bit nit-picky, admittedly.

Not at all. I've taken pains to make utterly sure that errors are
never lost and never cause data loss. The AFIO engine also prints a
stack backtrace of where an error occurred, both within the engine
and where in user code the operation was scheduled.

Indeed, I may have been a bit excessive, and let me explain. Nobody
seems to have noticed yet that if a precondition is errored at the
point of entering a function trying to schedule things against it, it
will immediately rethrow its error as if .get() had been called upon
it e.g.

auto a=async_file();
auto b=async_read(a);

// we go do something for a while, and during that time the
// async_read fails causing b to become errored

auto c=async_truncate(b); // this will throw, immediately

The advantage of this is that errors appear as soon as possible. The
disadvantage is that it makes every single afio::async_* function a
potential throw point which only throws under very exceptional
circumstances e.g. thrashing the swap file which is therefore likely
to not be well tested. Another disadvantage is you are converting any
error_code based state into an exception throw, and it's extra
handling to reverse that conversion.

I was hoping for boost-dev feedback on this design choice, and if it
is felt this is being overly paranoid, would simply pretending the
precondition state is not known be safe?

Niall

-- 
ned Productions Limited Consulting
http://www.nedproductions.biz/ 
http://ie.linkedin.com/in/nialldouglas/



Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk