elixir 高可用系列(三) GenEvent

简介:

概述

GenEvent 是事件处理的通用部分的抽象。
通过 GenEvent ,我们给已有的服务 动态 的添加 事件处理。

GenEevent 和 GenServer 的区别

之前已经介绍了 GenServer ,GenServer 和 GenEvent 的主要区别在于:

  • GenServer 是服务器的抽象,除了封装处理 同步/异步 事件的方法之外,还封装了服务器本身的启动/停止等方法。
  • GenEvent 是事件的抽象,封装了 同步/异步 事件的处理方法,GenEvent 可以绑定到任何服务器上,从而动态的 添加 服务器的处理方法。

基于上述的区别,GenEvent 和 GenServer 的应用场景也不同。

  • GenServer 可以帮助我们快速的创建服务,它类似于一个服务的脚手架,使用 GenServer,构建服务时,只需关注服务本身的业务即可
  • GenEvent 可以用于给现有的服务动态添加处理方法,也可以用于抽象多个服务的共通处理

GenEevent 示例

事件管理器

通过 GenEvent 创建一个事件管理器,将此事件管理器添加到现有进程中,现有进程就有了处理相应事件的能力。

简单示例如下:

  • 接收到 :hello 则返回 :world
  • 接收到 :world 则返回 :hello
  • 接收到 其他消息 则返回 "error msg"
defmodule HelloEvent do
  use GenEvent
  def handle_event(event, parent) do
    case event do
      :hello ->
        send parent, :world
      :world ->
        send parent, :hello
      _ ->
        send parent, "error msg"
    end
    {:ok, parent}
  end
end

测试过程:

