Merge with latest changes on akka/master and simplify OSGi configuration section

Conflicts:
	project/AkkaBuild.scala
This commit is contained in:
Gert Vanthienen 2012-05-24 23:34:20 +02:00
commit e24f7077ec
264 changed files with 9794 additions and 3334 deletions

View file

@ -334,3 +334,10 @@ same machine at the same time.
The machines that are used for testing (slaves) should have ssh access to the outside world and be able to talk
to each other with the internal addresses given. On the master machine ssh client is required. Obviosly git
and sbt should be installed on both master and slave machines.
The Test Conductor Extension
============================
The Test Conductor Extension is aimed at enhancing the multi JVM and multi node testing facilities.
.. image:: ../images/akka-remote-testconductor.png

View file

@ -14,6 +14,11 @@ which means that we need not concern ourselves with their emotional state or
moral issues). The result can then serve as a mental scaffolding for building
the software implementation.
.. note::
An ActorSystem is a heavyweight structure that will allocate 1…N Threads,
so create one per logical application.
Hierarchical Structure
----------------------

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.config;
package docs.config;
import akka.actor.ActorSystem;
import com.typesafe.config.*;

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.config
package docs.config
import org.scalatest.WordSpec
import org.scalatest.matchers.MustMatchers

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View file

@ -1,109 +0,0 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.serialization;
import org.junit.Test;
import static org.junit.Assert.*;
//#imports
import akka.actor.*;
import akka.serialization.*;
import com.typesafe.config.*;
//#imports
public class SerializationDocTestBase {
//#my-own-serializer
public static class MyOwnSerializer extends JSerializer {
// This is whether "fromBinary" requires a "clazz" or not
@Override public boolean includeManifest() {
return false;
}
// Pick a unique identifier for your Serializer,
// you've got a couple of billions to choose from,
// 0 - 16 is reserved by Akka itself
@Override public int identifier() {
return 1234567;
}
// "toBinary" serializes the given object to an Array of Bytes
@Override public byte[] toBinary(Object obj) {
// Put the code that serializes the object here
//#...
return new byte[0];
//#...
}
// "fromBinary" deserializes the given array,
// using the type hint (if any, see "includeManifest" above)
@Override public Object fromBinaryJava(byte[] bytes,
Class<?> clazz) {
// Put your code that deserializes here
//#...
return null;
//#...
}
}
//#my-own-serializer
@Test public void serializeActorRefs() {
final ActorSystem theActorSystem =
ActorSystem.create("whatever");
final ActorRef theActorRef =
theActorSystem.deadLetters(); // Of course this should be you
//#actorref-serializer
// Serialize
// (beneath toBinary)
final Address transportAddress =
Serialization.currentTransportAddress().value();
String identifier;
// If there is no transportAddress,
// it means that either this Serializer isn't called
// within a piece of code that sets it,
// so either you need to supply your own,
// or simply use the local path.
if (transportAddress == null) identifier = theActorRef.path().toString();
else identifier = theActorRef.path().toStringWithAddress(transportAddress);
// Then just serialize the identifier however you like
// Deserialize
// (beneath fromBinary)
final ActorRef deserializedActorRef = theActorSystem.actorFor(identifier);
// Then just use the ActorRef
//#actorref-serializer
theActorSystem.shutdown();
}
@Test public void demonstrateTheProgrammaticAPI() {
//#programmatic
ActorSystem system = ActorSystem.create("example");
// Get the Serialization Extension
Serialization serialization = SerializationExtension.get(system);
// Have something to serialize
String original = "woohoo";
// Find the Serializer for it
Serializer serializer = serialization.findSerializerFor(original);
// Turn it into bytes
byte[] bytes = serializer.toBinary(original);
// Turn it back into an object,
// the nulls are for the class manifest and for the classloader
String back = (String)serializer.fromBinary(bytes);
// Voilá!
assertEquals(original, back);
//#programmatic
system.shutdown();
}
}

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.actor
package docs.actor
import org.scalatest.junit.JUnitSuite

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.actor;
package docs.actor;
//#imports-data
import java.util.ArrayList;

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.actor
package docs.actor
import org.scalatest.junit.JUnitSuite
class FaultHandlingTest extends FaultHandlingTestBase with JUnitSuite

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.actor;
package docs.actor;
//#testkit
import akka.actor.ActorRef;

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.actor;
package docs.actor;
import akka.actor.ActorRef;
import akka.actor.Props;

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.actor;
package docs.actor;
import java.util.ArrayList;
import java.util.Collections;

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.actor;
package docs.actor;
//#receive-timeout
import akka.actor.ReceiveTimeout;

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.actor;
package docs.actor;
//#my-untyped-actor
import akka.actor.UntypedActor;

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.actor
package docs.actor
import org.scalatest.junit.JUnitSuite

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.actor;
package docs.actor;
//#imports1
import akka.actor.Props;

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.actor
package docs.actor
import org.scalatest.junit.JUnitSuite

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.actor;
package docs.actor;
//#imports

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.actor
package docs.actor
import org.scalatest.junit.JUnitSuite

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.actor;
package docs.actor;
//#imports
import akka.actor.ActorRef;
@ -36,7 +36,7 @@ import static akka.pattern.Patterns.gracefulStop;
import akka.dispatch.Future;
import akka.dispatch.Await;
import akka.util.Duration;
import akka.actor.ActorTimeoutException;
import akka.pattern.AskTimeoutException;
//#import-gracefulStop
//#import-askPipe
@ -207,7 +207,7 @@ public class UntypedActorDocTestBase {
Future<Boolean> stopped = gracefulStop(actorRef, Duration.create(5, TimeUnit.SECONDS), system);
Await.result(stopped, Duration.create(6, TimeUnit.SECONDS));
// the actor has been stopped
} catch (ActorTimeoutException e) {
} catch (AskTimeoutException e) {
// the actor wasn't stopped within 5 seconds
}
//#gracefulStop

