引子
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 并注明 “码之道”,笔者会将你拉入 “码之道” 交流群。