akka(tell,ask,send)

来源:互联网 发布:top域名续费 编辑:程序博客网 时间:2024/06/05 08:28

tell

异步发送一个消息并立即返回。

target.tell(message, getSelf());

在Actor外部,如果没有回复,第二个参数可以为null;

ask

异步发送一条消息并返回一个 Future代表一个可能的回应

forward转发消息

target.forward(result, getContext());

注意

使用ask会造成性能影响,因为当超时是,一些事情需要保持追踪。这需要一些东西来将一个Promise连接进入ActorRef,并且需要通过远程连接可到达的。所以总是使用tell更偏向性能,除非必须才用ask。

如果在角色外部需要一个回复,你可以使用ASK模式描

ask 模式既包含actor也包含future, 所以它是作为一种使用模式,而不是ActorRef的方法:
ask和future上的pipe模式一起使用是一个常用的组合,

final Timeout t = new Timeout(Duration.create(5, TimeUnit.SECONDS));final ArrayList<Future<Object>> futures = new ArrayList<Future<Object>>();futures.add(ask(actorA, "request", 1000)); futures.add(ask(actorB, "another request", t)); final Future<Iterable<Object>> aggregate = Futures.sequence(futures,    system.dispatcher());final Future<Result> transformed = aggregate.map(    new Mapper<Iterable<Object>, Result>() {      public Result apply(Iterable<Object> coll) {        final Iterator<Object> it = coll.iterator();        final String x = (String) it.next();        final String s = (String) it.next();        return new Result(x, s);      }    }, system.dispatcher());pipe(transformed, system.dispatcher()).to(actorC);

ask 产生 Future, 两个通过Futures.sequence和map方法组合成一个新的Future,然后用 pipe 在future上安装一个 onComplete-处理器来完成将收集到的 Result 发送到其它actor的动作。使用 ask 将会像tell 一样发送消息给接收方, 接收方必须通过getSender().tell(reply, getSelf()) 发送回应来为返回的 Future 填充数据。ask 操作包括创建一个内部actor来处理回应,必须为这个内部actor指定一个超时期限,过了超时期限内部actor将被销毁以防止内存泄露。

如果一个actor 没有完成future , 它会在超时时限到来时过期, 明确作为一个参数传给ask方法,以 AskTimeoutException来完成Future。

try {  String result = operation();  getSender().tell(result, getSelf());} catch (Exception e) {  getSender().tell(new akka.actor.Status.Failure(e), getSelf());  throw e;}

Future的onComplete, onResult, 或 onTimeout 方法可以用来注册一个回调,以便在Future完成时得到通知。从而提供一种避免阻塞的方法。

使用future回调时,在角色内部要避免使用关闭该角色的引用(不要在回调中调用该角色的方法或访问其可变状态)这会破坏角色的封装,会引用同步bug和race condition, 因为回调会与此角色一同被并发调度。 目前还没有一种编译时的方法能够探测到这种非法访问。

0 0