您的位置:首页 > 其它

部分akka文档翻译

2017-03-15 00:00 267 查看
摘要: 。。渣翻

Actor in Java are implemented by extending the UntypedActor class and implementing the onReceive method. This method takes the message as a parameter.

Actor 在java 中的实现是通过集成UntypedActor类和实现onReceive方法,这个方法使用message作为参数

import akka.actor.UntypedActor;

2.import akka.event.Logging;

3.import akka.event.LoggingAdapter;

4.

5.public class MyUntypedActor extends UntypedActor {

6. LoggingAdapter log = Logging.getLogger(getContext().system(), this);

7.

8. public void onReceive(Object message) throws Exception {

9. if (message instanceof String)

10. log.info("Received String message: {}", message);

11. else

12. unhandled(message);

13. }

14.}

Props

Props is a configuration class to specify options for the creation of actors. Here are some examples on how to create a Props instance.

props 是一个指定创建Actor的配置类。

Props props1 = new Props();

Props props2 = new Props(MyUntypedActor.class);

Props props3 = new Props(new UntypedActorFactory() {

public UntypedActor create() {

return new MyUntypedActor();

}

});

Props props4 = props1.withCreator(new UntypedActorFactory() {

public UntypedActor create() {

return new MyUntypedActor();

}

});

Creating Actors with Props

Actors are created by passing in a Props instance into the actorOf factory method.

Actors的创建是通过Props实例进入actorOf工厂方法。

ActorRef myActor = system.actorOf(new Props(MyUntypedActor.class).withDispatcher("mydispatcher"), "myactor");

Creating Actors with default constructor

import akka.actor.ActorRef;

import akka.actor.ActorSystem;

import akka.actor.Props;

ActorSystem system = ActorSystem.create("MySystem");

ActorRef myActor = system.actorOf(new Props(MyUntypedActor.class), "myactor");

The call to actorOf returns an instance of ActorRef. This is a handle to the UntypedActor instance which you can use to interact with the UntypedActor. The ActorRef is immutable and has a one to one relationship with the Actor it represents. The ActorRef is also serializable and network-aware. This means that you can serialize it, send it over the wire and use it on a remote host and it will still be representing the same Actor on the original node, across the network.

调用actorOf 并返回ActorRef的实例。这是一个处理UntypedActor实例,您可以使用与UntypedActor交互。ActorRef 是不可变得,并且与所表示的Actor有一对一的关系。ActorRef也是serializable 和network-aware的。你可以在网络上序列化并发送他,在远程主机端使用一个相同的Actor。

In the above example the actor was created from the system. It is also possible to create actors from other actors with the actor context. The difference is how the supervisor hierarchy is arranged. When using the context the current actor will be supervisor of the created child actor. When using the system it will be a top level actor, that is supervised by the system (internal guardian actor).

在上面的例子,actor被system创建,Actor还可能被别的actor通过actor context创建。不同的是管理层次结构是如何安排的。当使用context创建时,当前Actor监督被创建的child Actor。当使用system创建时,被创建的Actor将会是顶级Actor,被系统监督。

