Add some migration guidance for stm

This commit is contained in:
Peter Vlugter 2012-01-18 19:01:46 +13:00
parent 158bbabb58
commit b9bbb0744a

View file

@ -6,7 +6,9 @@
.. sidebar:: Contents
.. contents:: :local:
.. contents::
:local:
:depth: 3
Actors
======
@ -77,8 +79,11 @@ Last task of the migration would be to create your own ``ActorSystem``.
Unordered Collection of Migration Items
=======================================
Actors
------
Creating and starting actors
----------------------------
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Actors are created by passing in a ``Props`` instance into the actorOf factory method in
a ``ActorRefProvider``, which is the ``ActorSystem`` or ``ActorContext``.
@ -111,7 +116,7 @@ Documentation:
* :ref:`untyped-actors-java`
Stopping actors
---------------
^^^^^^^^^^^^^^^
``ActorRef.stop()`` has been moved. Use ``ActorSystem`` or ``ActorContext`` to stop actors.
@ -144,7 +149,7 @@ Documentation:
* :ref:`untyped-actors-java`
Identifying Actors
------------------
^^^^^^^^^^^^^^^^^^
In v1.3 actors have ``uuid`` and ``id`` field. In v2.0 each actor has a unique logical ``path``.
@ -167,7 +172,7 @@ Documentation:
* :ref:`untyped-actors-java`
Reply to messages
-----------------
^^^^^^^^^^^^^^^^^
``self.channel`` has been replaced with unified reply mechanism using ``sender`` (Scala)
or ``getSender()`` (Java). This works for both tell (!) and ask (?).
@ -189,7 +194,7 @@ Documentation:
* :ref:`untyped-actors-java`
``ActorRef.ask()``
------------------
^^^^^^^^^^^^^^^^^^
The mechanism for collecting an actors reply in a :class:`Future` has been
reworked for better location transparency: it uses an actor under the hood.
@ -206,7 +211,7 @@ Documentation:
* :ref:`untyped-actors-java`
ActorPool
---------
^^^^^^^^^
The ActorPool has been replaced by dynamically resizable routers.
@ -216,7 +221,7 @@ Documentation:
* :ref:`routing-java`
``UntypedActor.getContext()`` (Java API only)
---------------------------------------------
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
``getContext()`` in the Java API for UntypedActor is renamed to
``getSelf()``.
@ -234,7 +239,7 @@ Documentation:
* :ref:`untyped-actors-java`
Logging
-------
^^^^^^^
EventHandler API has been replaced by LoggingAdapter, which publish log messages
to the event bus. You can still plugin your own actor as event listener with the
@ -267,7 +272,7 @@ Documentation:
* :ref:`event-bus-java`
Supervision
-----------
^^^^^^^^^^^
Akka v2.0 implements parental supervision. Actors can only be created by other actors — where the top-level
actor is provided by the library — and each created actor is supervised by its parent.
@ -343,7 +348,7 @@ Documentation:
* :ref:`untyped-actors-java`
Spawn
-----
^^^^^
``spawn`` has been removed and can be implemented like this, if needed. Be careful to not
access any shared mutable state closed over by the body.
@ -359,7 +364,7 @@ Documentation:
* :ref:`jmm`
HotSwap
-------
^^^^^^^
In v2.0 ``become`` and ``unbecome`` metods are located in ``ActorContext``, i.e. ``context.become`` and ``context.unbecome``.
@ -370,15 +375,262 @@ in the actor receiving the message.
* :ref:`actors-scala`
* :ref:`untyped-actors-java`
STM
---
In Akka v2.0 `ScalaSTM`_ is used rather than Multiverse.
.. _ScalaSTM: http://nbronson.github.com/scala-stm/
Agent and Transactor have been ported to ScalaSTM. The API's for Agent and
Transactor are basically the same, other than integration with ScalaSTM. See:
* :ref:`agents-scala`
* :ref:`agents-java`
* :ref:`transactors-scala`
* :ref:`transactors-java`
Imports
^^^^^^^
Scala
~~~~~
To use ScalaSTM the import from Scala is::
import scala.concurrent.stm._
Java
~~~~
For Java there is a special JavaAPI helper object that can be statically
imported, along with any other imports that might be needed::
import scala.concurrent.stm.Ref;
import static scala.concurrent.stm.JavaAPI.*;
Transactions
^^^^^^^^^^^^
Scala
~~~~~
Both v1.3 and v2.0 provide an ``atomic`` block, however, the ScalaSTM ``atomic``
is a function from ``InTxn`` to return type.
v1.3::
atomic {
// do something in transaction
}
v2.0::
atomic { implicit txn =>
// do something in transaction
}
Note that in ScalaSTM the ``InTxn`` in the atomic function is usually marked as
implicit as transactional references require an implicit ``InTxn`` on all
methods. That is, the transaction is statically required and it is a
compile-time warning to use a reference without a transaction. There is also a
``Ref.View`` for operations without requiring an ``InTxn`` statically. See below
for more information.
Java
~~~~
In the ScalaSTM JavaAPI helpers there are atomic methods which accept
``java.lang.Runnable`` and ``java.util.concurrent.Callable``.
v1.3::
new Atomic() {
public Object atomically() {
// in transaction
return null;
}
}.execute();
SomeObject result = new Atomic<SomeObject>() {
public SomeObject atomically() {
// in transaction
return ...;
}
}.execute();
v2.0::
import static scala.concurrent.stm.JavaAPI.*;
import java.util.concurrent.Callable;
atomic(new Runnable() {
public void run() {
// in transaction
}
});
SomeObject result = atomic(new Callable<SomeObject>() {
public SomeObject call() {
// in transaction
return ...;
}
});
Ref
^^^
Scala
~~~~~
Other than the import, creating a Ref is basically identical between Akka STM in
v1.3 and ScalaSTM used in v2.0.
v1.3::
val ref = Ref(0)
v2.0::
val ref = Ref(0)
The API for Ref is similar. For example:
v1.3::
ref.get // get current value
ref() // same as get
ref.set(1) // set to new value, return old value
ref() = 1 // same as set
ref.swap(2) // same as set
ref alter { _ + 1 } // apply a function, return new value
v2.0::
ref.get // get current value
ref() // same as get
ref.set(1) // set to new value, return nothing
ref() = 1 // same as set
ref.swap(2) // set and return old value
ref transform { _ + 1 } // apply function, return nothing
ref transformIfDefined { case 1 => 2 } // apply partial function if defined
Ref.View
^^^^^^^^
In v1.3 using a ``Ref`` method outside of a transaction would automatically
create a single-operation transaction. In v2.0 (in ScalaSTM) there is a
``Ref.View`` which provides methods without requiring a current
transaction.
Scala
~~~~~
The ``Ref.View`` can be accessed with the ``single`` method::
ref.single() // returns current value
ref.single() = 1 // set new value
// with atomic this would be:
atomic { implicit t => ref() }
atomic { implicit t => ref() = 1 }
Java
~~~~
As ``Ref.View`` in ScalaSTM does not require implicit transactions, this is more
easily used from Java. ``Ref`` could be used, but requires explicit threading of
transactions. There are helper methods in ``JavaAPI`` for creating ``Ref.View``
references.
v1.3::
Ref<Integer> ref = new Ref<Integer>(0);
v2.0::
Ref.View<Integer> ref = newRef(0);
The ``set`` and ``get`` methods work the same way for both versions.
v1.3::
ref.get(); // get current value
ref.set(1); // set new value
v2.0::
ref.get(); // get current value
ref.set(1); // set new value
There are also ``transform``, ``getAndTransform``, and ``transformAndGet``
methods in ``JavaAPI`` which accept ``scala.runtime.AbstractFunction1``.
There are ``increment`` helper methods for ``Ref.View<Integer>`` and
``Ref.View<Long>`` references.
Transaction lifecycle callbacks
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Scala
~~~~~
It is also possible to hook into the transaction lifecycle in ScalaSTM. See the
ScalaSTM documentation for the full range of possibilities.
v1.3::
atomic {
deferred {
// executes when transaction commits
}
compensating {
// executes when transaction aborts
}
}
v2.0::
atomic { implicit txn =>
txn.afterCommit { txnStatus =>
// executes when transaction commits
}
txn.afterRollback { txnStatus =>
// executes when transaction rolls back
}
}
Java
~~~~
Rather than using the ``deferred`` and ``compensating`` methods in
``akka.stm.StmUtils``, use the ``afterCommit`` and ``afterRollback`` methods in
``scala.concurrent.stm.JavaAPI``, which behave in the same way and accept
``Runnable``.
Transactional Datastructures
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
In ScalaSTM see ``TMap``, ``TSet``, and ``TArray`` for transactional
datastructures. There are helper methods for creating these in
``JavaAPI``. These datastructure implement the ``scala.collection`` interfaces
and can also be used from Java with Scala's ``JavaConversions``.
More to be written
------------------
* Futures
* Dispatchers
* STM
* TypedActors
* Routing
* Remoting
* Scheduler
* Configuration
* ...?
* ...?