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 .. sidebar:: Contents
.. contents:: :local: .. contents::
:local:
:depth: 3
Actors Actors
====== ======
@ -77,8 +79,11 @@ Last task of the migration would be to create your own ``ActorSystem``.
Unordered Collection of Migration Items Unordered Collection of Migration Items
======================================= =======================================
Actors
------
Creating and starting actors Creating and starting actors
---------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Actors are created by passing in a ``Props`` instance into the actorOf factory method in Actors are created by passing in a ``Props`` instance into the actorOf factory method in
a ``ActorRefProvider``, which is the ``ActorSystem`` or ``ActorContext``. a ``ActorRefProvider``, which is the ``ActorSystem`` or ``ActorContext``.
@ -111,7 +116,7 @@ Documentation:
* :ref:`untyped-actors-java` * :ref:`untyped-actors-java`
Stopping actors Stopping actors
--------------- ^^^^^^^^^^^^^^^
``ActorRef.stop()`` has been moved. Use ``ActorSystem`` or ``ActorContext`` to stop actors. ``ActorRef.stop()`` has been moved. Use ``ActorSystem`` or ``ActorContext`` to stop actors.
@ -144,7 +149,7 @@ Documentation:
* :ref:`untyped-actors-java` * :ref:`untyped-actors-java`
Identifying Actors Identifying Actors
------------------ ^^^^^^^^^^^^^^^^^^
In v1.3 actors have ``uuid`` and ``id`` field. In v2.0 each actor has a unique logical ``path``. 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` * :ref:`untyped-actors-java`
Reply to messages Reply to messages
----------------- ^^^^^^^^^^^^^^^^^
``self.channel`` has been replaced with unified reply mechanism using ``sender`` (Scala) ``self.channel`` has been replaced with unified reply mechanism using ``sender`` (Scala)
or ``getSender()`` (Java). This works for both tell (!) and ask (?). or ``getSender()`` (Java). This works for both tell (!) and ask (?).
@ -189,7 +194,7 @@ Documentation:
* :ref:`untyped-actors-java` * :ref:`untyped-actors-java`
``ActorRef.ask()`` ``ActorRef.ask()``
------------------ ^^^^^^^^^^^^^^^^^^
The mechanism for collecting an actors reply in a :class:`Future` has been 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. reworked for better location transparency: it uses an actor under the hood.
@ -206,7 +211,7 @@ Documentation:
* :ref:`untyped-actors-java` * :ref:`untyped-actors-java`
ActorPool ActorPool
--------- ^^^^^^^^^
The ActorPool has been replaced by dynamically resizable routers. The ActorPool has been replaced by dynamically resizable routers.
@ -216,7 +221,7 @@ Documentation:
* :ref:`routing-java` * :ref:`routing-java`
``UntypedActor.getContext()`` (Java API only) ``UntypedActor.getContext()`` (Java API only)
--------------------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
``getContext()`` in the Java API for UntypedActor is renamed to ``getContext()`` in the Java API for UntypedActor is renamed to
``getSelf()``. ``getSelf()``.
@ -234,7 +239,7 @@ Documentation:
* :ref:`untyped-actors-java` * :ref:`untyped-actors-java`
Logging Logging
------- ^^^^^^^
EventHandler API has been replaced by LoggingAdapter, which publish log messages 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 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` * :ref:`event-bus-java`
Supervision Supervision
----------- ^^^^^^^^^^^
Akka v2.0 implements parental supervision. Actors can only be created by other actors — where the top-level 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. actor is provided by the library — and each created actor is supervised by its parent.
@ -343,7 +348,7 @@ Documentation:
* :ref:`untyped-actors-java` * :ref:`untyped-actors-java`
Spawn Spawn
----- ^^^^^
``spawn`` has been removed and can be implemented like this, if needed. Be careful to not ``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. access any shared mutable state closed over by the body.
@ -359,7 +364,7 @@ Documentation:
* :ref:`jmm` * :ref:`jmm`
HotSwap HotSwap
------- ^^^^^^^
In v2.0 ``become`` and ``unbecome`` metods are located in ``ActorContext``, i.e. ``context.become`` and ``context.unbecome``. 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:`actors-scala`
* :ref:`untyped-actors-java` * :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 More to be written
------------------ ------------------
* Futures * Futures
* Dispatchers * Dispatchers
* STM
* TypedActors * TypedActors
* Routing * Routing
* Remoting * Remoting
* Scheduler * Scheduler
* Configuration * Configuration
* ...? * ...?