概述

elixir 本身是一种 immutable 的语言,默认情况下,进程间是不共享任何状态的,进程之间通过消息来交互。

而 Agent 则封装了一种进程间共享状态的方式,通过这种方式,不用显式的写 send/receieve 的代码,就能方便的在进程之间共享状态。

使用方法

不用 Agent 来管理状态

首先,看一个在不用 Agent 的情况下,如何获取进程状态的例子。

defmodule WithoutAgent do
def start do
Map.new()
end def get(map, key) do
if Map.has_key?(map, key) do
Map.get(map, key)
else
nil
end
end def put(map, key, val) do
Map.put(map, key, val)
end def delete(map, key) do
Map.delete(map, key)
end
end

测试 WithoutAgent 的使用:

iex> m = WithoutAgent.start
%{}
iex> WithoutAgent.get(m, "map-key")
nil iex> m = WithoutAgent.put(m, "map-key", "map-val")
%{"map-key" => "map-val"}
iex> WithoutAgent.get(m, "map-key")
"map-val" iex> m = WithoutAgent.delete(m, "map-key")
%{}
iex> m = WithoutAgent.get(m, "map-key")
nil

从上面的使用可以看出,为了使用 WithoutAgent 中的状态(一个 map),外部还必须要自己管理 WithoutAgent 的返回的状态 m,

通过 WithoutAgent 来改变状态时,每次都要将当前状态 m 作为一个参数传给 WithoutAgent。

只有一个进程使用 WithoutAgent 时,上述方式没有什么问题,当有多个进程使用 WithoutAgent,每个进程持有的状态 m 很难保持一致。

使用 Agent 来管理状态

elixir 中的 Agent 其实并不是 elixir 发明的新东西,而是封装了 erlang OTP 中现有的 ETS (Erlang Term Storage)

使用 Agent 来重新实现上面的例子:

defmodule WithAgent do
def start do
Agent.start_link(fn -> Map.new end, name: __MODULE__)
end def get(key) do
Agent.get(__MODULE__, fn map ->
if Map.has_key?(map, key) do
Map.get(map, key)
else
nil
end
end)
end def put(key, val) do
Agent.update(__MODULE__, &Map.put(&1, key, val))
end def delete(key) do
Agent.get_and_update(__MODULE__, fn map ->
if Map.has_key?(map, key) do
Map.pop(map, key)
else
nil
end
end)
end
end

测试 WithAgent 的使用:

