首页 > 编程语言 >Go 语言项目源码解析:定时任务库 cron

Go 语言项目源码解析:定时任务库 cron

时间:2022-11-12 11:00:13浏览次数:33  
标签:Cron cron 源码 Go 解析 方法 我们

环境准备

首先我们将源码克隆(Fork)为自己的个人仓库,只需要在 GitHub 项目主页点击 Fork 按钮,然后输入项目名称点击确认即可。克隆完毕后,可以下载到本地,或者直接在科隆后的 GitHub 仓库主页上点击 ​​Create codespace on master​​ 来创建 Codespace。Codespace 是 GitHub 推出的基于 Azure 云服务的远程编程功能,现在对个人账号开放了,可以试一下。

Go 语言项目源码解析:定时任务库 cron_文件包含

点击后,浏览器中会打开一个新页面,并会出现在线 VS Code 的界面,然后显示该项目的目录、代码以及终端,如下图。

Go 语言项目源码解析:定时任务库 cron_文件包含_02

由于我们本次的目的是解析源码,我们主要将在这上面展现和阅读代码,并不会执行它。

现在,我们可以开始解析源码了。

入口文件

解析源码的一个比较好的手段是找到入口文件(Entry File),相当于是一本书的引言(Introduction)章节,项目的整体结构通常会在入口文件中体现出来。

Go 语言项目源码解析:定时任务库 cron_文件包含_03

我们从项目介绍 ​​README.md​​ 文件中可以看到,这个定时任务库的使用方式是 ​​cron.New(cron.WithSeconds())​​ 之类的,也就是 ​​cron.New​​ 方法。因此,我们可以猜测这个方法是在 ​​cron.go​​ 中,我们打开它看一看。

快速扫了一遍之后,我们可以发现这个 ​​New​​ 方法在 113 行,如下图。

Go 语言项目源码解析:定时任务库 cron_定时任务_04

仔细看一下,这个方法就是返回了一个 ​​Cron​​ 类的实例指针,中间的 ​​opts ...Option​​ 参数是一种函数式参数(Functional Option)。而实际的代码实现,无非就是构造了一个 ​​Cron​​ 类的实例指针 ​​c​​,并对其应用了函数参数,然后返回它。

这样,我们可以判断,真正的定时任务核心逻辑就在 ​​Cron​​ 类中。

不过,无论如何,我们可以确定,入口文件就是 ​​cron.go​​。接下来只需要分析这个文件包含的核心模块、逻辑就可以大概理清楚整个项目的源码了。

核心类

那么我们再来看一下核心类​Cron​​ 的构造,看看是否有什么新东西。

在代码中搜索一下可以定位到 ​​Cron​​ 类在第 13 行。

Go 语言项目源码解析:定时任务库 cron_文件包含_05

​Cron​​ 类有很多属性,包括小写单词表示的私有属性 ​​entries​​、​​chain​​、​​parser​​ 等等,我们暂时还不知道它们各自的含义,不过可以从名称猜测一下。另外,我们还可以看到第 10-12 行的注释描述,意思是 ​​Cron​​ 会追踪 ​​entries​​,并执行被 ​​schedule​​ 定义的函数,它可以开始运行、结束运行,以及 ​​entries​​ 也会在运行过程中被检查。一脸懵逼?是的,这些描述虽然长,但并不能完全解释清楚,我们只有继续阅读更多源码中的细节,才可以了解清楚。

另外,我们还可以在 ​​Cron​​ 类下面发现 3 个接口以及其描述:

  • ​ScheduleParser​​:定时任务的解析器,可以解析并返回 ​​Schedule​​ 实例;
  • ​Job​​:已提交的定时任务作业
  • ​Schedule​​:用于描述作业的运行周期。

其实,这 3 个接口都很重要,我们从它们的所在位置就可以判断出来。

入口方法

在继续探索之前,我们再回忆一下这个定时任务库的使用方法,除了 ​​cron.New​​ 之外,还需要调用 ​​c.Start()​​ 才能正式生效。因此,我们需要仔细看看 ​​Cron​​ 类的 ​​Start​​ 方法。这其实也是核心类的入口方法(Entry Method)。

我们可以在 ​​cron.go​​ 文件中定位到 ​​Start​​ 方法在第 215 行,如下图。

Go 语言项目源码解析:定时任务库 cron_文件包含_06

