2.8 标准ZIO服务

在本章的前面,我们讨论了ZIO环境类型,但是我们还没有使用它来编写任何程序。 在本书的后面,我们将深入介绍环境,并说明该环境如何为依赖项注入问题提供全面的解决方案。
现在,我们将讨论ZIO为每个应用程序提供的基本服务以及如何使用它们。
服务提供了定义明确的接口,可以在测试环境和生产环境中以不同的方式实现这些接口。ZIO根据平台为所有应用程序提供四到五个不同的默认服务:
1.Clock。 提供与时间和计划有关的功能。 如果您正在访问当前时间或计划在将来某个时间进行计算,则使用此时间。
2. Console. 提供与控制台输入和输出相关的功能。
3. System. 提供用于获取系统和环境变量的功能的能力。
4. Random. 提供用于生成随机值的功能。
5. Blocking. 用于工作负载优化,在单独的Executor上运行阻塞任务。 由于Scala.js不支持阻止,因此该服务仅在JVM上可用。

由于此基本系统功能是作为服务提供的,因此您可以轻松测试使用这些服务的任何代码,而无需实际与生产实现进行交互。

例如,随机服务使我们能够生成随机数。该服务的Live实现只是委托给scala.util.Random。但这可能并不总是我们想要的实现。 scala.util.Random是不确定的,在生产中可能有用,但会使我们更难测试程序。为了测试随机服务,我们可能要使用纯功能的伪随机数生成器,该生成器在给定相同初始种子的情况下始终会生成相同的值。这样,如果测试失败,我们可以重现失败并进行调试。
ZIO Test是用于测试ZIO应用程序的工具包,我们将在下一章中对其进行讨论,它提供了一个TestRandom来完成此任务。实际上,ZIO Test提供了每个标准服务的测试实现,并且您可以想象也希望提供其他实现。

ZIO提供了针对阻塞任务提供了特定的Executor的默认实现,但是您可以通过多种其他方式针对特定的使用模式调整Executor。

通过根据定义良好的接口定义功能,我们将具体实现推迟到以后。如您将看到的,将这些服务与ZIO一起使用非常容易,但是与此同时,高级用户具有极大的灵活性来提供这些服务(或您在自己的应用程序中定义的服务)的自定义实现。

使用服务的第二个较小的好处是,您可以使用该功能来记录效果中正在使用的功能。如果我们看到一个带有ZIO [Clock,Nothing,Unit]类型签名的效果,我们可以得出结论,这种效果(不会失败)正在使用与时间或调度相关的功能(可能不是与随机数有关的功能)。

但是,这种好处较小,因为只有在您的团队对接口编码(而不是实现)有严格的纪律时,这才是正确的。因为效果构造函数可以将任何副作用代码包装到ZIO值中,所以没有什么可以阻止我们编写如下代码:

val int: ZIO[Any, Nothing, Int] = ZIO.effectTotal(scala.util.Random.nextInt())

在此代码段中,我们将生成随机数,但这不会反映在类型签名中,因为我们直接包装了scala.util.Random,而不是在Random服务上使用方法。 不幸的是,编译器无法为我们进行检查,因此必须确保开发人员对接口的代码必须通过代码审查来实施。

因此,我们考虑了“查看”计算使用什么功能的能力,作为使用服务的次要和可选的好处。 主要的好处就是能够在测试和生产环境中插入不同的实现。现在,让我们详细讨论每种标准的ZIO服务。

2.8.1 Clock

Clock服务提供与时间和计划有关的功能。 这包括几种以不同方式获取当前时间的方法(currentTime以指定的TimeUnit返回当前时间,currentDateTime以返回当前OffsetDateTime,nanoTime以纳米为单位获取当前时间)。
此外,时钟服务还包括一种睡眠方法,可用于睡眠一定时间。
以下代码段显示了nanoTime和sleep的签名:

  import zio.duration._package object clock {def nanoTime: URIO[Clock, Long]def sleep(duration: => Duration): URIO[Clock, Unit]}

睡眠方法特别重要。 在指定的持续时间过去之前,它不会完成执行,并且像所有ZIO操作一样,它是非阻塞的,因此在等待时间过去时,它实际上并没有消耗任何线程。
我们可以使用sleep方法来实现本章前面介绍的延迟运算符:

  import zio.clock._import zio.duration._def delay[R, E, A](zio: ZIO[R, E, A])(duration: Duration): ZIO[R with Clock, E, A] = clock.sleep(duration) *> zio

