Agents
简介
Akka 的代理受到了「Clojure 中的代理」的启发。
- 废弃警告:代理已被弃用,并计划在下一个主要版本中删除。我们发现,他们的抽象性(他们不在网络上工作)使他们不如纯粹的 Actor,而且面对 Akka Typed 很快被包括在内的情况,我们认为维持现有的代理没有什么价值。
代理提供单个位置的异步更改。代理在其生命周期内绑定到单个存储位置(storage location
),并且只允许该位置的突变(到一个新的状态)作为操作的结果。更新操作是异步应用于代理状态的函数,其返回值将成为代理的新状态。代理的状态应该是不可变的。
虽然对代理的更新是异步的,但是代理的状态始终可以立即供任何线程(使用get
)读取,而不需要任何消息。
代理是反应性的。所有代理的更新操作在ExecutionContext
中的线程之间交错。在任何时间点,每个代理最多执行一个send
操作。从另一个线程发送到代理的操作将按发送顺序发生,可能与从其他线程发送到同一代理的操作交错出现。
- 注释:代理是创建它们的节点的本地代理。这意味着你通常不应将它们包括在可能传递给远程 Actor 的消息中,或者作为远程 Actor 的构造函数参数;这些远程 Actor 将无法读取或更新代理。
import scala.concurrent.ExecutionContext;
import akka.agent.Agent;
Agent<Integer> agent = Agent.create(5, ec);
读取代理的值
通过使用get()
调用代理,可以引用代理(可以获取代理的值),如下所示:
读取代理的当前值不涉及任何消息传递,并且会立即发生。因此,虽然对代理的更新是异步的,但是读取代理的状态是同步的。
你还可以获得代理值的Future
,该值将在当前入队的更新完成后完成:
import scala.concurrent.Future;
Future<Integer> future = agent.future();
通过「Futures」可以了解有关Futures
更多的信息。
你也可以调度一个函数来更新内部状态,但它是在自己的线程上进行的。这不使用反应式线程池,可以用于长时间运行或阻塞操作。你可以使用方法来实现这一点。使用sendOff
或send
的调度仍将按顺序执行。
import akka.dispatch.Mapper;
agent.sendOff(longRunningOrBlockingFunction, theExecutionContextToExecuteItIn);
所有send
方法都有一个相应的alter
方法,它返回一个Future
。有关Futures
的更多信息,请参阅「」。
配置
代理模块有几个配置属性,具体请参阅「」。
参与封闭 STM 事务的代理是版本中不推荐使用的功能。
英文原文链接:Agents.