iex> WithAgent.start
{:ok, #PID<0.108.0>}
iex> WithAgent.get("map-key")
nil iex> WithAgent.put("map-key", "map-val")
:ok
iex> WithAgent.get("map-key")
"map-val" iex> WithAgent.delete("map-key")
"map-val"
iex> WithAgent.get("map-key")
nil

从上面的使用中可以看出,使用了 Agent 之后,使用方完全不用自己管理 WithAgent 的状态,只要操作状态即可。

这样,多个进程同时使用 WithAgent 时,也不用管状态冲突的事情,状态如果有冲突也是在 WithAgent 中自己管理。

总结

总的来说,Agent 就是状态的简单的封装,方便进程间状态的共享。

此外,除了上面用的方法,Agent 中的所有方法参照:Agent

来源:http://blog.iotalabs.io/

elixir 高可用系列(一) Agent的更多相关文章

  1. elixir 高可用系列 - 目录

    1. elixir 高可用系列(一) Agent 2. elixir 高可用系列(二) GenServer 3. elixir 高可用系列(三) GenEvent 4. elixir 高可用系列(四) ...

  2. elixir 高可用系列(五) Supervisor

    概述 OTP 平台的容错性高,是因为它提供了机制来监控所有 processes 的状态,如果有进程出现异常, 不仅可以及时检测到错误,还可以对 processes 进行重启等操作. 有了 superv ...

  3. elixir 高可用系列(四) Task

    概述 之前学习的 Agent,GenSever以及GenEvent,都是用来管理状态或者处理消息的. 但是在很多时候,我们需要的是执行某个任务,这时如果使用 GenSever 或者 GenEvent, ...

  4. elixir 高可用系列(三) GenEvent

    概述 GenEvent 是事件处理的通用部分的抽象. 通过 GenEvent ,我们给已有的服务 动态 的添加 事件处理. GenEevent 和 GenServer 的区别 之前已经介绍了 GenS ...

  5. elixir 高可用系列(二) GenServer

    概述 如果我们需要管理多个进程,那么,就需要一个专门的 server 来集中监控和控制这些进程的状态,启停等. OTP 平台中的 GenServer 就是对这个 server 通用部分的抽象. 利用 ...

  6. (5.8)mysql高可用系列——MySQL中的GTID复制(实践篇)

    一.基于GTID的异步复制(一主一从)无数据/少数据搭建 二.基于GTID的无损半同步复制(一主一从)(mysql5.7)基于大数据量的初始化 正文: [0]概念 [0.5]GTID 复制(mysql ...

  7. (5.15)mysql高可用系列——MHA实践

    关键词:MHA,mysql mha [1]需求 采用mysql技术,实现MHA高可用主从环境,预计未来数据量几百G MHA概念参考:MYSQL高可用技术概述 [2]环境技术架构 [2.1]MHA简介 ...

  8. 高可用系列之Nginx

    1.1Keepalived高可用软件 Keepalived起初是专为LVS设计的,专门用来监控LVS集群系统中各个服务节点的状态,后来又加入了VRRP的功能,因此除了配合LVS服务外,也可以作为其他服 ...

  9. keepalived高可用系列~ keepalived+proxysql

    一 简介:介绍下高可用通用的方案 二 目的:一个中间件提供服务,故障后,另一个中间件提供服务 三 手段: 应用keepalived的vrrp_scripts服务 四 具体配置 global_defs ...

随机推荐

  1. delphi TEdit设为下横线,类似填表格

    delphi TEdit设为下横线,类似填表格效果,无需第三方控件就可以实现. 无须编写代码,只要设置一下控件属性 需要修改这些属性: BorderStyle改为bsNone BevelKind改为b ...

  2. python 格式化 json输出

    利用python格式化json 字符串输出. $ echo '{"json":"obj"}' | python -m json.tool 利用python -m ...

  3. 借助 MySQLTuner 优化 MySQL 性能(转载的一篇文章)

    MySQLTuner 是一个 Perl 脚本,可以用来分析您的 MySQL 性能,并且基于收集到的信息给出相应的优化建议.这样子,您就可以调整 my.cnf 从而优化您的 MySQL 设置. 这边只是 ...

  4. 在where条件中使用CASE WHEN 语句

    CREATE TABLE TB_Test_Report ( id int identity, stateid int, userid int, username ) ) go ,,'a') ,,'b' ...

  5. 第 一 百 天上课 PHP TP框架 数据库修改和删除

    修改的三种方式 //造数组的方式修改 public function xiugai1() { $db=D('yonghu'); $attr=array ( 'zhanghao'=>001, // ...

  6. ---iproute2 策略路由

    http://linux.chinaunix.net/techdoc/net/2007/03/30/953750.shtml 这篇文章写的例子讲明白策略路由的使用,但是本身好像不用这么麻烦, 用系统默 ...

  7. 一步步编写avalon组件01:弹出层组件

    avalon2已经稳定下来,是时候教大家如何使用组件这个高级功能了. 组件是我们实现叠积木开发的关键. avalon2实现一个组件非常轻松,并且如何操作这个组件也比以前的avalon2,还是react ...

  8. 关于web测试

    关于web测试1页面部分(1) 页面清单是否完整(是否已经将所需要的页面全部都列出来了)(2) 页面是否显示(在不同分辨率下页面是否存在,在不同浏览器版本中页面是是否显示)(3) 页面在窗口中的显示是 ...

  9. Dobbo的继任者?试用微博RPC框架Motan

    从14年开始就陆续看到新浪微博RPC框架Motan的介绍,时隔两年后,微博团队终于宣布开源轻量级RPC框架Motan,项目地址: https://github.com/weibocom/motan/ ...

  10. 用Javascript取float型小数点

    用Javascript取float型小数点后两位,例 var a = 12.2369826取成12.23,如何做?下面四种方法可用 (1)     var str = a.substring(0,s. ...