比较有经验的 Go 语言开发工程师应该会注意到,这是一个典型的原子性操作(Atomic Operation)。​​c.runningMu​​ 是一个 ​​sync.Mutex​​ 实例,可以加锁(Lock);然后 ​​defer c.runningMu.Unlock()​​ 表示函数调用之后会解锁(Unlock),因此保证重复调用该方法的时候不会出现数据竞速(Data Race);​​if c.running { return }​​ 的方法表示,如果已经开始运行了,就不会再执行,直接返回;​​c.running​​ 设置运行状态为 ​​true​​;最后一行比较关键,​​go c.run()​​ 表示新起了一个协程(Goroutine)来运行 ​​c.run​​ 方法。因此,我们找到了更核心的方法,​​run​​。接下来的工作就是继续解析它了。

是不是很像玩 RPG 游戏时不断寻找机关,最终在千辛万苦之下可喜可贺进入下一关?

总结

等一下,就这么完结撒花了?我那啥都准备好了,你就让我看这个?

我们在这里暂时打住的主要原因是不想让这篇文章变得又臭又长。因为源码解析通常是一个需要耐心繁琐枯燥的过程,而这种过程有时会让读者产生抵触情绪。因此,笔者的主要目的是抛砖引玉,将源码解析的一些核心要领用手把手的方式告诉读者,而读者也会根据自己的理解去实际操作,这样学习起来会更快也会更有意思。

现在稍微总结一下这篇文章用到的解析源码技巧:

  1. 找到入口文件
  2. 定位核心类
  3. 解析入口方法

标签:Cron,cron,源码,Go,解析,方法,我们
From: https://blog.51cto.com/u_15773567/5846570

相关文章

  • hadoop单个数据节点的不同存储路径的存储策略源码分析。
    产生问题于数据集群的数节点存储磁盘大小不同,造成使用一段时间以后容量小的磁盘空间紧张。其实,早期配置了磁盘使用存储策略,就能解决该问题,部分网来上说这个策略无效,再hadoop......
  • Idea/goland go debug : version of delve is too old for this version of go.
    terminal:gogetgithub.com/go-delve/delve/cmd/dlv1、拿到最新的dlv.exe。位置在gopath的lib目录下的bin目录。2、help>EditCustomProperties:创建一个properties......
  • 关于Go 包管理
      0、包管理的历史Golang的包管理一直被大众所诟病的一个点,但是我们可以看到现在确实是在往好的方向进行发展。下面是官方的包管理工具的发展历史:......
  • Go 语言机制之栈与指针
    原文作者:WilliamKennedy四哥水平有限,如有翻译或理解错误,烦请帮忙指出,感谢!原文如下:序言这个系列包含四篇文章,主要讲解Go言语指针、栈、堆、逃逸分析和值/指针语义背后的机......
  • 杂谈 | 在 macOS 上使用 Hugo + Coding 搭建个人博客
    文章目录​​前言​​​​旅途特色​​​​QuickStart​​​​一、Hugo配置以及使用​​​​1.Hugo下载安装​​​​2.创建本地网站​​​​3.下载喜欢的HugoTheme......
  • Redis 集群模式的安装与配置【源码安装redis-7.0.5】
    Redis最新版下载地址:http://download.redis.io/releases/redis-7.0.5.tar.gz步骤如下:1)wget http://download.redis.io/releases/redis-7.0.5.tar.gz2)tar-zxf redis-7......
  • 【源码】902- 探索 Snabbdom 模块系统原理
    近几年随着React、Vue等前端框架不断兴起,VirtualDOM概念也越来越火,被用到越来越多的框架、库中。VirtualDOM是基于真实DOM的一层抽象,用简单的JS对象描述真实DOM......
  • 部署ArgoCD
    官网https://github.com/argoproj/argo-cd/releases/tag/v2.5.2我部署的事Non-HA版本kubectlcreatenamespaceargocdkubectlapply-nargocd-fhttps://raw.github......
  • Seata Server 1.5.2 源码学习
    Seata包括Server端和Client端。Seata中有三种角色:TC、TM、RM,其中,Server端就是TC,TM和RM属Client端。Client端的源码学习上一篇已讲过,详见《Seata1.5.2源码学习》,今天来......
  • 一周干货回顾&总结(附论文、源码、链接)
    ​作者:Edison_G本周我们“计算机视觉研究院”主要推送了目标检测干货及中国人工智能大会内容,今天给大家总结一下!公众号ID|ComputerVisionGzq学习群|扫码在主页获取加入方式​......