public class FirstUntypedActor extends UntypedActor { ActorRef myActor = getContext().actorOf(new Props(MyActor.class), "myactor");

The name parameter is optional, but you should preferably name your actors, since that is used in log messages and for identifying actors. The name must not be empty or start with $. If the given name is already in use by another child to the same parent actor an InvalidActorNameException is thrown.

名称参数是可选择的,但应该给你的acotr起一个好名字,因为它被用来记录log和确定actor。名称不能为空,不能$开头。如果名字已经被使用,将会抛出InvalidActorNameException。

Actors are automatically started asynchronously when created. When you create the UntypedActor then it will automatically call the preStart callback method on the UntypedActor class. This is an excellent place to add initialization code for the actor.

Actor 被创建时将会异步自动开始。当你创建UntypedActor 类然后将自动调用preStart回调函数。可以Actor中添加初始化代码。

Creating Actors with non-default constructor

If your UntypedActor has a constructor that takes parameters then you can’t create it using ‘actorOf(new Props(clazz))’. Then you can instead pass in ‘new Props(new UntypedActorFactory() {..})’ in which you can create the Actor in any way you like.

如果你的UntypedActor 有一个含参构造函数,那么你不能使用‘actorOf(new Props(clazz))’创建。你可以用‘new Props(new UntypedActorFactory() {..})’代替

// allows passing in arguments to the MyActor constructor

ActorRef myActor = system.actorOf(new Props(new UntypedActorFactory() {

public UntypedActor create() {

return new MyActor("...");

}

}), "myactor");

This way of creating the Actor is also great for integrating with Dependency Injection (DI) frameworks like Guice or Spring.

这种方法也可以和DI结合

class DependencyInjector implements IndirectActorProducer {

final Object applicationContext;

final String beanName;

public DependencyInjector(Object applicationContext, String beanName) {

this.applicationContext = applicationContext;

this.beanName = beanName;

}

@Override

public Class<? extends Actor> actorClass() {

return MyActor.class;

}

@Override

public MyActor produce() {

MyActor result;

// obtain fresh Actor instance from DI framework ...

return result;

}

}

final ActorRef myActor = getContext().actorOf(

Props.create(DependencyInjector.class, applicationContext, "MyActor"),

"myactor3");

The Inbox

When writing code outside of actors which shall communicate with actors, the ask pattern can be a solution (see below), but there are two things it cannot do: receiving multiple replies (e.g. by subscribing an ActorRef to a notification service) and watching other actors’ lifecycle. For these purposes there is the Inbox class:

当在写actor外的沟通与actor时,解决方案是ask模式,但是有两个事不能做。接受多个回复(

比如订阅一个actorref 的通知服务)和观察其他actor的lifecycle。

final Inbox inbox = Inbox.create(system);

inbox.send(target, "hello");

try {

assert inbox.receive(Duration.create(1, TimeUnit.SECONDS)).equals("world");

} catch (java.util.concurrent.TimeoutException e) {

// timeout

}

The send method wraps a normal tell and supplies the internal actor’s reference as the sender. This allows the reply to be received on the last line. Watching an actor is quite simple as well:

send 方法包装了一个普通的tell并且支持内部的actor的引用作为一个sender。

final Inbox inbox = Inbox.create(system);

inbox.watch(target);

target.tell(PoisonPill.getInstance(), ActorRef.noSender());

try {

assert inbox.receive(Duration.create(1, TimeUnit.SECONDS)) instanceof Terminated;

} catch (java.util.concurrent.TimeoutException e) {

// timeout

}

UntypedActor API

The UntypedActor class defines only one abstract method, the above mentioned onReceive(Object message), which implements the behavior of the actor.

UntypedActor 类只定义一个抽象方法onReceive(Object message)用来实现actorde行为。

If the current actor behavior does not match a received message, unhandled is called, which by default publishes a new akka.actor.UnhandledMessage(message, sender, recipient) on the actor system’s event stream.

如果当前actor行为并不匹配接受的message,unhandled将被调用,他默认发送一个new akka.actor.UnhandledMessage(message, sender, recipient) 在actor system的事件流中。

In addition, it offers:

getSelf() reference to the ActorRef of the actor 自身引用

getSender() reference sender Actor of the last received message, typically used as described in Reply to messages 最近的发送者

supervisorStrategy() user overridable definition the strategy to use for supervising child actors 子actors的监控策略

getContext() exposes contextual information for the actor and the current message, such as:

factory methods to create child actors (actorOf)

system that the actor belongs to

parent supervisor

supervised children

lifecycle monitoring

hotswap behavior stack as described in HotSwap

监督和监控

http://blog.csdn.net/wsscy2004/article/details/38233197

The remaining visible methods are user-overridable life-cycle hooks which are described in the following

public void preStart() {

}

public void preRestart(Throwable reason, scala.Option<Object> message) {

for (ActorRef each : getContext().getChildren()) {

getContext().unwatch(each);

getContext().stop(each);

}

postStop();

}

public void postRestart(Throwable reason) {

preStart();

}

public void postStop() {

}

Lifecycle Monitoring aka DeathWatch

In order to be notified when another actor terminates (i.e. stops permanently, not temporary failure and restart), an actor may register itself for reception of the Terminated message dispatched by the other actor upon termination (see Stopping Actors). This service is provided by the DeathWatch component of the actor system.

为了另一个actor终止时被提醒(永久结束,非暂时失败或重启)、actor可以注册接收别的actor终止发送的消息。这项服务在actor system中的deathwatch组件提供。

public static class WatchActor extends UntypedActor {

final ActorRef child = this.getContext().actorOf(Props.empty(), "child");

{

this.getContext().watch(child); // <-- this is the only call needed for registration

}

ActorRef lastSender = getContext().system().deadLetters();

@Override

public void onReceive(Object message) {

if (message.equals("kill")) {

getContext().stop(child);

lastSender = getSender();

} else if (message instanceof Terminated) {

final Terminated t = (Terminated) message;

if (t.getActor() == child) {

lastSender.tell("finished");

}

} else {

unhandled(message);

}

}

}

Actor Lifecycle

A path in an actor system represents a "place" which might be occupied by a living actor. Initially (apart from system initialized actors) a path is empty. When actorOf() is called it assigns an incarnation of the actor described by the passed Props to the given path. An actor incarnation is identified by the path and a UID. A restart only swaps the Actor instance defined by the Props but the incarnation and hence the UID remains the same.

路径在actor system中代表着一个可能出现一个living actor 的地方。最初路径是空。当actorOf被调用,分配一个incarnation of the actor所描述的props传递给给定的路径。一个actor被确定通过路径和UID。重启仅交换iporps的Actor的实例但是incarnation和UID在原先位置

The lifecycle of an incarnation ends when the actor is stopped. At that point the appropriate lifecycle events are called and watching actors are notified of the termination. After the incarnation is stopped, the path can be reused again by creating an actor with actorOf(). In this case the name of the new incarnation will be the same as the previous one but the UIDs will differ. An actor can be stopped by the actor itself, another actor or the ActorSystem (see Stopping actors).

Note

It is important to note that Actors do not stop automatically when no longer referenced, every Actor that is created must also explicitly be destroyed. The only simplification is that stopping a parent Actor will also recursively stop all the child Actors that this parent has created.

An ActorRef always represents an incarnation (path and UID) not just a given path. Therefore if an actor is stopped and a new one with the same name is created an ActorRef of the old incarnation will not point to the new one.

Actor不会在不再因引用时自动停止(无法自动GC?),每个Actor创建必须明确被摧毁,唯一简化的是停止父Actor将递归stop所有的子Actor。

ActorSelection on the other hand points to the path (or multiple paths if wildcards are used) and is completely oblivious to which incarnation is currently occupying it. ActorSelection cannot be watched for this reason. It is possible to resolve the current incarnation's ActorRef living under the path by sending an Identify message to the ActorSelection which will be replied to with an ActorIdentity containing the correct reference (see Identifying Actors via Actor Selection). This can also be done with the resolveOne method of the ActorSelection, which returns a Future of the matching ActorRef.

Start Hook

Right after starting the actor, its preStart method is invoked.

@Override

public void preStart() {

child = getContext().actorOf(Props.empty());

}

Restart Hooks

All actors are supervised, i.e. linked to another actor with a fault handling strategy. Actors may be restarted in case an exception is thrown while processing a message (see Supervision and Monitoring). This restart involves the hooks mentioned above:

所有Actor都是被监控的 比如 连接到另一个Actor使用故障处理策略 (?)。Actor可能重启以防在当处理信息时异常被抛出。

The old actor is informed by calling preRestart with the exception which caused the restart and the message which triggered that exception; the latter may be None if the restart was not caused by processing a message, e.g. when a supervisor does not trap the exception and is restarted in turn by its supervisor, or if an actor is restarted due to a sibling’s failure. If the message is available, then that message’s sender is also accessible in the usual way (i.e. by calling getSender()).

老的Actor被

This method is the best place for cleaning up, preparing hand-over to the fresh actor instance, etc. By default it stops all children and calls postStop.

这个方法是最好的清理方法,准备移交新的Actor实例,默认情况下他停止所有子Actor并且调用

postStop。

The initial factory from the actorOf call is used to produce the fresh instance.

最初调用actorOf 工厂方法被用来产生新的实例

The new actor’s postRestart method is invoked with the exception which caused the restart. By default the preStart is called, just as in the normal start-up case.

An actor restart replaces only the actual actor object; the contents of the mailbox is unaffected by the restart, so processing of messages will resume after the postRestart hook returns. The message that triggered the exception will not be received again. Any message sent to an actor while it is being restarted will be queued to its mailbox as usual.

一个Actor 重启只替换存在的actor对象,mailbox 的内容不受重启影响,所以通讯的过程将会在postRestart 钩子返回后恢复。触发异常的消息将不会再次接收。任何信息发送到一个重启的Actor时通常将会排到mailbox队列里。

Warning

Be aware that the ordering of failure notifications relative to user messages is not deterministic. In particular, a parent might restart its child before it has processed the last messages sent by the child before the failure. See Discussion: Message Ordering for details.

请注意,相对于用户故障通知消息的顺序是不确定的。特别的是,父parent可能会重启他的子Actor在他处理最后的消息发送给child在失败之前??????。

Stop Hook

After stopping an actor, its postStop hook is called, which may be used e.g. for deregistering this actor from other services. This hook is guaranteed to run after message queuing has been disabled for this actor, i.e. messages sent to a stopped actor will be redirected to the deadLetters of the ActorSystem.

Identifying Actors via Actor Selection

As described in Actor References, Paths and Addresses, each actor has a unique logical path, which is obtained by following the chain of actors from child to parent until reaching the root of the actor system, and it has a physical path, which may differ if the supervision chain includes any remote supervisors. These paths are used by the system to look up actors, e.g. when a remote message is received and the recipient is searched, but they are also useful more directly: actors may look up other actors by specifying absolute or relative paths—logical or physical—and receive back an ActorSelection with the result:

Actor References, Paths and Addresses描述中每一个actor都有一个独一无二的逻辑路径,拥有的Actor链路 从子到父直到actor system 的根节点,并且拥有物理路径,但可能不相同如果监督链包含一些远程监督者。这些路径被系统用来监管actor。比如,当接收远程信息,接收者搜索,但他们更有用直接:actors 可能观察别的actor通过特殊的绝对或相对路径,逻辑或物理路径并且接收ActorSelection 发回的结果:

// will look up this absolute path

getContext().actorSelection("/user/serviceA/actor");

// will look up sibling beneath same supervisor

getContext().actorSelection("../joe");

Note

It is always preferable to communicate with other Actors using their ActorRef instead of relying upon ActorSelection. Exceptions are

sending messages using the At-Least-Once Delivery facility

initiating first contact with a remote system

In all other cases ActorRefs can be provided during Actor creation or initialization, passing them from parent to child or introducing Actors by sending their ActorRefs to other Actors within messages.

The supplied path is parsed as a java.net.URI, which basically means that it is split on / into path elements. If the path starts with /, it is absolute and the look-up starts at the root guardian (which is the parent of "/user"); otherwise it starts at the current actor. If a path element equals .., the look-up will take a step “up” towards the supervisor of the currently traversed actor, otherwise it will step “down” to the named child. It should be noted that the .. in actor paths here always means the logical structure, i.e. the supervisor.

The path elements of an actor selection may contain wildcard patterns allowing for broadcasting of messages to that section:

// will look all children to serviceB with names starting with worker

getContext().actorSelection("/user/serviceB/worker*");

// will look up all siblings beneath same supervisor

getContext().actorSelection("../*");
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Akka