引子
GitHub 上有许多优异的开源项目,代码都是通明可见的,每个人只要有账号就能够下载来查看。而咱们作为软件开发者来说也能够从中学习到许多知识,以及领会如何正确的工程化、单元测试、一致代码风格等,乃至从源码中找到问题,并提出 Pull Request 来奉献开源社区。今日这篇文章将解析 Go 言语开源项目 robfig/cron 的源码,这个项目不大,知名度较高,注释也比较清楚,很适合新手学习如何阅览和解析源码。
环境预备
首要咱们将源码克隆(Fork)为自己的个人库房,只需求在 GitHub 项目主页点击 Fork 按钮,然后输入项目称号点击确认即可。克隆完毕后,能够下载到本地,或许直接在科隆后的 GitHub 库房主页上点击 Create codespace on master 来创立 Codespace。Codespace 是 GitHub 推出的基于 Azure 云服务的远程编程功用,现在对个人账号开放了,能够试一下。
点击后,浏览器中会翻开一个新页面,并会呈现在线 VS Code 的界面,然后显现该项目的目录、代码以及终端,如下图。
由于咱们本次的目的是解析源码,咱们首要将在这上面展现和阅览代码,并不会履行它。
现在,咱们能够开端解析源码了。
进口文件
解析源码的一个比较好的手法是找到进口文件(Entry File),适当于是一本书的导言(Introduction)章节,项目的全体结构一般会在进口文件中体现出来。
咱们从项目介绍 README.md 文件中能够看到,这个守时使命库的使用办法是 cron.New(cron.WithSeconds()) 之类的,也便是 cron.New 办法。因而,咱们能够猜想这个办法是在 cron.go 中,咱们翻开它看一看。
快速扫了一遍之后,咱们能够发现这个 New 办法在 113 行,如下图。
仔细看一下,这个办法便是回来了一个 Cron 类的实例指针,中心的 opts ...Option 参数是一种函数式参数(Functional Option)。而实际的代码实现,无非便是结构了一个 Cron 类的实例指针 c,并对其应用了函数参数,然后回来它。
这样,咱们能够判别,真实的守时使命中心逻辑就在 Cron 类中。
不过,无论如何,咱们能够确认,进口文件便是 cron.go。接下来只需求剖析这个文件包含的中心模块、逻辑就能够大概理清楚整个项目的源码了。
中心类
那么咱们再来看一下中心类 Cron 的结构,看看是否有什么新东西。
在代码中查找一下能够定位到 Cron 类在第 13 行。
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 言语开发工程师应该会注意到,这是一个典型的原子性操作(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 游戏时不断寻找机关,最终在含辛茹苦之下可喜可贺进入下一关?
总结
等一下,就这么结束撒花了?我那啥都预备好了,你就让我看这个?
咱们在这里暂时打住的首要原因是不想让这篇文章变得又臭又长。由于源码解析一般是一个需求耐性、繁琐单调的进程,而这种进程有时会让读者产生抵触情绪。因而,笔者的首要目的是抛砖引玉,将源码解析的一些中心方法用手把手的办法告诉读者,而读者也会根据自己的理解去实际操作,这样学习起来会更快也会更有意思。
现在稍微总结一下这篇文章用到的解析源码技巧:
- 找到进口文件
- 定位中心类
- 解析进口办法
社区
如果您对笔者的文章感兴趣,能够加笔者微信 tikazyq1 并注明 “码之道”,笔者会将你拉入 “码之道” 交流群。






