[elixir! #0012] 漫话源码之Agent

news/2024/7/24 2:01:49

我们知道 Elixir 有一个从 Erlang 那里继承来的重要特性 —— immutable, 所以我们不能像 OO语言那样简单地用变量存储临时数据. 因此, Agent 出现了.

Agent 是关于 state 的简单抽象. state 可以解释为数据的某个状态. 在 Elixir 里经常需要在不同进程之间, 或者是同一个进程在不同的时间点, 分享或存储 state.

Agent 是一个基础的服务器实现, 它提供了简单的 API, 帮助我们对 state 进行获取与更新.

所有传送给 agent 的函数都会在 agent 里执行. 所以要避免在 agent 中进行昂贵的操作.

对比这两个例子:

# Compute in the agent/server
def get_something(agent) doAgent.get(agent, fn state -> do_something_expensive(state) end)
end# Compute in the agent/client
def get_something(agent) doAgent.get(agent, &(&1)) |> do_something_expensive()
end

第一个例子阻塞了 agent, 第二个例子将所有的 state 复制到客户端执行. 选择哪种方式取决于数据的大小, 是否大到需要在服务器执行, 或是小到可以传送到客户端.

agent 提供了两种 API, 一种是匿名函数, 另一种是确定的模块函数和参数. 使用分布式 agent 的时候最好选择后者.

agent 可以热更新代码, 只需要简单地传送一个模块,函数和参数的元组到更新命令里. 例如:

{:update, :sample, {:advanced, {Enum, :into, [%{}]}}}

agent 的 state 会被当做第一个参数添加到参数列表里.

Agent 模块里的主要函数

@spec start_link((() -> term), GenServer.options) :: on_start
@spec start_link(module, atom, [any], GenServer.options) :: on_start
启动一个包含了给定的函数, 链接到当前进程的 agent.

@spec start((() -> term), GenServer.options) :: on_start
@spec start(module, atom, [any], GenServer.options) :: on_start
启动一个没有链接的 agent. (在监督树之外)

@spec get(agent, (state -> a), timeout) :: a when a: var
@spec get(agent, module, atom, [term], timeout) :: any
通过给定的函数获取 agent 的值.

@spec get_and_update(agent, (state -> {a, state}), timeout) :: a when a: var
@spec get_and_update(agent, module, atom, [term], timeout) :: any
获取并更新 agent state.

@spec update(agent, (state -> state), timeout) :: :ok
@spec update(agent, module, atom, [term], timeout) :: :ok
更新 agent state.

@spec cast(agent, (state -> state)) :: :ok
@spec cast(agent, module, atom, [term]) :: :ok
在 agent state 中执行一个 cast 操作.

@spec stop(agent, reason :: term, timeout) :: :ok
以给定的原因关闭 agent.


https://dhexx.cn/news/show-1298421.html

相关文章

迭代流程_什么时候应该从迭代过渡到流程?

迭代流程我正在写程序管理书的一部分,讨论如何保持所有小东西以保持动力。 有时,为了保持工作量小,团队从迭代过渡到流程。 在某些情况下,您可能会考虑从迭代过渡到流程: 产品负责人出于商业原因希望在迭代中更改功能…

《深入BREW开发》——第六章 使用Applet和模块

第六章 使用Applet和模块 在BREW SDK中,每一个应用程序模块做为一个独立的Windows DLL文件开发。每一个模块中可以包含一个或多个Applet,并且必须有一个与此应用程序模块对应的MIF文件。通过BREW MIF Editor(MIF文件编辑器)…

DATETIME FORMATE(时间格式)

来源于Oracle官方文档,为了工作中方便使用,这里截取下来供参考:http://docs.oracle.com/cd/E11882_01/server.112/e41084/sql_elements004.htm#i34924Table 3-15 Datetime Format ElementsElementTO_* datetime functions?Description- / , …

noi 1996 登山

题目链接: http://noi.openjudge.cn/ch0206/1996/ LIS,LDS 正着做最长递增子序列,反着做最长递减子序列。 http://paste.ubuntu.com/23402475/转载于:https://www.cnblogs.com/TreeDream/p/6023758.html

Android入门(十八)服务

原文链接:http://www.orlion.ga/674/ 一、定义一个服务 创建一个项目ServiceDemo,然后在这个项目中新增一个名为 MyService的类,并让它继承自 Service,完成后的代码如下所示: public class MyService extends Service {Overridepu…

微信小程序选择题制作_制作较小故事的三种选择

微信小程序选择题制作几周前我在以色列教研班时,人们遇到的最大问题之一就是大故事。 为什么这是一个问题? 如果您的故事很大,则无法显示进度,更重要的是,您无法进行更改。 对我来说,敏捷的重点是透明度-嘿…

《深入BREW开发》——第五章 BREW简介

第五章 BREW简介 在移动通讯领域,不可变化的应用程序抑制了消费者的使用兴趣,亟需一种可以实现类似Windows的图形化系统,在这个系统上,可以容易的开发应用程序,同时支持应用程序的安装和管理等功能。当然&#x…

软件安装失败,导致ubuntu软件中心软件消失

感谢百度上各位IT界朋友的帮助,由于某个软件安装失败,导致ubuntu软件中心软件消失的解决办法: 找百度,有人说, 使用命令:sudo apt-get install software-center输入命令后,提示:software-center…

另类的ip地址伪装折腾记

收到这样一个需求:在现有结构不变的情况下,让被访问方看起来是很多物理地址在同时请求。为了便于大家理解,我画个图来描述,就明白了。新的业务规定是这样,见下图这样一来,就没有中间那个“业务处理服务器”…

scrum_Scrum适​​合您的产品吗?

scrumScrum何时最有帮助? 当您的产品是新产品或年轻产品时,以及延长产品生命周期时,像Scrum这样的过程非常适合您的产品,如下图所示。 这意味着并非每种产品都会从Scrum中受益:成熟或下降的产品不会从Scrum中受益-至少…