Boost logo

Boost :

Subject: Re: [boost] [transact] code in sandbox
From: Vicente Botet Escriba (vicente.botet_at_[hidden])
Date: 2010-02-12 07:54:37


strasser wrote:
>
> Zitat von "vicente.botet" <vicente.botet_at_[hidden]>:
>
>>> why can't the user create his own try/catch block for that?:
>>> (using your syntax)
>>> BOOST_TRANSACT_ATOMIC(_) {
>>> try{
>>> ...
>>> }catch(my_exc &){
>>> _.commit();
>>> }
>>> }BOOST_TRANSACT_COMMIT();
>>
>> Yes this is always possible. However, transactions and exception
>> handling are used for the same goal, recover from errors. Thus it is
>> interesting to handle them in the same way and in a single
>> try-cactch block.
>
> why is this interesting?
>

One try-catch block instead on two :)

> if your goal is a language-like syntax, the user should not even have
> to be aware that the macro is implemented using a try/catch block. so
> why should he be able to add a catch-block? what's the advantage?
>

This is the reason to provide the macros BEFORE_RETRY, ON_EXCEPTION, and so
on. To hide this to the user.

>
> is this the only reason that you restart transaction objects instead
> of destructing and reconstructing them, or is there another?
>

The transaction variable must exist while handling the possible exceptions.
As the transaction variable has not been destroyed yet, we need to restart
the transaction on retry.

> from my viewpoint, it doesn't make sense to "restart" a transaction.
> when a transaction fails, you can repeat the operations in it in a new
> transaction. but there is no such thing as "restarting" it.
>
> this would require considerable support from resource managers, so
> that each of them can reuse the transaction object for a new
> transaction.
>

On TBoost.STM the restat operation is less expensive than creating a
transaction.

>>>> _.force_to_abort();
>>>
>>> what does this do? retry the transaction but make sure it fails? why?
>>> why don't you just go ahead and throw an exception that is not caught
>>> inside the transaction scope?
>>
>> When the user wants to undo whatever the transacton block did, the
>> simple way is to abort the transaction. Don't forget that
>> transactions can be used in a single-threaded application to make
>> exception-safe code.
>
> yes, but what's wrong with throwing an exception that is uncaught in
> the transaction scope?
> undoing the transaction is the default behaviour when a transaction
> object is destructed.
>

Sometimes the user can not throw an exception because s/he is handling
already an exception, on it is in a no throw function destructor, ... In
these cases it will be more convenient to just state that the transaction
could only abort.

>
>
>> The question is what is the simple case. for an INNER transaction
>> Boost.STM provides a macro
>
> snip
>
>>
>> #define BOOST_STM_USE_ATOMIC(TX) \
>> for (boost::stm::transaction TX; \
>> ! TX.committed() \
>> && TX.restart(); \
>> TX.commit())
>>
>
> I was talking about "simple" from the user's perspective, not
> implementation-wise.
> I'd also prefer a macro xxx{} instead of a combination of two macros
> xxx{}yyy(); but since this is not possible in all cases, it is better
> to provide only the latter imho.
> providing another macro only to avoid writing yyy() in some
> cases(nested transactions) is confusing. you have to understand
> implementation details in order to decide if you can save yourself
> writing yyy().
>

This use is simple for the user perspective and efficient from the
implementation point of view. I respect you wish to provide only a macro,
but IMO there are more use cases than one on which macros could be used.

>>
>> As I said in a preceding post, we can provide initially both sets of
>> macros and see which set the users use more often.
>
> yes, we can always do that. I'd still like to understand the benefit
> of the additional macros.
>

Well you see these as additional macros. I see as initial macros from
TBoost.STM.

>
> you have clearly spent more time than me on this topic and I'm looking
> forward to the paper, but right now I honestly don't see the benefit.
> the benefit of the simple macro is 1) a less verbose interface, not
> having to write a loop each time, and 2) saving the user from the
> implementation details.
>
>

With my macros or with yours, the user needs to be aware that the
transaction block is included on a internal loop. Otherwise his code could
not work. For example with your macro (that hides the transaction variable)
the user is unable to exit successfully from the transaction block.

int f() {
  BOOST_TRANSACT_ATOMIC {
      ...
     return 1; // do not commits
      ...
  }BOOST_TRANSACT_COMMIT;
}
 
will not behaves as the user expects. With the STM macros the user could do

int f() {
  BOOST_TRANSACT_ATOMIC(_) {
      ...
     _.commit(); return 1;
  // or
     BOOST_TRANSACT_RETURN(_, 1);

      ...
  } BOOST_TRANSACT_RETRY(_);
}

>
> when the user needs to have control over code-on-retry etc., using the
> macros is not less verbose and the user has to be aware of the details
> that this is implemented as a loop and a try/catch block.
> having more than one choice on which macro to use even adds complexity.
>
>

Maybe you are right, may be not. All these depend on whether we found a good
macro name for each common use case. I hope we will find out these common
use cases and appropriated names together.

Best,
Vicente

-- 
View this message in context: http://old.nabble.com/-transact--code-in-sandbox-tp27515535p27563130.html
Sent from the Boost - Dev mailing list archive at Nabble.com.

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