Clock服务是ZIO中所有时间和计划功能的基础。 因此,每当重试,重复,计时或ZIO中内置的与时间和调度有关的其他功能时,您都将Clock服务视为环境的组成部分。

2.8.2 Console

控制台服务提供了有关读写控制台的功能。
到目前为止,在本书中,我们一直在通过使用ZIO.effect构造函数将Scala库中的过程代码转换为ZIO效果与控制台进行交互。 这有助于说明如何将程序转换为ZIO,并证明ZIO自己的控制台功能没有“魔力”。
但是,直接包装控制台功能并不理想,因为我们无法为测试环境提供替代实现。 此外,控制台服务还会为我们处理一些棘手的控制台交互案例。 (例如,从控制台读取只能因IOException而失败。)
控制台服务上的关键方法是getStrLn,它类似于readLine()putStrLn,它等效于println。 如果不想在将文本打印到控制台之后添加换行符,则还有一个putStr方法。

  package object console {val getStrLn : ZIO [Console, IOException, String]def putStr(line : => String) : URIO [Console, Unit]def putStrLn(line : => String) : URIO [Console, Unit]}

控制台服务通常在控制台应用程序中使用,但在代码中不如时钟或随机出现的多。
在本书的其余部分,我们将说明使用这些方法涉及控制台应用程序的示例,而不是从Scala标准库转换方法。

2.8.3 System

系统服务提供了获取系统和环境变量的功能。

  package object system {def env(variable : String) : IO [SecurityException, Option [String]]def property(prop : String) : IO [Throwable, Option [String]]}

System服务上的两个主要方法是env(访问指定的环境变量)和property(访问指定的系统属性)。如果不存在指定的环境变量或属性,还有其他方法可用于获取所有环境变量或系统属性.又或者指定默认值。
与控制台服务一样,系统服务通常在应用程序或某些库(例如,处理配置的库)中使用更多,但在通用代码中并不常见。

2.8.4 Random

随机服务提供与随机数生成相关的功能。 随机服务公开与scala.util.Random基本上相同的接口,但是所有方法都返回功能效果。 因此,如果您熟悉标准库中的random.nextInt(6)之类的代码,那么使用Random服务应该会很舒服。
随机服务有时在调度中的通用代码中使用,例如在某些效果的重复之间添加随机延迟时。

2.8.5 Blocking

阻塞服务支持 在针对阻塞任务进行了优化的执行器上 运行阻塞效果。 默认情况下,ZIO运行时针对异步和计算绑定任务进行了优化,并具有少量固定数量的线程来执行所有工作。
尽管此选择可以优化异步和CPU任务的吞吐量,但是这意味着,如果您在ZIO的默认线程上运行阻塞的I / O操作,则可能会耗尽它们。 因此,至关重要的是,阻塞任务必须在单独的阻塞线程池上运行,该池针对这些工作负载进行了优化。
阻塞服务有几种支持此用例的方法。
最基本的是blocking操作,它会消费一个effect并确保它将在阻塞线程池上运行。

  import zio.blocking._object blocking {def blocking[R <: Blocking, E, A](zio: ZIO[R, E, A]): ZIO[R, E, A] =???}

假设上述数据库查询不是基于基于回调的API来实现的,而是同步等待直到结果可用(从而阻塞了调用线程)。 在这种情况下,我们想确保通过使用blocking操作在阻塞线程池上执行效果,如以下代码片段所示:

  import zio.blocking._def getUserById(id: Int): IO[Unit, String] =???def getUserByIdBlocking(id: Int): ZIO[Blocking, Unit, String] =blocking(getUserById(id))

请注意,阻塞服务现在是类型签名中的依赖项,它说明返回的效果涉及阻塞IO,而其先前的签名则没有。
如果要直接从阻塞的副作用构造一个effect,则可以使用effectBlocking构造函数,它等效于blocking(ZIO.effect(…))。

