elixir 高可用系列(四) Task

简介:

概述

之前学习的 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/



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


目录
相关文章
|
存储 安全 数据安全/隐私保护
中外AIGC大模型的差距、态势与结构
【1月更文挑战第21天】中外AIGC大模型的差距、态势与结构
585 2
中外AIGC大模型的差距、态势与结构
|
10月前
|
供应链 算法 调度
【双层模型】考虑供需双侧的综合能源双层优化模型
该程序构建了一个综合能源系统的优化调度双层模型,采用差分进化算法和规划算法分别求解上下层问题。模型涵盖了燃气轮机、锅炉、风电、光伏及储能设备的协同运行,并考虑了供应商与用户的利益平衡。通过满足设备出力、储能、负荷平衡等约束条件,实现了系统经济性和性能的优化。程序基于Matlab+Cplex编写,注释详尽且附带文档说明,便于学习研究。
|
存储 机器学习/深度学习 人工智能
探索未来科技:人工智能与区块链的融合之路
【10月更文挑战第14天】探索未来科技:人工智能与区块链的融合之路
565 1
|
人工智能 弹性计算 API
通义万相AI绘画创作体验评测
从使用者的角度解读通义万相AI绘画创作方案的优与劣
11492 12
|
存储 Android开发
Android 高版本 packageManager.getPackageArchiveInfo 总是返回null
Android 高版本 packageManager.getPackageArchiveInfo 总是返回null
546 1
|
存储 Prometheus 监控
【监控】grafana图表使用快速上手
【监控】grafana图表使用快速上手
489 0
|
小程序 JavaScript Java
宿舍|学生宿舍管理小程序|基于微信小程序的学生宿舍管理系统设计与实现(源码+数据库+文档)
宿舍|学生宿舍管理小程序|基于微信小程序的学生宿舍管理系统设计与实现(源码+数据库+文档)
432 0
|
前端开发 UED Python
Wagtail-基于Python Django的内容管理系统CMS实现公网访问
Wagtail-基于Python Django的内容管理系统CMS实现公网访问
330 0
|
机器学习/深度学习 编解码
YOLOv8改进 | 主干篇 | EfficientNetV2均衡缩放网络改进特征提取层
YOLOv8改进 | 主干篇 | EfficientNetV2均衡缩放网络改进特征提取层
522 0
|
人工智能 安全 Linux
​idea中使用X-ChatGPT详解
使用编程ai插件X-ChatGPT提高开发效率
394 0