I guess you had same challenge in your projects, hadn’t you?
With my team, we have faced this problem during the development of our previous project. As application started to grow, some parts of it required continuous execution with certain predefined intervals and we decided to develop a library that would help us schedule such types of tasks in an elegant manner.
You can find it here.
Let’s dive into it!
This library is pretty simple with only 50 lines of code. The main idea behind it is to collect context cancel functions for each and every added job (to cancel them in balk when needed) and start a goroutine that will execute that job by every time.Ticker tick with a provided time interval.
Here is a Scheduler structure that has Add() and Stop() methods. It consists
of sync.WaitGroup and slice of context.CancelFunc. WaitGroup is used to stop all running jobs gracefully at the application shutdown.
Here is how Add() and Stop() methods behave. As you can see the Stop() method waits for all the running goroutines to be finished using wg.Wait() call.
Job is a defined type which is just a simple func(ctx context.Context).
When the job is added with a defined interval, we run a goroutine that listens for ticker.C and ctx.Done() channels.
So that’s it. Really simple :)
See it in actionImagine that we have a monolith application that has a lot of different parts to it. There is a module that has to constantly collect some frequently updated subscription data from a payment provider every N minutes and another module has to send calculated statistics to an analytic server every M minutes. This will look like this:
And don’t forget to call the Stop() method at application shutdown to finish gracefully.
Feel free to use the scheduler in your Go projects and improve it with your pull requests!