2.8 zio入门——标准ZIO服务相关推荐

  1. 2.10 zio入门——总结

    2.10 总结 函数式作用是并发工作流的蓝图,不可变的值提供了多种运算符,用于转换和组合effect以解决更复杂的问题. ZIO类型参数使我们可以对需要上下文提供环境才能执行的作用进行建模:它们使我们 ...

  2. 2.7 zio入门——更多的Effect构造函数

    2.7 更多的Effect构造函数 在本章的前面,我们了解了如何使用ZIO.effect构造函数将过程代码转换为ZIO效果.ZIO.effect构造函数是一种有用且通用的效果构造函数,但并不适合所有情 ...

  3. 2.1 zio入门——把函数作用作为工作蓝图

    ZIO标准库的核心数据类型是ZIO[R, E, A],这种类型的值被称为函数式作用 函数式作用是并发工作流的一种蓝图,如图1所示.该蓝图本质上是纯描述性的,必须执行才能观察到任何副作用,例如与数据库的 ...

  4. 2.5 zio入门——ZIO类型别名

    2.5 ZIO类型别名 ZIO的三个类型参数,功能极为强大.我们可以使用环境类型参数进行参数注入(数据库,连接池,配置等),并且可以使用错误和成功类型参数返回结果. 在最常见的情况下,程序需要向下传播 ...

  5. NIO框架入门(一):服务端基于Netty4的UDP双向通信Demo演示

    2019独角兽企业重金招聘Python工程师标准>>> 前言 NIO框架的流行,使得开发大并发.高性能的互联网服务端成为可能.这其中最流行的无非就是MINA和Netty了,MINA目 ...

  6. 视频教程-【吴刚】电商活动站设计初级入门标准视频教程-UI

    [吴刚]电商活动站设计初级入门标准视频教程 业内知名UID.UED.用户体验.品牌策略与创意设计师,十三年行业职业教育培训经验,业内"UI视频第一人",教学总监.视觉设计讲师. A ...

  7. 视频教程-【吴刚】个人网站设计初级入门标准视频教程-UI

    [吴刚]个人网站设计初级入门标准视频教程 业内知名UID.UED.用户体验.品牌策略与创意设计师,十三年行业职业教育培训经验,业内"UI视频第一人",教学总监.视觉设计讲师. Ad ...

  8. 视频教程-【吴刚】电商网站详情页设计初级入门标准视频教程-UI

    [吴刚]电商网站详情页设计初级入门标准视频教程 业内知名UID.UED.用户体验.品牌策略与创意设计师,十三年行业职业教育培训经验,业内"UI视频第一人",教学总监.视觉设计讲师. ...

  9. 视频教程-【吴刚】UI拟物图标设计初级入门标准教程-UI

    [吴刚]UI拟物图标设计初级入门标准教程 业内知名UID.UED.用户体验.品牌策略与创意设计师,十三年行业职业教育培训经验,业内"UI视频第一人",教学总监.视觉设计讲师. Ad ...

最新文章

  1. ARTS打卡计划第四周-ALGORITHM
  2. 详解语句srcImage(cv::Rect(xRoi,yRoi,widthRoi,heightRoi)).copyTo(roiImage);
  3. 小白重装系统教程_重装解决99%的电脑问题:小白U盘重装系统教程
  4. 成功解决AttributeError: module ‘tensorflow‘ has no attribute ‘placeholder‘
  5. css跑道_如何不超出跑道:计划种子的简单方法
  6. oracle中packages使用,oracle中packages的使用
  7. [转载]监控 Linux 性能的 18 个命令行工具
  8. 传智教育1月12日在深交所成功挂牌上市,教育行业A股IPO第一股今诞生!
  9. oracle执行plus时跳出,oracle – 从shell脚本运行sqlplus时管理错误处理
  10. 华为MA5616配置及维护指南
  11. 通过过滤器获取表单元素
  12. acm入门搜索-石油数目
  13. Linux中安装软件
  14. 日记 [2007年11月19日]...
  15. 百宝云网络验证对接+脚本更新功能(源码)
  16. Django搭建个人博客之编写博客文章的Model模型
  17. 鸿蒙初开三界未立,太子长琴
  18. 标梵互动:微信公众号开发之node第二篇
  19. USB音频编解码芯片电路方案设计(原理图)|TYPEC音频方案|TYPEC扩展坞方案|USB音频方案
  20. 算法中的一些数学问题分享,ICG游戏

热门文章

  1. 网站设计的好坏对宣传的效果的影响!
  2. 风袖第一阶段之每周上新
  3. Echarts饼图无法切换漏斗图问题处理
  4. 又是白嫖Gitee的一天,PicGo+Gitee搭建图床,用过的都说真香!!!
  5. 新一配:金融学的历史起源和主要分类【转载】
  6. linux jpg图片转base64,html中的图片直接使用base64编码后的字符串代替
  7. 用计算机画函数,用计算机画函数图像 优质课教案设计
  8. 81.(cesium之家)cesium修改灰色背景(默认蓝色)
  9. python语言画成圆相切_三个相切圆的公切圆
  10. 三星i865刷android,三星亮剑,120Hz+1.08亿+高通骁龙865,这才是安卓机皇