elixir 高可用系列(四) Task
概述
之前学习的 Agent,GenSever以及GenEvent,都是用来管理状态或者处理消息的。
但是在很多时候,我们需要的是执行某个任务,这时如果使用 GenSever 或者 GenEvent,就会显得比较笨重。
这时,我们就可以使用 Task 模块,使用 Task 模块时注意以下几点:
- 每个 task 只执行一个特定的功能,要让 task 处理的业务尽量简单(如果业务复杂的话,考虑使用 GenSever 或者 GenEvent)
- task 之间尽量不要交互,也尽量不要和其他 process交互 ,保持 task 的独立性
task 最重要的特性是能够方便的将顺序执行的代码转变为并发执行的代码。
task 示例
示例一: 将顺序代码转为并发代码(类似多线程)
defmodule TaskTest do
def test_sync() do
for n <- [1,2,3,4] do
:timer.sleep(1000)
IO.puts("it's #{n} #{TimeUtil.now}")
end
end
def test_async() do
for n <- [1,2,3,4] do
Task.start_link(fn ->
:timer.sleep(1000)
IO.puts("it's #{n} #{TimeUtil.now}")
end)
end
end
defmodule TimeUtil do
def now() do
{{y,m,d}, {h,mm,s}} = :calendar.local_time
"#{y}/#{m}/#{d} #{h}:#{mm}:#{s}"
end
end
IO.puts "execute sync"
TaskTest.test_sync
IO.puts "==============================="
IO.puts "execute async"
TaskTest.test_async
执行结果如下:
iex(1)> r(TaskTest)
execute sync
it's 1 2016/5/31 13:53:2
it's 2 2016/5/31 13:53:3
it's 3 2016/5/31 13:53:4
it's 4 2016/5/31 13:53:5
===============================
execute async
it's 1 2016/5/31 13:53:6
it's 2 2016/5/31 13:53:6
it's 3 2016/5/31 13:53:6
it's 4 2016/5/31 13:53:6
示例二:异步执行,并获取执行结果
defmodule TaskTest do
def exec_task() do
t = Task.async(fn ->
IO.puts("start to do something at #{TimeUtil.now}")
:timer.sleep(3000)
end)
t
end
def get_task_result(t) do
Task.await(t, 5000)
IO.puts("get something result at #{TimeUtil.now}")
end
end
defmodule TimeUtil do
def now() do
{{y,m,d}, {h,mm,s}} = :calendar.local_time
"#{y}/#{m}/#{d} #{h}:#{mm}:#{s}"
end
end
t = TaskTest.exec_task # 异步执行
IO.inspect(TaskTest.get_task_result(t)) # 同步获取执行结果
运行结果如下:
iex(1)> r(TaskTest)
start to do something at 2016/5/31 14:24:48
get something result at 2016/5/31 14:24:51
:ok
注意 如果 get_task_result 中 Task.await 的超时时间设置的小于task的执行时间的话(比如await的时间由 5000 -> 2000),
那么,会导致 get_task_result timeout的错误。
总结
从上面的例子可以看出,利用 Task 模块,可以很方便的实现并发和异步操作。
但是,在用 task 执行任务的时候,我们发现,在并发和异步的环境中,如果某个 task 执行失败的话,甚至会导致主进程也失败。
下一节的监督者机制,将介绍 elixir 如何利用 OTP平台 完美解决上述并发和异步中的问题。
elixir 高可用系列(四) Task的更多相关文章
- elixir 高可用系列 - 目录
1. elixir 高可用系列(一) Agent 2. elixir 高可用系列(二) GenServer 3. elixir 高可用系列(三) GenEvent 4. elixir 高可用系列(四) ...
- elixir 高可用系列(五) Supervisor
概述 OTP 平台的容错性高,是因为它提供了机制来监控所有 processes 的状态,如果有进程出现异常, 不仅可以及时检测到错误,还可以对 processes 进行重启等操作. 有了 superv ...
- elixir 高可用系列(三) GenEvent
概述 GenEvent 是事件处理的通用部分的抽象. 通过 GenEvent ,我们给已有的服务 动态 的添加 事件处理. GenEevent 和 GenServer 的区别 之前已经介绍了 GenS ...
- elixir 高可用系列(二) GenServer
概述 如果我们需要管理多个进程,那么,就需要一个专门的 server 来集中监控和控制这些进程的状态,启停等. OTP 平台中的 GenServer 就是对这个 server 通用部分的抽象. 利用 ...
- elixir 高可用系列(一) Agent
概述 elixir 本身是一种 immutable 的语言,默认情况下,进程间是不共享任何状态的,进程之间通过消息来交互. 而 Agent 则封装了一种进程间共享状态的方式,通过这种方式,不用显式的写 ...
- (5.8)mysql高可用系列——MySQL中的GTID复制(实践篇)
一.基于GTID的异步复制(一主一从)无数据/少数据搭建 二.基于GTID的无损半同步复制(一主一从)(mysql5.7)基于大数据量的初始化 正文: [0]概念 [0.5]GTID 复制(mysql ...
- keepalived高可用系列~ keepalived+proxysql
一 简介:介绍下高可用通用的方案 二 目的:一个中间件提供服务,故障后,另一个中间件提供服务 三 手段: 应用keepalived的vrrp_scripts服务 四 具体配置 global_defs ...
- keepalived高可用系列~keepalived+mysql
一 简介:建立读写分离模式 二 keepalived相关配置 vrrp_instance VI_1 { state MASTER // 可修改 interface eth0 virtual_r ...
- keepalived高可用系列~通用基础
简介:今天咱们来聊聊keepalived一 keepalived 架构 1 标准架构: keepalived+lvs/haproxy+后端 real server(mysql从库,nginx.myc ...
随机推荐
- 在php中写接口时 对json格式的转换 简单的方法
方法 一 方法二 可以通过urlencode();遍历出来
- C# 接口应用及意义
写在前面:新手入行,读者勉强看看吧,写的不对的欢迎讨论,板砖轻拍! 一.定义 接口描述的是可属于任何类或结构的一组相关功能,所以实现接口的类或结构必须实现接口定义中指定的接口成员. 通常用Interf ...
- Django web 基础
一.Django概述 Django大而全; 创建Django工程:django-admin startproject sitename 创建django之后生成的目录结构如下: Project Pro ...
- ghost系统到硬盘完后,重启进入winxp安装的画面变成了蓝屏
ghost系统到硬盘完后,重启进入winxp安装的画面变成了蓝屏 原因分析: 一.系统集成的驱动和主板不兼容 这种原因引起的故障在部份品牌机上较常见,主要症状是系统能正常安装完成,但完成后重启进入系 ...
- C/C++操作MySQL数据库——增、删、改、查
1.数据库链接 int cppDatebase::DatabaseConnect(sBit8 *uName,sBit8 *pWord,sBit8 *dbName) { dbHandle = mysql ...
- jquery移动端日期插件
不说多的,直接看代码<!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...
- 反向代理及如何获得原始IP
在现代网站架构中,scalability 已经不再是可有可无的质量属性,而是决定着网站的生死攸关,所以稍微上规模的站点都不会只有一个web server,让internet clients 直接与其交 ...
- 校验日期函数的js
/判断输入内容是否为空 function IsNull(){ var str = document.getElementById('str').value.trim(); if(str.length= ...
- CentOS 6.5 源码编译搭建LNMP(三台独立主机实现)
搭建前准备: 1.三台独立主机 nginx:192.168.1.102 php-fpm:192.168.1.105 mysql:192.168.1.103 2.相关软件的源码包 nginx:nginx ...
- C++STL学习笔记_(1)string知识
/*============================================ string是STL的字符串类型,通常用来表示字符串 = ======================== ...