概述

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. 常用freemarker使用文档

    设置价格格式 <#setting number_format = "currency" /> <#assign price = 42 /> ${price} ...

  2. 使用linux的nc来进行文件的传输

    NAME nc - arbitrary TCP and UDP connections and listensSYNOPSIS     nc [-46DdhklnrStUuvz] [-i interv ...

  3. Linux 文件锁

    当多个进程同时访问操作同一个文件时,我们怎么保证文件数据的正确性. linux通常采用的方法是文件上锁,来避免共享资源的产生竞争状态. 文件锁包括建议性锁和强制性的锁: 建议性的锁 :顾名思义,相对温 ...

  4. SQL 基础:Select语句,各种join,union用法

    一.基本的SELECT语句 1. “*”的注意事项:在SELECT语句中,用*来选取所有的列,这是一个应该抵制的习惯. 虽然节省了输入列名的时间,但是也意味着获得的数据比真正需要的数据多的多.相应的, ...

  5. VC++ CTreeCtrl 使用NM_CLICK和TVN_SELCHANGED

    //这是当CTREECTRL控件点击时NM_CLICK的处理函数 void CDriverSelCtrl::OnNMClick(NMHDR *pNMHDR, LRESULT *pResult) { C ...

  6. debian vi

    这次用DigitalOcean VPS发现vi的方向键变成字母,没办法正常使用,搜索了下找到了解决办法. 1 vi /etc/vim/vimrc.tiny 找到set compatible改为set ...

  7. 安卓中adapter的应用

    个人菜鸟总结,期待大神指点,悉心倾看! Adapter是ListView界面与数据之间的桥梁,Adapter提供对数据的访问,也负责为每一项数据产生一个对应的View(白话通俗点:先写adapter为 ...

  8. 亚马逊开放机器学习系统源代码:挑战谷歌TensorFlow

    北京时间5月17日上午消息,亚马逊在开源技术领域迈出了更大的步伐,宣布开放该公司的机器学习软件DSSTNE的源代码.这个最新项目将与谷歌的TensorFlow竞争,后者已于去年开源.亚马逊表示,在缺乏 ...

  9. Groovy basic

    1. print println "Hello Groovy!" you can use java in Groovy System.out.println("Hello ...

  10. cms替换主页的步骤

    cms替换主页的步骤 .先做好静态页面: .在D:\wamp\www\phpcms\install_package\phpcms\templates文件夹下建新的文件夹tianqiwangluo(项目 ...