View file

@ -1,9 +1,9 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.actor;
package docs.actor;
import static akka.docs.actor.UntypedActorSwapper.Swap.SWAP;
import static docs.actor.UntypedActorSwapper.Swap.SWAP;
import akka.actor.ActorRef;
import akka.actor.Props;
import akka.actor.ActorSystem;

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.actor.japi;
package docs.actor.japi;
//#all
//#imports
@ -26,10 +26,10 @@ import static akka.actor.SupervisorStrategy.*;
import static akka.pattern.Patterns.ask;
import static akka.pattern.Patterns.pipe;
import static akka.docs.actor.japi.FaultHandlingDocSample.WorkerApi.*;
import static akka.docs.actor.japi.FaultHandlingDocSample.CounterServiceApi.*;
import static akka.docs.actor.japi.FaultHandlingDocSample.CounterApi.*;
import static akka.docs.actor.japi.FaultHandlingDocSample.StorageApi.*;
import static docs.actor.japi.FaultHandlingDocSample.WorkerApi.*;
import static docs.actor.japi.FaultHandlingDocSample.CounterServiceApi.*;
import static docs.actor.japi.FaultHandlingDocSample.CounterApi.*;
import static docs.actor.japi.FaultHandlingDocSample.StorageApi.*;
//#imports

View file

