⌛️ Manage time specified operations with Go in easy way.
Tags: go, time, programming, cronjob
Published: 2022-02-19 16:06:39

In programming we need specifying time for our code. Sometimes we wait until our crush end her relationship. Sometimes we wait until summer to change our job.

## Let's Start!
For doing thing with specified time I will show the basics in Go. In the first part we will look 2 simple code part. After we will discuss about how can we improve them and make it usable even production environment.

## Part 1 — Basics Of Time Specifying in Go
For time specifying we will use 2 basic technique. First one is for blocking current goroutine until specified time.

{% gist https://gist.github.com/yusufpapurcu/853dc145c743c556844479aecdab94c9
%}

In this example goroutine blocked for 5 second at 3rd line and continues after this. If you want waiting more time and doing more readable. You can use `time.Until()`. Here a basic example for this.

{% gist https://gist.github.com/yusufpapurcu/c8d5eb2e203a1cfb7826c4ea5192fa8a
%}

Second technique is blocking goroutine forever and make it cron engine. For doing this we have an excellent function called `time.Tick()`. This method takes duration and returns channel that triggers at every duration loop.

{% gist https://gist.github.com/yusufpapurcu/514386cda3e8a5acb3099002d2c4d18a
%}

If you don’t care about current time and just want to execute code continuously you can use this one. Also this way is more manageable and allow control flow with context or specific trigger channels.

{% gist https://gist.github.com/yusufpapurcu/a2d8d9500c1c0e3842db845c82c38fb9
%}

## Part 2 — Let’s Improve Them With Context Package

Context package is so useful. Because Context gives you a power of cancellation. You can cancel functions with it. If you are doing things with time, context is like Thor’s Mjölnir for you.

Key part of using context is based on `for { select{…} }` loop. Also you must use async for be able to use context. Because If your code flow don’t run, you can’t cancel the context.

Let’s do some examples. First we will implement a basic wait function with context. If context cancel called before timer end, function will exit without wait to timer end. In that case our program just wait 5 second instead of 5 minutes. That can annoy your goroutine :)

{% gist https://gist.github.com/yusufpapurcu/eed8c15284f28faace00636208666c8b
%}

For key point. We split our waiting routine and main routine. We must do that because if we didn’t do that we can’t call cancel function asynchronously.

Creating cron engine with context is basic than previous example. Just add `context.Done()` to the select statement.

{% gist https://gist.github.com/yusufpapurcu/5b7949ab9faaa0007dc90de0168c014e
%}

For a final example I want to add more complex, beautiful and useful cron engine example from [here](https://github.com/stephenafamo/kronika/blob/master/kronika.go#L9). I won’t add code to article. You can use link for this. Also this repository is a great implementation and my inspiration for writing this article.

- https://github.com/stephenafamo/kronika

I would like to hear all feedback’s about this article. Please feel free to give feedback. I want to hear all of good and bad feedbacks :)

I’m planning to expand this article some. If you have an idea what can I talk about at the feature of this article, I want to hear it.

**Inspired Articles**
- https://stephenafamo.com/blog/posts/better-scheduling-in-go

**Good Repositories**
- https://github.com/stephenafamo/kronika
- https://github.com/go-co-op/gocron
- https://github.com/gorhill/cronexpr