概述

之前学习的 Agent,GenSever以及GenEvent,都是用来管理状态或者处理消息的。

但是在很多时候,我们需要的是执行某个任务,这时如果使用 GenSever 或者 GenEvent,就会显得比较笨重。

这时,我们就可以使用 Task 模块,使用 Task 模块时注意以下几点:

  1. 每个 task 只执行一个特定的功能,要让 task 处理的业务尽量简单(如果业务复杂的话,考虑使用 GenSever 或者 GenEvent)
  2. 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平台 完美解决上述并发和异步中的问题。

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

elixir 高可用系列(四) Task的更多相关文章

  1. elixir 高可用系列 - 目录

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

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

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

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

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

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

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

  5. elixir 高可用系列(一) Agent

    概述 elixir 本身是一种 immutable 的语言,默认情况下,进程间是不共享任何状态的,进程之间通过消息来交互. 而 Agent 则封装了一种进程间共享状态的方式,通过这种方式,不用显式的写 ...

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

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

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

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

  8. keepalived高可用系列~keepalived+mysql

    一 简介:建立读写分离模式 二 keepalived相关配置 vrrp_instance VI_1 {  state MASTER  // 可修改  interface eth0  virtual_r ...

  9. keepalived高可用系列~通用基础

    简介:今天咱们来聊聊keepalived一 keepalived 架构 1  标准架构: keepalived+lvs/haproxy+后端 real server(mysql从库,nginx.myc ...

随机推荐

  1. Linux:基础配置--备忘

    1.网络 /etc/sysconfig/network-scripts/ifcfg-eth0 DEVICE=eth0 HWADDR=08:00:27:77:F3:A1 TYPE=Ethernet UU ...

  2. 1.No MBR错误

    如果提示如下错误: Error: No MBR is found at SD/MMC.                                              Hint: use f ...

  3. RadGridView标头分行

  4. Mysql命令行中文乱码的解决方法

    环境:Windows 8 64位,Mysql  5.0.96 for Win64 (x86) 数据库本身安装时默认已经是使用utf8编码的了,但在命令行中执行查询时,查询到的中文依然乱码,解决方法如下 ...

  5. CLR VIA C#事件

    事件是类型的一个成员,用来在事情发生的时候通知注册了该事件的成员. 事件和观察者模式十分的相似,所以事件应该提供如下几种能力 1.能让对象的方法登记对他的关注 2.能让对象的方法取消对他的关注 3.能 ...

  6. VC++ 标准C++中的string类的用法总结

    相信使用过MFC编程的朋友对CString这个类的印象应该非常深刻吧?的确,MFC中的CString类使用起来真的非常的方便好用.但是如果离开了MFC框架,还有没有这样使用起来非常方便的类呢?答案是肯 ...

  7. iOS学习笔记(5)— UITextField

    UITextField详解 一.基本属性 1.创建文本输入框 UITextField*textField=[[UITextField alloc]initWithFrame:CGRectMake(10 ...

  8. java基础八 [序列化和文件的输入/输出](阅读Head First Java记录)

    对象具有状态和行为两种属性.行为存在类中的方法中,想要保存状态有多种方法,这里介绍两种: 一是保存整个当前对象本身(通过序列化):一是将对象中各个状态值保存到文件中(这种方式可以给其他非JAVA程序用 ...

  9. html 高亮显示表格当前行

    html在线模拟网:http://www.w3school.com.cn/tiy/t.asp?f=html_basic 高亮显示表格当前行 <html> <head> < ...

  10. OpenLDAP与phpldapadmin的搭建

    最近一直在看LDAP的东西,把自己的记录下来,以后可以看看. 1:环境 1):关闭防火墙 service iptables stop 2):setenforce 0 vim /etc/sysconfi ...