@ -1,10 +1,10 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.agent
package docs.agent
import org.scalatest.junit.JUnitWrapperSuite
class AgentDocJavaSpec extends JUnitWrapperSuite(
"akka.docs.agent.AgentDocTest",
"docs.agent.AgentDocTest",
Thread.currentThread.getContextClassLoader)

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.agent;
package docs.agent;
import static org.junit.Assert.*;

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.dispatcher
package docs.dispatcher
import org.scalatest.junit.JUnitSuite

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.dispatcher;
package docs.dispatcher;
//#imports
import akka.actor.*;
@ -32,8 +32,8 @@ import static org.junit.Assert.*;
import com.typesafe.config.ConfigFactory;
import akka.docs.actor.MyUntypedActor;
import akka.docs.actor.UntypedActorDocTestBase.MyActor;
import docs.actor.MyUntypedActor;
import docs.actor.UntypedActorDocTestBase.MyActor;
import akka.testkit.AkkaSpec;
public class DispatcherDocTestBase {

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.event
package docs.event
import org.scalatest.junit.JUnitSuite

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.event;
package docs.event;
//#imports
import akka.event.Logging;

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.extension
package docs.extension
import org.scalatest.junit.JUnitSuite

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.extension;
package docs.extension;
//#imports
import akka.actor.*;

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.extension
package docs.extension
import org.scalatest.junit.JUnitSuite

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.extension;
package docs.extension;
//#imports
import akka.actor.Extension;

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.future
package docs.future
import org.scalatest.junit.JUnitSuite

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.future;
package docs.future;
//#imports1
import akka.dispatch.*;

View file

@ -1,4 +1,4 @@
package akka.docs.jrouting;
package docs.jrouting;
import org.scalatest.junit.JUnitSuite

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.jrouting;
package docs.jrouting;
import java.util.List;
import java.util.Arrays;
@ -22,9 +22,9 @@ import akka.testkit.AkkaSpec;
import com.typesafe.config.ConfigFactory;
import static akka.pattern.Patterns.ask;
import static akka.docs.jrouting.CustomRouterDocTestBase.DemocratActor;
import static akka.docs.jrouting.CustomRouterDocTestBase.RepublicanActor;
import static akka.docs.jrouting.CustomRouterDocTestBase.Message.*;
import static docs.jrouting.CustomRouterDocTestBase.DemocratActor;
import static docs.jrouting.CustomRouterDocTestBase.RepublicanActor;
import static docs.jrouting.CustomRouterDocTestBase.Message.*;
public class CustomRouterDocTestBase {

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.jrouting;
package docs.jrouting;
import java.io.Serializable;

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.jrouting;
package docs.jrouting;
import akka.routing.ScatterGatherFirstCompletedRouter;
import akka.routing.BroadcastRouter;

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.jrouting;
package docs.jrouting;
import akka.actor.UntypedActor;

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.jrouting;
package docs.jrouting;
import akka.routing.FromConfig;
import akka.actor.ActorRef;

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.jrouting;
package docs.jrouting;
import akka.routing.RoundRobinRouter;
import akka.routing.DefaultResizer;
@ -55,7 +55,7 @@ public class RouterViaProgramExample {
ActorRef actor2 = system.actorOf(new Props(ExampleActor.class));
ActorRef actor3 = system.actorOf(new Props(ExampleActor.class));
Iterable<ActorRef> routees = Arrays.asList(new ActorRef[] { actor1, actor2, actor3 });
ActorRef router2 = system.actorOf(new Props(ExampleActor.class).withRouter(RoundRobinRouter.create(routees)));
ActorRef router2 = system.actorOf(new Props().withRouter(RoundRobinRouter.create(routees)));
//#programmaticRoutingRoutees
for (int i = 1; i <= 6; i++) {
router2.tell(new ExampleActor.Message(i));

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.remoting;
package docs.remoting;
import akka.actor.ActorRef;
import akka.actor.UntypedActor;

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.remoting
package docs.remoting
import org.scalatest.junit.JUnitSuite

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.remoting;
package docs.remoting;
import org.junit.AfterClass;
import org.junit.BeforeClass;

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.serialization
package docs.serialization
import org.scalatest.junit.JUnitSuite

View file

@ -0,0 +1,196 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package docs.serialization;
import org.junit.Test;
import static org.junit.Assert.*;
//#imports
import akka.actor.*;
import akka.remote.RemoteActorRefProvider;
import akka.serialization.*;
import com.typesafe.config.*;
//#imports
public class SerializationDocTestBase {
//#my-own-serializer
public static class MyOwnSerializer extends JSerializer {
// This is whether "fromBinary" requires a "clazz" or not
@Override public boolean includeManifest() {
return false;
}
// Pick a unique identifier for your Serializer,
// you've got a couple of billions to choose from,
// 0 - 16 is reserved by Akka itself
@Override public int identifier() {
return 1234567;
}
// "toBinary" serializes the given object to an Array of Bytes
@Override public byte[] toBinary(Object obj) {
// Put the code that serializes the object here
//#...
return new byte[0];
//#...
}
// "fromBinary" deserializes the given array,
// using the type hint (if any, see "includeManifest" above)
@Override public Object fromBinaryJava(byte[] bytes,
Class<?> clazz) {
// Put your code that deserializes here
//#...
return null;
//#...
}
}
//#my-own-serializer
@Test public void serializeActorRefs() {
final ActorSystem theActorSystem =
ActorSystem.create("whatever");
final ActorRef theActorRef =
theActorSystem.deadLetters(); // Of course this should be you
//#actorref-serializer
// Serialize
// (beneath toBinary)
final Address transportAddress =
Serialization.currentTransportAddress().value();
String identifier;
// If there is no transportAddress,
// it means that either this Serializer isn't called
// within a piece of code that sets it,
// so either you need to supply your own,
// or simply use the local path.
if (transportAddress == null) identifier = theActorRef.path().toString();
else identifier = theActorRef.path().toStringWithAddress(transportAddress);
// Then just serialize the identifier however you like
// Deserialize
// (beneath fromBinary)
final ActorRef deserializedActorRef = theActorSystem.actorFor(identifier);
// Then just use the ActorRef
//#actorref-serializer
theActorSystem.shutdown();
}
//#external-address
public static class ExternalAddressExt implements Extension {
private final ExtendedActorSystem system;
public ExternalAddressExt(ExtendedActorSystem system) {
this.system = system;
}
public Address getAddressFor(Address remoteAddress) {
final scala.Option<Address> optAddr = system.provider()
.getExternalAddressFor(remoteAddress);
if (optAddr.isDefined()) {
return optAddr.get();
} else {
throw new UnsupportedOperationException(
"cannot send to remote address " + remoteAddress);
}
}
}
public static class ExternalAddress extends
AbstractExtensionId<ExternalAddressExt> implements ExtensionIdProvider {
public static final ExternalAddress ID = new ExternalAddress();
public ExternalAddress lookup() {
return ID;
}
public ExternalAddressExt createExtension(ExtendedActorSystem system) {
return new ExternalAddressExt(system);
}
}
//#external-address
public void demonstrateExternalAddress() {
// this is not meant to be run, only to be compiled
final ActorSystem system = ActorSystem.create();
final Address remoteAddr = new Address("", "");
// #external-address
final Address addr = ExternalAddress.ID.get(system).getAddressFor(remoteAddr);
// #external-address
}
//#external-address-default
public static class DefaultAddressExt implements Extension {
private final ExtendedActorSystem system;
public DefaultAddressExt(ExtendedActorSystem system) {
this.system = system;
}
public Address getAddress() {
final ActorRefProvider provider = system.provider();
if (provider instanceof RemoteActorRefProvider) {
return ((RemoteActorRefProvider) provider).transport().address();
} else {
throw new UnsupportedOperationException("need RemoteActorRefProvider");
}
}
}
public static class DefaultAddress extends
AbstractExtensionId<DefaultAddressExt> implements ExtensionIdProvider {
public static final DefaultAddress ID = new DefaultAddress();
public DefaultAddress lookup() {
return ID;
}
public DefaultAddressExt createExtension(ExtendedActorSystem system) {
return new DefaultAddressExt(system);
}
}
//#external-address-default
public void demonstrateDefaultAddress() {
// this is not meant to be run, only to be compiled
final ActorSystem system = ActorSystem.create();
final Address remoteAddr = new Address("", "");
// #external-address-default
final Address addr = DefaultAddress.ID.get(system).getAddress();
// #external-address-default
}
@Test
public void demonstrateTheProgrammaticAPI() {
// #programmatic
ActorSystem system = ActorSystem.create("example");
// Get the Serialization Extension
Serialization serialization = SerializationExtension.get(system);
// Have something to serialize
String original = "woohoo";
// Find the Serializer for it
Serializer serializer = serialization.findSerializerFor(original);
// Turn it into bytes
byte[] bytes = serializer.toBinary(original);
// Turn it back into an object,
// the nulls are for the class manifest and for the classloader
String back = (String) serializer.fromBinary(bytes);
// Voilá!
assertEquals(original, back);
// #programmatic
system.shutdown();
}
}

View file

@ -2,7 +2,7 @@
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.transactor;
package docs.transactor;
//#class
import akka.actor.*;

View file

@ -2,7 +2,7 @@
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.transactor;
package docs.transactor;
import akka.actor.*;
import akka.transactor.*;

View file

@ -2,7 +2,7 @@
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.transactor;
package docs.transactor;
//#class
import akka.transactor.*;

View file

@ -2,7 +2,7 @@
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.transactor;
package docs.transactor;
//#class
import akka.actor.*;

View file

@ -2,7 +2,7 @@
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.transactor;
package docs.transactor;
//#class
import akka.actor.ActorRef;

View file

@ -2,6 +2,6 @@
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.transactor;
package docs.transactor;
public class Message {}

View file

@ -2,10 +2,10 @@
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.transactor
package docs.transactor
import org.scalatest.junit.JUnitWrapperSuite
class TransactorDocJavaSpec extends JUnitWrapperSuite(
"akka.docs.transactor.TransactorDocTest",
"docs.transactor.TransactorDocTest",
Thread.currentThread.getContextClassLoader)

View file

@ -2,7 +2,7 @@
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.transactor;
package docs.transactor;
import static org.junit.Assert.*;
import org.junit.Test;

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.zeromq
package docs.zeromq
import org.scalatest.junit.JUnitSuite

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.zeromq;
package docs.zeromq;
//#pub-socket
import akka.zeromq.Bind;

View file

@ -70,7 +70,7 @@ There are 4 different types of message dispatchers:
* BalancingDispatcher
- This is an executor based event driven dispatcher that will try to redistribute work from busy actors to idle actors.
- This is an executor based event driven dispatcher that will try to redistribute work from busy actors to idle actors.
- It is assumed that all actors using the same instance of this dispatcher can process all messages that have been sent to one of the actors; i.e. the actors belong to a pool of actors, and to the client there is no guarantee about which actor instance actually processes a given message.
@ -85,9 +85,11 @@ There are 4 different types of message dispatchers:
"thread-pool-executor" or the FQCN of
an ``akka.dispatcher.ExecutorServiceConfigurator``
- Note that you can **not** use a ``BalancingDispatcher`` together with any kind of ``Router``, trying to do so will make your actor fail verification.
* CallingThreadDispatcher
- This dispatcher runs invocations on the current thread only. This dispatcher does not create any new threads,
- This dispatcher runs invocations on the current thread only. This dispatcher does not create any new threads,
but it can be used from different threads concurrently for the same actor. See :ref:`TestCallingThreadDispatcherRef`
for details and restrictions.

View file

@ -54,7 +54,7 @@ in the "akka.extensions" section of the config you provide to your ``ActorSystem
::
akka {
extensions = ["akka.docs.extension.ExtensionDocTestBase.CountExtension"]
extensions = ["docs.extension.ExtensionDocTestBase.CountExtension"]
}
Applicability

View file

@ -4,6 +4,10 @@
Microkernel (Java)
==================
The purpose of the Akka Microkernel is to offer a bundling mechanism so that you can distribute
an Akka application as a single payload, without the need to run in a Java Application Server or manually
having to create a launcher script.
The Akka Microkernel is included in the Akka download found at `downloads`_.
.. _downloads: http://akka.io/downloads

View file

@ -294,3 +294,63 @@ which holds the transport used (RemoteTransport) and optionally the address that
To intercept when an inbound remote client has been closed you listen to ``RemoteServerClientClosed``
which holds the transport used (RemoteTransport) and optionally the address of the remote client that was closed (Option<Address>).
Remote Security
^^^^^^^^^^^^^^^
Akka provides a couple of ways to enhance security between remote nodes (client/server):
* Untrusted Mode
* Security Cookie Handshake
Untrusted Mode
--------------
You can enable untrusted mode for preventing system messages to be send by clients, e.g. messages like.
This will prevent the client to send these messages to the server:
* ``Create``
* ``Recreate``
* ``Suspend``
* ``Resume``
* ``Terminate``
* ``Supervise``
* ``ChildTerminated``
* ``Link``
* ``Unlink``
Here is how to turn it on in the config::
akka {
actor {
remote {
untrusted-mode = on
}
}
}
Secure Cookie Handshake
-----------------------
Akka remoting also allows you to specify a secure cookie that will be exchanged and ensured to be identical
in the connection handshake between the client and the server. If they are not identical then the client
will be refused to connect to the server.
The secure cookie can be any kind of string. But the recommended approach is to generate a cryptographically
secure cookie using this script ``$AKKA_HOME/scripts/generate_config_with_secure_cookie.sh`` or from code
using the ``akka.util.Crypt.generateSecureCookie()`` utility method.
You have to ensure that both the connecting client and the server have the same secure cookie as well
as the ``require-cookie`` option turned on.
Here is an example config::
akka {
actor {
remote {
netty {
secure-cookie = "090A030E0F0A05010900000A0C0E0C0B03050D05"
require-cookie = on
}
}
}
}

View file

@ -33,6 +33,11 @@ You can also give the router already created routees as in:
.. includecode:: code/akka/docs/jrouting/RouterViaProgramExample.java#programmaticRoutingRoutees
It should be noted that no actor factory or class needs to be provided in this
case, as the ``Router`` will not create any children on its own (which is not
true anymore when using a resizer). The routees can also be specified by giving
their path strings.
When you create a router programmatically you define the number of routees *or* you pass already created routees to it.
If you send both parameters to the router *only* the latter will be used, i.e. ``nrOfInstances`` is disregarded.
@ -48,7 +53,7 @@ Once you have the router actor it is just to send messages to it as you would to
router.tell(new MyMsg());
The router will apply its behavior to the message it receives and forward it to the routees.
The router will forward the message to its routees according to its routing policy.
Remotely Deploying Routees
**************************
@ -375,7 +380,8 @@ The dispatcher for created children of the router will be taken from
makes sense to configure the :class:`BalancingDispatcher` if the precise
routing is not so important (i.e. no consistent hashing or round-robin is
required); this enables newly created routees to pick up work immediately by
stealing it from their siblings.
stealing it from their siblings. Note that you can **not** use a ``BalancingDispatcher``
together with any kind of ``Router``, trying to do so will make your actor fail verification.
The “head” router, of course, cannot run on the same balancing dispatcher,
because it does not process the same messages, hence this special actor does

View file

@ -85,7 +85,7 @@ Customization
=============
So, lets say that you want to create your own ``Serializer``,
you saw the ``akka.docs.serialization.MyOwnSerializer`` in the config example above?
you saw the ``docs.serialization.MyOwnSerializer`` in the config example above?
Creating new Serializers
------------------------
@ -109,6 +109,47 @@ you might want to know how to serialize and deserialize them properly, here's th
.. includecode:: code/akka/docs/serialization/SerializationDocTestBase.java
:include: imports,actorref-serializer
.. note::
``ActorPath.toStringWithAddress`` only differs from ``toString`` if the
address does not already have ``host`` and ``port`` components, i.e. it only
inserts address information for local addresses.
This assumes that serialization happens in the context of sending a message
through the remote transport. There are other uses of serialization, though,
e.g. storing actor references outside of an actor application (database,
durable mailbox, etc.). In this case, it is important to keep in mind that the
address part of an actors path determines how that actor is communicated with.
Storing a local actor path might be the right choice if the retrieval happens
in the same logical context, but it is not enough when deserializing it on a
different network host: for that it would need to include the systems remote
transport address. An actor system is not limited to having just one remote
transport per se, which makes this question a bit more interesting.
In the general case, the local address to be used depends on the type of remote
address which shall be the recipient of the serialized information. Use
:meth:`ActorRefProvider.getExternalAddressFor(remoteAddr)` to query the system
for the appropriate address to use when sending to ``remoteAddr``:
.. includecode:: code/akka/docs/serialization/SerializationDocTestBase.java
:include: external-address
This requires that you know at least which type of address will be supported by
the system which will deserialize the resulting actor reference; if you have no
concrete address handy you can create a dummy one for the right protocol using
``new Address(protocol, "", "", 0)`` (assuming that the actual transport used is as
lenient as Akkas RemoteActorRefProvider).
There is a possible simplification available if you are just using the default
:class:`NettyRemoteTransport` with the :meth:`RemoteActorRefProvider`, which is
enabled by the fact that this combination has just a single remote address:
.. includecode:: code/akka/docs/serialization/SerializationDocTestBase.java
:include: external-address-default
This solution has to be adapted once other providers are used (like the planned
extensions for clustering).
Deep serialization of Actors
----------------------------
@ -137,3 +178,10 @@ representation into a real reference. :class:`DynamicVariable` is a
thread-local variable, so be sure to have it set while deserializing anything
which might contain actor references.
External Akka Serializers
=========================
`Akka-protostuff by Roman Levenstein<https://github.com/romix/akka-protostuff-serialization>`_
`Akka-quickser by Roman Levenstein<https://github.com/romix/akka-quickser-serialization>`_

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.actor.mailbox
package docs.actor.mailbox
//#imports
import akka.actor.Props
@ -107,7 +107,7 @@ import akka.actor.mailbox.DurableMailboxSpec
object MyMailboxSpec {
val config = """
MyStorage-dispatcher {
mailbox-type = akka.docs.actor.mailbox.MyMailboxType
mailbox-type = docs.actor.mailbox.MyMailboxType
}
"""
}

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.actor.mailbox
package docs.actor.mailbox
import org.scalatest.junit.JUnitSuite

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.actor.mailbox;
package docs.actor.mailbox;
//#imports
import akka.actor.Props;

View file

@ -443,7 +443,7 @@ An Actor has to implement the ``receive`` method to receive messages:
.. code-block:: scala
protected def receive: PartialFunction[Any, Unit]
def receive: PartialFunction[Any, Unit]
Note: Akka has an alias to the ``PartialFunction[Any, Unit]`` type called
``Receive`` (``akka.actor.Actor.Receive``), so you can use this type instead for

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.actor
package docs.actor
//#imports1
import akka.actor.Actor
@ -326,14 +326,13 @@ class ActorDocSpec extends AkkaSpec(Map("akka.loglevel" -> "INFO")) {
//#gracefulStop
import akka.pattern.gracefulStop
import akka.dispatch.Await
import akka.actor.ActorTimeoutException
try {
val stopped: Future[Boolean] = gracefulStop(actorRef, 5 seconds)(system)
Await.result(stopped, 6 seconds)
// the actor has been stopped
} catch {
case e: ActorTimeoutException // the actor wasn't stopped within 5 seconds
case e: akka.pattern.AskTimeoutException // the actor wasn't stopped within 5 seconds
}
//#gracefulStop
}

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.actor
package docs.actor
//#test-code
import akka.testkit.AkkaSpec

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.actor
package docs.actor
//#all
//#imports

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.actor
package docs.actor
//#testkit
import akka.testkit.{ AkkaSpec, ImplicitSender, EventFilter }

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.actor
package docs.actor
//#imports1
import akka.actor.Actor

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.actor
package docs.actor
//#imports
import akka.dispatch.{ Promise, Future, Await }

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.actor
package docs.actor
import akka.actor._
import scala.collection.mutable.ListBuffer

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.agent
package docs.agent
import akka.agent.Agent
import akka.util.duration._

View file

@ -1,4 +1,4 @@
package akka.docs.camel
package docs.camel
object Consumers {
{

View file

@ -1,4 +1,4 @@
package akka.docs.camel
package docs.camel
object Introduction {
{

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.dispatcher
package docs.dispatcher
import org.scalatest.{ BeforeAndAfterAll, WordSpec }
import org.scalatest.matchers.MustMatchers
@ -91,13 +91,13 @@ object DispatcherDocSpec {
//#prio-dispatcher-config
prio-dispatcher {
mailbox-type = "akka.docs.dispatcher.DispatcherDocSpec$MyPrioMailbox"
mailbox-type = "docs.dispatcher.DispatcherDocSpec$MyPrioMailbox"
}
//#prio-dispatcher-config
//#prio-dispatcher-config-java
prio-dispatcher-java {
mailbox-type = "akka.docs.dispatcher.DispatcherDocTestBase$MyPrioMailbox"
mailbox-type = "docs.dispatcher.DispatcherDocTestBase$MyPrioMailbox"
//Other dispatcher configuration goes here
}
//#prio-dispatcher-config-java

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.event
package docs.event
import akka.testkit.AkkaSpec
import akka.actor.Actor

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.extension
package docs.extension
import java.util.concurrent.atomic.AtomicLong
import akka.actor.Actor
@ -45,7 +45,7 @@ object ExtensionDocSpec {
val config = """
//#config
akka {
extensions = ["akka.docs.extension.CountExtension$"]
extensions = ["docs.extension.CountExtension$"]
}
//#config
"""

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.extension
package docs.extension
//#imports
import akka.actor.Extension

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.future
package docs.future
import org.scalatest.{ BeforeAndAfterAll, WordSpec }
import org.scalatest.matchers.MustMatchers

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.io
package docs.io
//#imports
import akka.actor._

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.remoting
package docs.remoting
import akka.actor.{ ExtendedActorSystem, ActorSystem, Actor, ActorRef }
import akka.testkit.{ AkkaSpec, ImplicitSender }

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.routing
package docs.routing
import RouterDocSpec.MyActor
import akka.actor.{ Props, Actor }

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.routing
package docs.routing
import akka.routing.{ ScatterGatherFirstCompletedRouter, BroadcastRouter, RandomRouter, RoundRobinRouter }
import annotation.tailrec

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.routing
package docs.routing
import akka.actor.{ Actor, Props, ActorSystem }
import com.typesafe.config.ConfigFactory

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.routing
package docs.routing
import akka.routing.RoundRobinRouter
import akka.actor.{ ActorRef, Props, Actor, ActorSystem }
@ -29,7 +29,7 @@ object RoutingProgrammaticallyExample extends App {
val actor2 = system.actorOf(Props[ExampleActor1])
val actor3 = system.actorOf(Props[ExampleActor1])
val routees = Vector[ActorRef](actor1, actor2, actor3)
val router2 = system.actorOf(Props[ExampleActor1].withRouter(
val router2 = system.actorOf(Props().withRouter(
RoundRobinRouter(routees = routees)))
//#programmaticRoutingRoutees
1 to 6 foreach { i router2 ! Message1(i) }

View file

@ -1,17 +1,21 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.serialization
package docs.serialization
import org.scalatest.matchers.MustMatchers
import akka.testkit._
import akka.actor.{ ActorRef, ActorSystem }
//#imports
import akka.actor.{ ActorRef, ActorSystem }
import akka.serialization._
import com.typesafe.config.ConfigFactory
//#imports
import akka.actor.ExtensionKey
import akka.actor.ExtendedActorSystem
import akka.actor.Extension
import akka.actor.Address
import akka.remote.RemoteActorRefProvider
//#my-own-serializer
class MyOwnSerializer extends Serializer {
@ -87,7 +91,7 @@ class SerializationDocSpec extends AkkaSpec {
serializers {
java = "akka.serialization.JavaSerializer"
proto = "akka.serialization.ProtobufSerializer"
myown = "akka.docs.serialization.MyOwnSerializer"
myown = "docs.serialization.MyOwnSerializer"
}
}
}
@ -105,14 +109,14 @@ class SerializationDocSpec extends AkkaSpec {
serializers {
java = "akka.serialization.JavaSerializer"
proto = "akka.serialization.ProtobufSerializer"
myown = "akka.docs.serialization.MyOwnSerializer"
myown = "docs.serialization.MyOwnSerializer"
}
serialization-bindings {
"java.lang.String" = java
"akka.docs.serialization.Customer" = java
"docs.serialization.Customer" = java
"com.google.protobuf.Message" = proto
"akka.docs.serialization.MyOwnSerializable" = myown
"docs.serialization.MyOwnSerializable" = myown
"java.lang.Boolean" = myown
}
}
@ -176,5 +180,38 @@ class SerializationDocSpec extends AkkaSpec {
val deserializedActorRef = theActorSystem actorFor identifier
// Then just use the ActorRef
//#actorref-serializer
//#external-address
object ExternalAddress extends ExtensionKey[ExternalAddressExt]
class ExternalAddressExt(system: ExtendedActorSystem) extends Extension {
def addressFor(remoteAddr: Address): Address =
system.provider.getExternalAddressFor(remoteAddr) getOrElse
(throw new UnsupportedOperationException("cannot send to " + remoteAddr))
}
def serializeTo(ref: ActorRef, remote: Address): String =
ref.path.toStringWithAddress(ExternalAddress(theActorSystem).addressFor(remote))
//#external-address
}
"demonstrate how to do default Akka serialization of ActorRef" in {
val theActorSystem: ActorSystem = system
//#external-address-default
object ExternalAddress extends ExtensionKey[ExternalAddressExt]
class ExternalAddressExt(system: ExtendedActorSystem) extends Extension {
def addressForAkka: Address = system.provider match {
case r: RemoteActorRefProvider r.transport.address
case _
throw new UnsupportedOperationException(
"this method requires the RemoteActorRefProvider to be configured")
}
}
def serializeAkkaDefault(ref: ActorRef): String =
ref.path.toStringWithAddress(ExternalAddress(theActorSystem).addressForAkka)
//#external-address-default
}
}

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.testkit
package docs.testkit
//#plain-spec
import akka.actor.ActorSystem

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.testkit
package docs.testkit
//#testkit-usage
import scala.util.Random

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.testkit
package docs.testkit
//#imports-test-probe
import akka.testkit.TestProbe

View file

@ -2,7 +2,7 @@
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.transactor
package docs.transactor
import akka.actor._
import akka.transactor._

View file

@ -1,7 +1,7 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.docs.zeromq
package docs.zeromq
import akka.actor.Actor
import akka.actor.Props

View file

@ -71,7 +71,7 @@ There are 4 different types of message dispatchers:
* BalancingDispatcher
- This is an executor based event driven dispatcher that will try to redistribute work from busy actors to idle actors.
- This is an executor based event driven dispatcher that will try to redistribute work from busy actors to idle actors.
- It is assumed that all actors using the same instance of this dispatcher can process all messages that have been sent to one of the actors; i.e. the actors belong to a pool of actors, and to the client there is no guarantee about which actor instance actually processes a given message.
@ -86,9 +86,11 @@ There are 4 different types of message dispatchers:
"thread-pool-executor" or the FQCN of
an ``akka.dispatcher.ExecutorServiceConfigurator``
- Note that you can **not** use a ``BalancingDispatcher`` together with any kind of ``Router``, trying to do so will make your actor fail verification.
* CallingThreadDispatcher
- This dispatcher runs invocations on the current thread only. This dispatcher does not create any new threads,
- This dispatcher runs invocations on the current thread only. This dispatcher does not create any new threads,
but it can be used from different threads concurrently for the same actor. See :ref:`TestCallingThreadDispatcherRef`
for details and restrictions.
@ -112,8 +114,8 @@ And then using it:
.. includecode:: ../scala/code/akka/docs/dispatcher/DispatcherDocSpec.scala#defining-pinned-dispatcher
Note that ``thread-pool-executor`` configuration as per the above ``my-thread-pool-dispatcher`` exmaple is
NOT applicable. This is because every actor will have its own thread pool when using ``PinnedDispatcher``,
Note that ``thread-pool-executor`` configuration as per the above ``my-thread-pool-dispatcher`` exmaple is
NOT applicable. This is because every actor will have its own thread pool when using ``PinnedDispatcher``,
and that pool will have only one thread.
Mailboxes

View file

@ -4,6 +4,10 @@
Microkernel (Scala)
===================
The purpose of the Akka Microkernel is to offer a bundling mechanism so that you can distribute
an Akka application as a single payload, without the need to run in a Java Application Server or manually
having to create a launcher script.
The Akka Microkernel is included in the Akka download found at `downloads`_.
.. _downloads: http://akka.io/downloads

View file

@ -301,3 +301,64 @@ which holds the transport used (RemoteTransport) and optionally the address that
To intercept when an inbound remote client has been closed you listen to ``RemoteServerClientClosed``
which holds the transport used (RemoteTransport) and optionally the address of the remote client that was closed (Option[Address]).
Remote Security
^^^^^^^^^^^^^^^
Akka provides a couple of ways to enhance security between remote nodes (client/server):
* Untrusted Mode
* Security Cookie Handshake
Untrusted Mode
--------------
You can enable untrusted mode for preventing system messages to be send by clients, e.g. messages like.
This will prevent the client to send these messages to the server:
* ``Create``
* ``Recreate``
* ``Suspend``
* ``Resume``
* ``Terminate``
* ``Supervise``
* ``ChildTerminated``
* ``Link``
* ``Unlink``
Here is how to turn it on in the config::
akka {
actor {
remote {
untrusted-mode = on
}
}
}
Secure Cookie Handshake
-----------------------
Akka remoting also allows you to specify a secure cookie that will be exchanged and ensured to be identical
in the connection handshake between the client and the server. If they are not identical then the client
will be refused to connect to the server.
The secure cookie can be any kind of string. But the recommended approach is to generate a cryptographically
secure cookie using this script ``$AKKA_HOME/scripts/generate_config_with_secure_cookie.sh`` or from code
using the ``akka.util.Crypt.generateSecureCookie()`` utility method.
You have to ensure that both the connecting client and the server have the same secure cookie as well
as the ``require-cookie`` option turned on.
Here is an example config::
akka {
actor {
remote {
netty {
secure-cookie = "090A030E0F0A05010900000A0C0E0C0B03050D05"
require-cookie = on
}
}
}
}

View file

@ -33,6 +33,11 @@ You can also give the router already created routees as in:
.. includecode:: code/akka/docs/routing/RouterViaProgramExample.scala#programmaticRoutingRoutees
It should be noted that no actor factory or class needs to be provided in this
case, as the ``Router`` will not create any children on its own (which is not
true anymore when using a resizer). The routees can also be specified by giving
their path strings.
When you create a router programmatically you define the number of routees *or* you pass already created routees to it.
If you send both parameters to the router *only* the latter will be used, i.e. ``nrOfInstances`` is disregarded.
@ -48,7 +53,7 @@ Once you have the router actor it is just to send messages to it as you would to
router ! MyMsg
The router will apply its behavior to the message it receives and forward it to the routees.
The router will forward the message to its routees according to its routing policy.
Remotely Deploying Routees
**************************
@ -375,7 +380,9 @@ The dispatcher for created children of the router will be taken from
makes sense to configure the :class:`BalancingDispatcher` if the precise
routing is not so important (i.e. no consistent hashing or round-robin is
required); this enables newly created routees to pick up work immediately by
stealing it from their siblings.
stealing it from their siblings. Note that you can **not** use a ``BalancingDispatcher``
together with any kind of ``Router``, trying to do so will make your actor fail verification.
.. note::

View file

@ -84,7 +84,7 @@ Customization
=============
So, lets say that you want to create your own ``Serializer``,
you saw the ``akka.docs.serialization.MyOwnSerializer`` in the config example above?
you saw the ``docs.serialization.MyOwnSerializer`` in the config example above?
Creating new Serializers
------------------------
@ -107,6 +107,47 @@ you might want to know how to serialize and deserialize them properly, here's th
.. includecode:: code/akka/docs/serialization/SerializationDocSpec.scala
:include: imports,actorref-serializer
.. note::
``ActorPath.toStringWithAddress`` only differs from ``toString`` if the
address does not already have ``host`` and ``port`` components, i.e. it only
inserts address information for local addresses.
This assumes that serialization happens in the context of sending a message
through the remote transport. There are other uses of serialization, though,
e.g. storing actor references outside of an actor application (database,
durable mailbox, etc.). In this case, it is important to keep in mind that the
address part of an actors path determines how that actor is communicated with.
Storing a local actor path might be the right choice if the retrieval happens
in the same logical context, but it is not enough when deserializing it on a
different network host: for that it would need to include the systems remote
transport address. An actor system is not limited to having just one remote
transport per se, which makes this question a bit more interesting.
In the general case, the local address to be used depends on the type of remote
address which shall be the recipient of the serialized information. Use
:meth:`ActorRefProvider.getExternalAddressFor(remoteAddr)` to query the system
for the appropriate address to use when sending to ``remoteAddr``:
.. includecode:: code/akka/docs/serialization/SerializationDocSpec.scala
:include: external-address
This requires that you know at least which type of address will be supported by
the system which will deserialize the resulting actor reference; if you have no
concrete address handy you can create a dummy one for the right protocol using
``Address(protocol, "", "", 0)`` (assuming that the actual transport used is as
lenient as Akkas RemoteActorRefProvider).
There is a possible simplification available if you are just using the default
:class:`NettyRemoteTransport` with the :meth:`RemoteActorRefProvider`, which is
enabled by the fact that this combination has just a single remote address:
.. includecode:: code/akka/docs/serialization/SerializationDocSpec.scala
:include: external-address-default
This solution has to be adapted once other providers are used (like the planned
extensions for clustering).
Deep serialization of Actors
----------------------------
@ -135,3 +176,11 @@ representation into a real reference. :class:`DynamicVariable` is a
thread-local variable, so be sure to have it set while deserializing anything
which might contain actor references.
External Akka Serializers
=========================
`Akka-protostuff by Roman Levenstein<https://github.com/romix/akka-protostuff-serialization>`_
`Akka-quickser by Roman Levenstein<https://github.com/romix/akka-quickser-serialization>`_