which is the recommended way to execute a block with temporary change of a TxnLocal:
abstract sealed class Transition
case object NoTransition extends Transition
case class XFade( time: Float ) extends Transition
case class Ramp( time: Float ) extends Transition
val transition: new TxnLocal[ Transition ] {
override def initialValue( t: Txn ) = NoTransition
}
STM.atomic {
...
fade( 33 ) {
...
operationWhichCausesTxnToFail
...
}
...
}
where
def fade( time: Float )( thunk: => Unit )( implicit t: Txn ) {
val oldTrns = transition.swap( XFade( time ))
try {
thunk
}
finally {
if( t.status.mightCommit ) transition.set( oldTrns )
}
}
like this?
i assume i must add "if( t.status.mightCommit )" because otherwise if the inner operation fails, it might not be possible to call set any more. correct?
also i wonder what happens to transition if concurrent code is calling fade( ) { ... } ? will that be a problem, or will one fail immediately as transition has already done a write-action?
thanks, -sciss-
At the moment, TxnLocal.set doesn't check whether the current
transaction is doomed. This might need to change after I add partial
rollback, because TxnLocal values will be reverted if a nested
transaction fails. Regardless, it should always be okay to just revert
it directly
val old = aLocal.get
aLocal.set(newV)
try {
stuff
} finally {
aLocal.set(old)
}
When TxnLocal.set checks the transaction status in the future, it will
just regenerate the RollbackError if it finds a doomed transaction.
- Nathan