Update stm scaladoc
This commit is contained in:
parent
9f725b2742
commit
9a0b442704
7 changed files with 186 additions and 119 deletions
|
|
@ -14,18 +14,20 @@ object Transactor {
|
|||
}
|
||||
|
||||
/**
|
||||
* Transactor - an actor with built-in support for coordinated transactions.
|
||||
* <p/>
|
||||
* Transactors implement the general pattern for using Coordinated where first
|
||||
* any coordination messages are sent to other transactors, then the coordinated
|
||||
* An actor with built-in support for coordinated transactions.
|
||||
*
|
||||
* Transactors implement the general pattern for using [[akka.stm.Coordinated]] where
|
||||
* first any coordination messages are sent to other transactors, then the coordinated
|
||||
* transaction is entered.
|
||||
* <p/>
|
||||
* Simple transactors will just implement the 'atomically' method, similar to
|
||||
* the actor 'receive' method, but which runs within a coordinated transaction.
|
||||
* <p/>
|
||||
* Transactors can also accept explicitly sent `Coordinated` messages.
|
||||
* <br/><br/>
|
||||
*
|
||||
* Simple transactors will just implement the `atomically` method which similar to
|
||||
* the actor `receive` method but runs within a coordinated transaction.
|
||||
*
|
||||
* Example of a simple transactor that will join a coordinated transaction:
|
||||
* <p/>
|
||||
* <pre>
|
||||
*
|
||||
* {{{
|
||||
* class Counter extends Transactor {
|
||||
* val count = Ref(0)
|
||||
*
|
||||
|
|
@ -33,18 +35,19 @@ object Transactor {
|
|||
* case Increment => count alter (_ + 1)
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
* <p/>
|
||||
* To coordinate with other transactors override the 'coordinate' method.
|
||||
* The 'coordinate' method matches messages to a set of 'SendTo' objects,
|
||||
* a pair of ActorRef and Message. You can use the 'include' and 'sendTo' methods
|
||||
* to easily coordinate with other transactors. The 'include' method will send
|
||||
* on the same message that was received to other transactors. The 'sendTo' method
|
||||
* allows you to specify both the actor to send to, and message to send.
|
||||
* <p/>
|
||||
* Example of using coordinate:
|
||||
* <p/>
|
||||
* <pre>
|
||||
* }}}
|
||||
* <br/>
|
||||
*
|
||||
* To coordinate with other transactors override the `coordinate` method.
|
||||
* The `coordinate` method maps a message to a set
|
||||
* of [[akka.actor.Transactor.SendTo]] objects, pairs of `ActorRef` and a message.
|
||||
* You can use the `include` and `sendTo` methods to easily coordinate with other transactors.
|
||||
* The `include` method will send on the same message that was received to other transactors.
|
||||
* The `sendTo` method allows you to specify both the actor to send to, and message to send.
|
||||
*
|
||||
* Example of using coordinating an increment:
|
||||
*
|
||||
* {{{
|
||||
* class FriendlyCounter(friend: ActorRef) extends Transactor {
|
||||
* val count = Ref(0)
|
||||
*
|
||||
|
|
@ -56,37 +59,40 @@ object Transactor {
|
|||
* case Increment => count alter (_ + 1)
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
* <p/>
|
||||
* Using 'include' to include more than one transactor:
|
||||
* <p/>
|
||||
* <pre>
|
||||
* }}}
|
||||
* <br/>
|
||||
*
|
||||
* Using `include` to include more than one transactor:
|
||||
*
|
||||
* {{{
|
||||
* override def coordinate = {
|
||||
* case Message => include(actor1, actor2, actor3)
|
||||
* }
|
||||
* </pre>
|
||||
* <p/>
|
||||
* Using 'sendTo' to coordinate transactions but send on a different message
|
||||
* }}}
|
||||
* <br/>
|
||||
*
|
||||
* Using `sendTo` to coordinate transactions but send on a different message
|
||||
* than the one that was received:
|
||||
* <p/>
|
||||
* <pre>
|
||||
*
|
||||
* {{{
|
||||
* override def coordinate = {
|
||||
* case Message => sendTo(someActor -> SomeOtherMessage)
|
||||
* case SomeMessage => sendTo(actor1 -> Message1, actor2 -> Message2)
|
||||
* }
|
||||
* </pre>
|
||||
* <p/>
|
||||
* }}}
|
||||
* <br/>
|
||||
*
|
||||
* To exeucte directly before or after the coordinated transaction, override
|
||||
* the 'before' and 'after' methods. These methods also expect partial functions
|
||||
* the `before` and `after` methods. These methods also expect partial functions
|
||||
* like the receive method. They do not execute within the transaction.
|
||||
* <p/>
|
||||
* To completely bypass coordinated transactions override the normally method.
|
||||
* Any message matched by 'normally' will not be matched by the other methods,
|
||||
*
|
||||
* To completely bypass coordinated transactions override the `normally` method.
|
||||
* Any message matched by `normally` will not be matched by the other methods,
|
||||
* and will not be involved in coordinated transactions. In this method you
|
||||
* can implement normal actor behavior, or use the normal STM atomic for
|
||||
* local transactions.
|
||||
* <p/>
|
||||
* @see Coordinated for more information about the underlying mechanism.
|
||||
*
|
||||
* @see [[akka.stm.Coordinated]] for more information about the underlying mechanism
|
||||
*/
|
||||
trait Transactor extends Actor {
|
||||
import Transactor.SendTo
|
||||
|
|
|
|||
|
|
@ -6,10 +6,10 @@ package akka.stm
|
|||
|
||||
/**
|
||||
* Java-friendly atomic blocks.
|
||||
* <p/>
|
||||
* Example usage (in Java):
|
||||
* <p/>
|
||||
* <pre>
|
||||
*
|
||||
* Example usage ''(Java)''
|
||||
*
|
||||
* {{{
|
||||
* import akka.stm.*;
|
||||
*
|
||||
* final Ref<Integer> ref = new Ref<Integer>(0);
|
||||
|
|
@ -31,7 +31,7 @@ package akka.stm
|
|||
* return ref.get();
|
||||
* }
|
||||
* }.execute();
|
||||
* </pre>
|
||||
* }}}
|
||||
*/
|
||||
abstract class Atomic[T](factory: TransactionFactory) {
|
||||
def this() = this(DefaultTransactionFactory)
|
||||
|
|
|
|||
|
|
@ -21,52 +21,62 @@ object Coordinated {
|
|||
}
|
||||
|
||||
/**
|
||||
* Coordinated transactions across actors.
|
||||
* <p/>
|
||||
* Coordinated is a wrapper for any message that adds a CountDownCommitBarrier to
|
||||
* coordinate transactions across actors or threads. To start a new coordinated transaction
|
||||
* that you will also participate in, use:
|
||||
* <p/>
|
||||
* <pre>
|
||||
* `Coordinated` is a message wrapper that adds a `CountDownCommitBarrier` for explicitly
|
||||
* coordinating transactions across actors or threads.
|
||||
*
|
||||
* Creating a `Coordinated` will create a count down barrier with initially one member.
|
||||
* For each member in the coordination set a transaction is expected to be created using
|
||||
* the coordinated atomic method. The number of included parties must match the number of
|
||||
* transactions, otherwise a successful transaction cannot be coordinated.
|
||||
* <br/><br/>
|
||||
*
|
||||
* To start a new coordinated transaction set that you will also participate in just create
|
||||
* a `Coordinated` object:
|
||||
*
|
||||
* {{{
|
||||
* val coordinated = Coordinated()
|
||||
* </pre>
|
||||
* <p/>
|
||||
* Creating a Coordinated object will create a count down barrier with one member. For each
|
||||
* member in the coordination set a coordinated transaction is expected to be created.
|
||||
* <p/>
|
||||
* To start a coordinated transaction in another actor that you won't participate in yourself
|
||||
* can send the Coordinated message directly and the recipient is the first member of the
|
||||
* coordinating actors:
|
||||
* <p/>
|
||||
* <pre>
|
||||
* }}}
|
||||
* <br/>
|
||||
*
|
||||
* To start a coordinated transaction that you won't participate in yourself you can create a
|
||||
* `Coordinated` object with a message and send it directly to an actor. The recipient of the message
|
||||
* will be the first member of the coordination set:
|
||||
*
|
||||
* {{{
|
||||
* actor ! Coordinated(Message)
|
||||
* </pre>
|
||||
* <p/>
|
||||
* To receive a coordinated message in an actor:
|
||||
* <p/>
|
||||
* <pre>
|
||||
* }}}
|
||||
* <br/>
|
||||
*
|
||||
* To receive a coordinated message in an actor simply match it in a case statement:
|
||||
*
|
||||
* {{{
|
||||
* def receive = {
|
||||
* case coordinated @ Coordinated(Message) => ...
|
||||
* }
|
||||
* </pre>
|
||||
* <p/>
|
||||
* }}}
|
||||
* <br/>
|
||||
*
|
||||
* To include another actor in the same coordinated transaction set that you've created or
|
||||
* received, use the apply method on that object. This will increment the number of parties
|
||||
* involved by one.
|
||||
* <p/>
|
||||
* <pre>
|
||||
* involved by one and create a new `Coordinated` object to be sent.
|
||||
*
|
||||
* {{{
|
||||
* actor ! coordinated(Message)
|
||||
* </pre>
|
||||
* <p/>
|
||||
* To enter a coordinated transaction use the atomic method of the Coordinated object:
|
||||
* <p/>
|
||||
* <pre>
|
||||
* }}}
|
||||
* <br/>
|
||||
*
|
||||
* To enter the coordinated transaction use the atomic method of the coordinated object:
|
||||
*
|
||||
* {{{
|
||||
* coordinated atomic {
|
||||
* // Do something in transaction that will wait for the other transactions before committing.
|
||||
* // If any of the coordinated transactions fail then they all fail.
|
||||
* // do something in transaction ...
|
||||
* }
|
||||
* </pre>
|
||||
* <p/>
|
||||
* }}}
|
||||
*
|
||||
* The coordinated transaction will wait for the other transactions before committing.
|
||||
* If any of the coordinated transactions fail then they all fail.
|
||||
*
|
||||
* @see [[akka.actor.Transactor]] for an actor that implements coordinated transactions
|
||||
*/
|
||||
class Coordinated(val message: Any, barrier: CountDownCommitBarrier) {
|
||||
def apply(msg: Any) = {
|
||||
|
|
|
|||
|
|
@ -28,12 +28,12 @@ object Ref {
|
|||
* To ensure safety the value stored in a Ref should be immutable (they can also
|
||||
* contain refs themselves). The value referenced by a Ref can only be accessed
|
||||
* or swapped within a transaction. If a transaction is not available, the call will
|
||||
* be executed in its own transaction (equivalent to using the Ref.atomic* methods).
|
||||
* be executed in its own transaction.
|
||||
* <br/><br/>
|
||||
*
|
||||
* <p/>
|
||||
* Creating a Ref (in Scala):
|
||||
* <p/>
|
||||
* <pre>
|
||||
* Creating a Ref ''(Scala)''
|
||||
*
|
||||
* {{{
|
||||
* import akka.stm._
|
||||
*
|
||||
* // giving an initial value
|
||||
|
|
@ -41,12 +41,12 @@ object Ref {
|
|||
*
|
||||
* // specifying a type but no initial value
|
||||
* val ref = Ref[Int]
|
||||
* </pre>
|
||||
* }}}
|
||||
* <br/>
|
||||
*
|
||||
* <p/>
|
||||
* Creating a Ref (in Java):
|
||||
* <p/>
|
||||
* <pre>
|
||||
* Creating a Ref ''(Java)''
|
||||
*
|
||||
* {{{
|
||||
* import akka.stm.*;
|
||||
*
|
||||
* // giving an initial value
|
||||
|
|
@ -54,7 +54,7 @@ object Ref {
|
|||
*
|
||||
* // specifying a type but no initial value
|
||||
* final Ref<Integer> ref = new Ref<Integer>();
|
||||
* </pre>
|
||||
* }}}
|
||||
*/
|
||||
class Ref[T](initialValue: T) extends BasicRef[T](initialValue) with Transactional {
|
||||
self =>
|
||||
|
|
|
|||
|
|
@ -9,21 +9,26 @@ import org.multiverse.api.{Transaction => MultiverseTransaction}
|
|||
import org.multiverse.templates.{TransactionalCallable, OrElseTemplate}
|
||||
|
||||
/**
|
||||
* Stm trait that defines the atomic block for local transactions.
|
||||
* <p/>
|
||||
* If you need to coordinate transactions across actors @see Coordinated.
|
||||
* <p/>
|
||||
* Example of atomic transaction management using the atomic block (in Scala).
|
||||
* <p/>
|
||||
* <pre>
|
||||
* import akka.stm._
|
||||
* Defines the atomic block for local transactions. Automatically imported with:
|
||||
*
|
||||
* {{{
|
||||
* import akka.stm._
|
||||
* }}}
|
||||
* <br/>
|
||||
*
|
||||
* If you need to coordinate transactions across actors see [[akka.stm.Coordinated]].
|
||||
* <br/><br/>
|
||||
*
|
||||
* Example of using the atomic block ''(Scala)''
|
||||
*
|
||||
* {{{
|
||||
* atomic {
|
||||
* // do something within a transaction
|
||||
* }
|
||||
* </pre>
|
||||
* <p/>
|
||||
* @see Atomic for creating atomic blocks in Java.
|
||||
* }}}
|
||||
*
|
||||
* @see [[akka.stm.Atomic]] for creating atomic blocks in Java.
|
||||
* @see [[akka.stm.StmUtil]] for useful methods to combine with `atomic`
|
||||
*/
|
||||
trait Stm {
|
||||
val DefaultTransactionFactory = TransactionFactory(DefaultTransactionConfig, "DefaultTransaction")
|
||||
|
|
@ -42,7 +47,61 @@ trait Stm {
|
|||
}
|
||||
|
||||
/**
|
||||
* Stm utils for scheduling transaction lifecycle tasks and for blocking transactions.
|
||||
* Stm utility methods for scheduling transaction lifecycle tasks and for blocking transactions.
|
||||
* Automatically imported with:
|
||||
*
|
||||
* {{{
|
||||
* import akka.stm._
|
||||
* }}}
|
||||
* <br/>
|
||||
*
|
||||
* Schedule a deferred task on the thread local transaction (use within an atomic).
|
||||
* This is executed when the transaction commits.
|
||||
*
|
||||
* {{{
|
||||
* atomic {
|
||||
* deferred {
|
||||
* // executes when transaction successfully commits
|
||||
* }
|
||||
* }
|
||||
* }}}
|
||||
* <br/>
|
||||
*
|
||||
* Schedule a compensating task on the thread local transaction (use within an atomic).
|
||||
* This is executed when the transaction aborts.
|
||||
*
|
||||
* {{{
|
||||
* atomic {
|
||||
* compensating {
|
||||
* // executes when transaction aborts
|
||||
* }
|
||||
* }
|
||||
* }}}
|
||||
* <br/>
|
||||
*
|
||||
* STM retry for blocking transactions (use within an atomic).
|
||||
* Can be used to wait for a condition.
|
||||
*
|
||||
* {{{
|
||||
* atomic {
|
||||
* if (!someCondition) retry
|
||||
* // ...
|
||||
* }
|
||||
* }}}
|
||||
* <br/>
|
||||
*
|
||||
* Use either-orElse to combine two blocking transactions.
|
||||
*
|
||||
* {{{
|
||||
* atomic {
|
||||
* either {
|
||||
* // ...
|
||||
* } orElse {
|
||||
* // ...
|
||||
* }
|
||||
* }
|
||||
* }}}
|
||||
* <br/>
|
||||
*/
|
||||
trait StmUtil {
|
||||
/**
|
||||
|
|
@ -67,14 +126,6 @@ trait StmUtil {
|
|||
|
||||
/**
|
||||
* Use either-orElse to combine two blocking transactions.
|
||||
* Usage:
|
||||
* <pre>
|
||||
* either {
|
||||
* ...
|
||||
* } orElse {
|
||||
* ...
|
||||
* }
|
||||
* </pre>
|
||||
*/
|
||||
def either[T](firstBody: => T) = new {
|
||||
def orElse(secondBody: => T) = new OrElseTemplate[T] {
|
||||
|
|
|
|||
|
|
@ -202,7 +202,7 @@ trait Abortable {
|
|||
}
|
||||
|
||||
/**
|
||||
* For reflective access to the JTA module.
|
||||
* Used internally for reflective access to the JTA module.
|
||||
* Allows JTA integration to work when akka-jta.jar is on the classpath.
|
||||
*/
|
||||
object ReflectiveJtaModule {
|
||||
|
|
|
|||
|
|
@ -149,23 +149,23 @@ object TransactionFactory {
|
|||
/**
|
||||
* Wrapper for transaction config, factory, and boilerplate. Used by atomic.
|
||||
* Can be passed to atomic implicitly or explicitly.
|
||||
* <p/>
|
||||
* <pre>
|
||||
*
|
||||
* {{{
|
||||
* implicit val txFactory = TransactionFactory(readonly = true)
|
||||
* ...
|
||||
* atomic {
|
||||
* // do something within a readonly transaction
|
||||
* }
|
||||
* </pre>
|
||||
* <p/>
|
||||
* }}}
|
||||
*
|
||||
* Can be created at different levels as needed. For example: as an implicit object
|
||||
* used throughout a package, as a static implicit val within a singleton object and
|
||||
* imported where needed, or as an implicit val within each instance of a class.
|
||||
* <p/>
|
||||
*
|
||||
* If no explicit transaction factory is passed to atomic and there is no implicit
|
||||
* transaction factory in scope, then a default transaction factory is used.
|
||||
*
|
||||
* @see TransactionConfig for configuration options.
|
||||
* @see [[akka.stm.TransactionConfig]] for configuration options.
|
||||
*/
|
||||
class TransactionFactory(
|
||||
val config: TransactionConfig = DefaultTransactionConfig,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue