Go Project Source Code Analysis: Schedule Job Library "cron"
Tags: go, opensource, github
Published: 2022-11-12 03:22:06

## Introduction

There are many excellent open-source projects on GitHub, where the code is transparent and available to everyone. As software developer, we can learn a lot from them including software engineering, unit testing, coding style standardization, etc. We can even find issues by looking into their code, and submit pull requests to contribute to tech communities. Today we are going to dig into the source code of a popular Golang open-source project on GitHub, [robfig/cron](https://github.com/robfig/cron), which is small and with clear annotations, and is very suitable for new developers to learn how to read and analyze source code.

## Environment Preparation

First, we are going to fork the project into our personal repo. We can do so by clicking the `Fork` button and enter the project name. After it's forked, we can either download to our local, or click `Create codespace on master` to create a **Codespace** on the GitHub repo's home page. Codespace is a Azure-based GitHub service that allows developers to develop remotely, and it is now available to individuals. Let's give it a try!

![Create Codespace](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bes1t5okfuv3qcsbbr54.jpeg)

After clicking, a new page will be opened in the browser, where there is a web interface of VS Code, displaying the directory, code and terminal of the project. See the figure below.

![Codespace](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0vv9bumq8nbl4gsf4udm.png)

As our objective is to analyze source code, we will use it to display code for reading, instead of executing it.

Now, we can start reading and analyzing.

## Entry File

A good way of analyzing source code is find the **entry file**, which is like a book's introduction, where the overall project structure will show up.

![Code Structure](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zcar22vs4b7pgwp35tjx.png)

We can find in `README.md` file that the usage of this library is something like `cron.New(cron.WithSeconds())`, or the method `cron.New`. Therefore, we reckon that this method is in the file `cron.go`. Let's open it and take a look.

A quick go-through can allow us to locate the `New` method at Line 113, as below.

![Method New](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/as3lg0i33ic2necf7sqo.jpeg)

If we take a close look, it is basically a pointer to the instance of the `Cron` struct. The parameters `opts ...Option` is called Functional Option. The actual implementation is to build an instance pointer `c` of the struct `Cron`, applied by functional options, and return it. 

With above analysis, we can conclude that the main logic is inside the `Cron` struct.

Regardless to say, we can be sure that the entry file is `cron.go`. What we can do next is analyze the core modules of this file to fully understand the source code.

## Core Struct/Class

Now let's take a look at the structure of the core struct `Core` to find some enlightenment. 

We can locate the struct `Cron` at Line 13. 

![Cron Struct](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4qz0sfkj093ktzqzq64n.jpeg)

There are quite many fields in the struct `Cron`, including the lower-case private attributes `entries`, `chain`, `parser`, but we can hardly know their actual meanings and functionalities. According to the comments at Line 10-12, we can deduct that it is used for tracking `entries` and executing functions defined by `schedule`. However, we are still not quite sure about what it does exactly, so only through reading the source code further, we can understand more details.

We can also find 3 interfaces just under beneath with their descriptions:

- `ScheduleParser`: parser of the schedule, which parses specs and returns `Schedule` instance.
- `Job`: submitted scheduled jobs.
- `Schedule`: used for describing running cycles of jobs.

In fact, these 3 interfaces are very important, given their locations in the source code.

## Entry Method

Before we explore further, let's recall the usage of the library apart from `cron.New`: it takes effect after calling `c.Start()`. Therefore, we need to dig into the `Start` method in `Cron`, which is actually the **entry method** of the core struct. 

We can locate the `Start` method at Line 215 in `cron.go` as below.

![Cron Start](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dz2zma8vjllw3v68k2da.jpeg)

An experienced Go developer could notice this is an atomic operation. `c.runningMu` is an instance of `sync.Mutex`, which can **lock** at the beginning, and **unlock** after the function execution finishes. This technique avoids data racing in the repeated calls of this method. `if c.running { return }` denotes that the method won't go further and return immediately if it's already started. `c.running` is set as `true`. The last line is an essential statement, `go c.run()`, meaning it starts a **goroutine** to asynchronously execute `c.run`. Now we have found the real core method, and the rest of the work is to analyze it through. 

Is it similar to we playing RPG games and unlocking all the milestones and entering the next episode?

## Conclusion

Wait! Is it over?

The reason why we stopped here is that I want to keep the article short. Reading and analyzing source code a **tedious and boring** process, which might prevent readers from going further. As a result, the objective of this article is to introduce the **right and basic techniques** of analyzing source code to readers, allowing you guys to do the analysis by yourselves. This way can make you learn faster and with more interest. 

Now let's summarize the techniques for analyzing source code:

1. Find the entry file
2. Locate the core struct/class
3. Analyze the entry method