elixir 高可用系列(一) Agent

简介:

概述

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/



本文转自wang_yb博客园博客,原文链接:http://www.cnblogs.com/wang_yb/p/5422683.html,如需转载请自行联系原作者


目录
相关文章
|
4月前
|
机器人 数据安全/隐私保护 Python
微信自动转发机器人,微信群自动发消息机器人,微信全自动群发软件
展示一个使用Python进行基础网页自动化的示例代码,仅供学习自动化技术原理使用。
|
4月前
|
JSON Java 定位技术
抖音虚拟位置修改器,快手小红书陌陌均支持,jar最新xposed插件
这个代码实现了一个GPS位置模拟器,主要功能包括: 基于基准位置生成随机GPS坐标点
|
12月前
|
敏捷开发 监控 数据可视化
哪些任务管理工具能提升团队协作效率?2024年最佳进度管理工具推荐
随着团队合作和项目管理的数字化转型,选择合适的任务进度管理工具成为提高团队效率的关键。本文推荐5款适合团队使用、功能各异的任务管理工具:板栗看板、Airtable、ZenHub、Proofhub 和 Wrike,旨在帮助团队根据具体需求挑选最合适的软件。这些工具不仅支持任务的高效管理和追踪,还促进了团队成员间的沟通与协作,尤其适用于跨地区协作、远程办公及项目繁杂的环境。
 哪些任务管理工具能提升团队协作效率?2024年最佳进度管理工具推荐
|
7月前
|
人工智能 自动驾驶 物联网
5G到底有多牛?一文看懂它的原理与优势!
5G到底有多牛?一文看懂它的原理与优势!
433 19
|
8月前
|
人工智能 边缘计算 算法
《AI为工业互联网设备,打造互联互通的数字桥梁》
在数字化转型背景下,工业互联网成为推动制造业变革的核心力量,而AI技术的融入为其发展注入新活力。实现工业设备互联互通是关键,但面临设备种类繁杂、协议不统一、网络架构封闭等挑战。通过AI驱动的协议转换、边缘计算融合以及统一标准体系的建立,可有效破解这些难题。华为推出的IT与OT融合方案已在多行业应用,助力企业显著提升生产效率。构建开放生态、加强多方协作,将推动工业互联网繁荣发展,引领智能制造新时代。
231 15
|
11月前
|
人工智能 算法 决策智能
CompassArena上新!JudgeCopilot与新一代Bradley-Terry模型竞技体验
2024 年 5 月,上海人工智能实验室司南 OpenCompass 团队携手魔搭 ModelScope,联合推出了大模型评测平台——CompassArena(大模型竞技场),为大模型领域引入了一种全新的竞技模式。
265 6
CompassArena上新!JudgeCopilot与新一代Bradley-Terry模型竞技体验
|
10月前
|
存储 边缘计算 缓存
智联边缘: CDN算网联动新范式
本文介绍了智联边缘计算中CDN算网联动的新范式,涵盖四个方面:1) 淘宝HTTP3升级实践,介绍XQUIC协议栈的研发与应用;2) 阿里云CDN QUIC应用升级,强调其易用性、可靠性和丰富的功能;3) CDN边缘流量计算应用生态矩阵,展示EdgeRoutine在边缘节点上的多种计算形态和存储方案;4) 新一代Web架构,基于边缘应用开发者平台构建低延迟、免运维的前端边缘应用,提升网站性能和用户体验。通过这些技术,实现了高效、安全、低延迟的网络传输和边缘计算能力。
277 2
|
12月前
|
人工智能 机器人
朱玉可团队新作:看一眼就能模仿,大模型让机器人轻松学会撒盐
朱玉可团队来自UT Austin和NVIDIA Research,提出了一种名为OKAMI的新方法,通过模仿人类行为视频,使机器人能快速学会操作技能,如撒盐、放玩具等。OKAMI分为参考计划生成和对象感知重定位两阶段,显著提高了机器人的操作精度和适应能力,减少了传统方法所需的大量示范和训练时间。
203 3
|
SQL 存储 自然语言处理
Sharding-JDBC 的基本用法和基本原理
Sharding-JDBC 的基本用法和基本原理