elixir 高可用系列(四) Task
程序员文章站
2022-06-16 23:48:11
概述 之前学习的 Agent,GenSever以及GenEvent,都是用来管理状态或者处理消息的。 但是在很多时候,我们需要的是执行某个任务,这时如果使用 GenSever 或者 GenEvent,就会显得比较笨重。 这时,我们就可以使用 Task 模块,使用 Task 模块时注意以下几点: 1. ......
概述
之前学习的 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平台 完美解决上述并发和异步中的问题。
来源:http://blog.iotalabs.io/
上一篇: Lua脚本调用外部脚本
下一篇: Lua中的源代码预编译浅析
推荐阅读
-
Spark快速入门系列(6) | Spark环境搭建—standalone(3) 配置HA高可用模式
-
[Security系列一]拿什么保障企业对外网络服务的高可用性?
-
redis 系列26 Cluster高可用 (1)
-
redis 系列27 Cluster高可用 (2)
-
Spring Cloud 学习系列:(十三)高可用的分布式配置中心——Spring Cloud Config
-
搭建高可用mongodb集群(四)—— 分片
-
搭建高可用mongodb集群(四)—— 分片
-
MySQL系列之十四 MySQL的高可用实现
-
redis 系列25 哨兵Sentinel (高可用演示 下)
-
高并发高可用复杂系统中的缓存架构(四) redis架构基础