I. Getting started with Golang Ticker
In this tutorial, we are going through tickers in Go and how you can use them effectively within your own Go applications.
Tickers are used to repeat an action at regular intervals. It is comparable to setting the alarm clock to ring at 7:00 am every day. If we want to run tasks in the background without breaking the flow of the application, we can use tickers with goroutines
.
To create a new Ticker, we use Tick()
or NewTicker()
function which takes a time period as an argument. Tick is a convenience wrapper for NewTicker providing access to the ticking channel only. While Tick is useful for clients that have no need to shut down the Ticker, be aware that without a way to shut it down the underlying Ticker cannot be recovered by the garbage collector; it "leaks".
For this reason, in this tutorial, we will use NewTicker()
function to create a new ticker and Stop()
function when the ticker is no longer used. The result of the NewTicker
function is a pointer to a Ticker struct, which defines the field and methods described in below Table:
Name | Description |
---|---|
c |
This field returns the channel over which the Ticker  will send its Time  values. |
Stop() |
This method stops the ticker (but does not close the channel returned by the c  field). |
Reset(duration) |
This method stops a ticker and resets it so that its interval is the specified Duration . |
The general syntax would be NewTicker(duration)
where the function returns a *Ticker
with the specified period.
II. Examples
1. Example 1: Create a simple ticker to run indefinitely
The following example demonstrates how we can use a ticker in Golang. Here's an example of using a ticker to call a function every 2 seconds. Consider the code shown below.
package main
import (
"fmt"
"time"
)
func main() {
fmt.Println("Start Ticker Example 1")
// define an interval and the ticker for this interval
interval := time.Duration(2) * time.Second
// create a new Ticker
tk := time.NewTicker(interval)
// start the ticker by constructing a loop
i := 0
for range tk.C {
i++
countFuncCall(i)
}
}
// define the function
func countFuncCall(i int) {
fmt.Println("Function is called: ", i, "times")
}
Output: If we run the above code with the command go run main.go then we will get the following output:
Start Ticker Example 1
Function is called:Â 1 times
Function is called:Â 2 times
Function is called:Â 3 times
Function is called:Â 4 times
Function is called:Â 5 times
Function is called:Â 6 times
Function is called:Â 7 times
…..
The program will run indefinitely. We can stop the program by pressing CTRL+C.Â
In this example, we can exit the loop by using ‘break
’ statement. We will break the loop when the function is called 5 times. Consider the code shown below
i := 0
for range tk.C {
i++
countFuncCall(i)
if i > 4 {
break
}
}
Output:
Start Ticker Example 1
Function is called:Â 1 times
Function is called:Â 2 times
Function is called:Â 3 times
Function is called:Â 4 times
Function is called:Â 5 times
2. Example 2: Stop a ticker using Ticker.Stop()
We can stop the ticker by Ticker.Stop()
function. The Stop()
function in Go language is used to disable a ticker, after calling Stop()
method no further ticks will be transmitted.
package main
import (
"fmt"
"time"
)
func main() {
ticker := time.NewTicker(2 * time.Second)
// Creating channel using make
tickerChan := make(chan bool)
go func() {
// Using for loop
for {
// Select statement
select {
// Case statement
case <-tickerChan:
return
// Case to print current time
case tm := <-ticker.C:
fmt.Println("The Current time is: ", tm)
}
}
}()
// Calling Sleep() method
time.Sleep(7 * time.Second)
// Calling Stop() method
ticker.Stop()
// Setting the value of channel
tickerChan <- true
// Printed when the ticker is turned off
fmt.Println("Ticker is turned off!")
}
Output:
The Current time is:Â 2022-09-11 21:42:57.3287283 +0700 +07 m=+2.011840401
The Current time is:Â 2022-09-11 21:42:59.3279005 +0700 +07 m=+4.011012601
The Current time is:Â 2022-09-11 21:43:01.3249886 +0700 +07 m=+6.008100701
Ticker is turned off!
Explanation: Firstly, a Ticker is created, then a channel is created that transmits time. After that, a loop is used in order to print the current time, then the Ticker.Stop()
method is called and the ticker is turned off. Once a ticker is stopped it won’t receive any more values on its channel.
3. Example 3: Using golang ticker with goroutines
We can also run the ticker in the background with the help of goroutines. Consider the code shown below
package main
import (
"fmt"
"time"
)
func inBackground() {
ticker := time.NewTicker(1 * time.Second)
for _ = range ticker.C {
fmt.Println("Ticking..")
}
}
func main() {
fmt.Println("Starting the ticker")
// create a goroutine to run the ticker
go inBackground()
fmt.Println("After goroutine..")
select {}
}
Output: If we run the above code with the command go run main.go then we will get the following output.
Starting the ticker
After goroutine..
Ticking..
Ticking..
…
It should be noted that if we do not break the loop, the program will continue to run until we forcefully stop it. We can stop it by pressing CTRL+C.
4. Example 4: Running multiple tickers in parallel
Here, we will implement two tickers using time.NewTicker()
function. Here we will get the notification every second and 500 milliseconds.
package main
import (
"log"
"time"
)
func main() {
MyTicker1 := time.NewTicker(500 * time.Millisecond)
MyTicker2 := time.NewTicker(1 * time.Second)
go func() {
for {
<-MyTicker1.C
log.Println("Tick Received for 500 millisecond")
}
}()
go func() {
for {
<-MyTicker2.C
log.Println("Tick Received 1 second")
}
}()
time.Sleep(6 * time.Second)
log.Println("Main finished")
select {}
}
Output:
2022/09/11 21:49:09 Tick Received for 500 millisecond
2022/09/11 21:49:10 Tick Received 1 second
2022/09/11 21:49:10 Tick Received for 500 millisecond
2022/09/11 21:49:10 Tick Received for 500 millisecond
2022/09/11 21:49:11 Tick Received 1 second
2022/09/11 21:49:11 Tick Received for 500 millisecond
2022/09/11 21:49:11 Tick Received for 500 millisecond
2022/09/11 21:49:12 Tick Received 1 second
2022/09/11 21:49:12 Tick Received for 500 millisecond
2022/09/11 21:49:12 Tick Received for 500 millisecond
2022/09/11 21:49:13 Tick Received 1 second
2022/09/11 21:49:13 Tick Received for 500 millisecond
2022/09/11 21:49:13 Tick Received for 500 millisecond
2022/09/11 21:49:14 Tick Received 1 second
2022/09/11 21:49:14 Tick Received for 500 millisecond
2022/09/11 21:49:14 Tick Received for 500 millisecond
2022/09/11 21:49:15 Main finished
2022/09/11 21:49:15 Tick Received for 500 millisecond
2022/09/11 21:49:15 Tick Received 1 second
2022/09/11 21:49:15 Tick Received for 500 millisecond
2022/09/11 21:49:16 Tick Received 1 second
2022/09/11 21:49:16 Tick Received for 500 millisecond
2022/09/11 21:49:16 Tick Received for 500 millisecond
…
Explanation: In the main()
function, we created two ticker MyTicker1, MyTicker2 using time.NewTicker()
function for 500ms and 1 second. Then we got the notification every 500ms and 1 second and then printed the "Main finished" message with a timestamp on the console screen. Because we use ‘select
’ statement, the tickers will not be stopped and the program run infinitely. If we removed that statement, the output will be:
2022/09/11 21:57:36 Tick Received 1 second
2022/09/11 21:57:36 Tick Received for 500 millisecond
2022/09/11 21:57:36 Tick Received for 500 millisecond
2022/09/11 21:57:37 Tick Received 1 second
2022/09/11 21:57:37 Tick Received for 500 millisecond
2022/09/11 21:57:37 Tick Received for 500 millisecond
2022/09/11 21:57:38 Tick Received 1 second
2022/09/11 21:57:38 Tick Received for 500 millisecond
2022/09/11 21:57:38 Tick Received for 500 millisecond
2022/09/11 21:57:39 Tick Received for 500 millisecond
2022/09/11 21:57:39 Tick Received 1 second
2022/09/11 21:57:39 Tick Received for 500 millisecond
2022/09/11 21:57:40 Tick Received for 500 millisecond
2022/09/11 21:57:40 Tick Received 1 second
2022/09/11 21:57:40 Tick Received for 500 millisecond
2022/09/11 21:57:41 Main finished
III. Comparison of Timer Vs Ticker
Timers and tickers both create a receive-only channel.
Timers are for when you want to do something once in the future. It means Timers are used for one-off tasks. It represents a single event in the future. Timers can be used in a loop with a select statement, instead of using default, in order to reduce the frequency of the selection and lower the CPU usage of the application when it is idle.
Tickers are for when you want to do something repeatedly at regular intervals. We can use tickers, in combination with goroutines to run these tasks in the background of our applications while one practical usage is a rate limiter, which limits the number of executions over a set period of time in a certain segment of an application.
IV. Summary
There are often cases where we would want to perform a particular task after a specific interval of time repeatedly. In Golang, we achieve this with the help of tickers. Go’s the built-in ticker features make this task easy. We can use these implementations in a much-controlled way. You can access Go ticker official documents (https://pkg.go.dev/time#NewTicker
) to know more about this package.
V. References
https://pkg.go.dev/time#NewTicker