# 启动一个空的事件管理器
iex(1)> {:ok, manager} = GenEvent.start_link                     
{:ok, #PID<0.87.0>}
# 发送 :hello 消息
iex(2)> GenEvent.sync_notify(manager, :hello)                    
:ok
# 没有任何反应,因为事件管理器中没有任何 handle 来处理消息
iex(3)> flush                                                    
:ok
# 给事件管理器增加一个handle,同时将当前进程PID作为事件处理的状态
iex(4)> GenEvent.add_handler(manager, HelloEvent, self())        
:ok
# 发送 :hello 消息
iex(5)> GenEvent.sync_notify(manager, :hello)                    
:ok
# 事件管理器处理了 :hello 消息,并返回 :world 结果
iex(6)> flush                                                    
:world
:ok
# 发送 :world 消息
iex(7)> GenEvent.sync_notify(manager, :world)                    
:ok
# 事件管理器处理了 :world 消息,并返回 :hello 结果
iex(8)> flush                                                    
:hello
:ok
# 发送 :test 消息
iex(9)> GenEvent.sync_notify(manager, :test)                     
:ok
# 事件管理器对于 :hello 和 :world 以外的消息都返回 "error msg"
iex(10)> flush                                                   
"error msg"
:ok

上面测试中用的发送消息的方法都是同步方式 sync_notify ,通过异步方式 notify 发送消息也是一样的, GenEvent 的 handle_event 接收同步和异步的消息。

事件流

事件流就是将 GenEvent 的事件转入到流中,这样,就可以通过处理流的方式来处理事件。

比如上面的例子,通过 GenEvent 的 stream ,可以不定义 defmodule HelloEvent 也实现上面的功能。

上述测试过程可以改为如下:

iex(1)> {:ok, manager} = GenEvent.start_link
{:ok, #PID<0.59.0>}
iex(2)> stream = GenEvent.stream(manager)
%GenEvent.Stream{manager: #PID<0.59.0>, timeout: :infinity}
iex(3)>
nil
iex(4)> spawn_link fn ->
...(4)>   for x <- stream do
...(4)>     case x do
...(4)>       :hello -> IO.inspect :world
...(4)>       :world -> IO.inspect :hello
...(4)>       _ -> IO.inspect "error msg"
...(4)>     end
...(4)>   end
...(4)> end
#PID<0.71.0>
iex(5)> GenEvent.sync_notify(manager, :hello)
:world
:ok
iex(6)> GenEvent.sync_notify(manager, :world)
:hello
:ok
iex(7)> GenEvent.sync_notify(manager, :test)
"error msg"
:ok

可以看出,我们没有给 GenEvent 绑定任何的 handler,而是在 GenEvent 的事件流中对所有消息进行了处理。

GenEvent 中事件流的特性是 erlang 中所没有的。

总结

除了上面用的 handle_event 和 stream, GenEvent 中还有其他的实用的 Functios 和 Callbacks

具体参见:http://elixir-lang.org/docs/stable/elixir/GenEvent.html

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



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


目录
相关文章
|
人工智能 自然语言处理 算法
SAM-U升级SAM | 带你分析SAM的弱点并重新优化设计填补空缺
SAM-U升级SAM | 带你分析SAM的弱点并重新优化设计填补空缺
259 0
|
网络协议 数据库 网络架构
华为路由器如何过滤OSPF 特定的3类LSA?
华为路由器如何过滤OSPF 特定的3类LSA?
271 0
|
消息中间件 分布式计算 Hadoop
实时计算 Flink版操作报错合集之使用flink jar开发,报错:找不到main方法,是什么原因
在使用实时计算Flink版过程中,可能会遇到各种错误,了解这些错误的原因及解决方法对于高效排错至关重要。针对具体问题,查看Flink的日志是关键,它们通常会提供更详细的错误信息和堆栈跟踪,有助于定位问题。此外,Flink社区文档和官方论坛也是寻求帮助的好去处。以下是一些常见的操作报错及其可能的原因与解决策略。
|
消息中间件 移动开发
PCIe RN (Readiness Notification)介绍
PCIe RN (Readiness Notification)介绍
993 0
PCIe RN (Readiness Notification)介绍
|
存储 安全 数据安全/隐私保护
云计算中的数据安全与隐私保护:技术与挑战
云计算中的数据安全与隐私保护:技术与挑战
1161 0
|
数据可视化 应用服务中间件 nginx
Docker Swarm编排:构建简单集群
Docker Swarm 是 Docker 官方提供的容器编排工具,通过它可以轻松构建和管理多个 Docker 容器的集群。本文将深入探讨 Docker Swarm 的基础概念、构建集群的步骤,并提供更为丰富和实际的示例代码,帮助大家全面了解如何使用 Docker Swarm 搭建一个简单而强大的容器编排集群。
|
C# 图形学
【Unity 3D】元宇宙案例之虚拟地球信息射线实战(附源码、演示视频和步骤 超详细)
【Unity 3D】元宇宙案例之虚拟地球信息射线实战(附源码、演示视频和步骤 超详细)
320 0
|
人工智能 运维 搜索推荐
【互联网+“创新创业大赛”】智慧课堂项目计划书
智慧课堂项目是一种基于互联网、人工智能、大数据等技术的数字化教育解决方案。该项目旨在升级传统课堂教学模式,将传统教育与数字化教育相结合,创造更加智能化、高效化、个性化的教学环境。 智慧课堂项目的主要目标是提高教学质量和效率,满足学生及家长对于灵活性和个性化学习需求,解决教育过程中出现的一些问题。 智慧课堂项目主要包括以下几个方面: 智能化的教学平台:利用互联网和人工智能技术,建立一套智能化的教学平台,包括课程内容、教学计划、教学方式等的数字化管理和推送,提高教师教学的效率和质量。 个性化学习环境:根据每个学生的学习需求和兴趣,为学生提供个性化的学习环境,包括学习内容、学习进度和学习方式等.
884 2
|
机器学习/深度学习 人工智能 算法
秒懂算法 | 莫队算法
本篇介绍了莫队算法的几何意义、基本莫队、带修改莫队以及树上莫队的相关内容。
835 1
秒懂算法 | 莫队算法
|
开发框架 自然语言处理 数据库连接