Golang Cron Job Example

Introduction

Automating tasks is a crucial aspect of software development, and cron jobs are a popular way to schedule these tasks. In this tutorial, we’ll show you how to create and manage cron jobs in Golang using the robfig/cron package. We’ll cover everything from installation to running your first scheduled task, along with best practices to ensure your cron jobs run efficiently.

Difference between system cron job and Golang cron job

Aspect
System Cron Job
Golang Cron Job
Where
Managed by the operating system.
Managed within a Golang application.
Setup
Configured using system files like crontab on Unix/Linux.
Configured in your Go code using libraries like 'go-coop/gocron' or 'robfig' package.
Language
Can run scripts or commands in any language (e.g., Shell, Python or Golang).
Written in Go.
Scope
Can perform system-wide tasks (e.g., backups, updates).
Performs tasks specific to the application (e.g., data processing).
Management
Controlled via system-level tools and configuration.
Controlled within the application’s codebase.

In this blog we will learn to create the cron job in the Golang using the robfig package:

Golang cron job example using function call

Copy the following program in your main.go file,

package main

import (
   "fmt"
   "github.com/robfig/cron"
)

func main() {
   fmt.Println("Cron Job Example")

   // Create a new cron job instance
   c := cron.New()

   // Add the cron schedule and task to the cron job
   c.AddFunc("@every 00h00m10s", GuestGreeting)

   // Start the cron job scheduler
   c.Start()

   // Keep the main program running
   select {}
}

func GuestGreeting() {
   fmt.Println("Message after 10 seconds")
}

open the main.go directory in the terminal, and run the following command sequentially to import the packages

go mod init
go mod tidy

To run the program , please run the following command

go run main.go

Explanation :
The program imports two packages:

  • fmt: For printing output to the console.
  • github.com/robfig/cron: A package to create and manage cron jobs in Go.

Main function

  • fmt.Println(“Cron Job Example”): Prints a message to the console.
  • c := cron.New(): Creates a new instance of a cron job scheduler.
  • c.AddFunc(“@every 00h00m10s”, GuestGreeting): Schedules the GuestGreeting function to run every 10 seconds. The schedule format @every 00h00m10s specifies this interval.
  • c.Start(): Starts the cron job scheduler, which begins executing scheduled tasks.
  • select {}: Keeps the main program running indefinitely. Without this, the program would exit immediately, stopping the cron job scheduler.

GuestGreeting Function:

  • This function simply prints “Message after every 10 seconds” to the console. It is the task that gets executed every 10 seconds by the cron job scheduler.

Summary

  • The program creates a cron job that runs a specific task GuestGreeting() every 10 seconds.
  • The task is to print a greeting message to the console.
  • The program keeps running indefinitely to allow the cron job to execute as scheduled.

Golang cron job example using net/http package

Copy the following program in your main.go file,

package main

import (
   "fmt"
   "io"
   "net/http"
   "time"

   "github.com/robfig/cron"
)

func main() {
   // Initialize the cron scheduler
   c := InitCronScheduler()

   // Defer the stop of the cron scheduler to ensure it stops when main function exits
   defer c.Stop()

   // Start the HTTP server
   StartServer()
}

// InitCronScheduler initializes and starts the cron scheduler
func InitCronScheduler() *cron.Cron {
   // Create a new cron instance
   c := cron.New()

   // Add a cron job that runs every 10 seconds
   c.AddFunc("@every 00h00m10s", BackUpLocalDataCall)

   // Start the cron scheduler
   c.Start()
   fmt.Println("Cron scheduler initialized")
   return c
}

// BackUpLocalDataCall is the function to be executed by the cron job
func BackUpLocalDataCall() {
   resp, err := http.Get("http://localhost:8080")
   if err != nil {
       fmt.Println("Error while calling the API:", err)
       return
   }
   defer resp.Body.Close()

   body, err := io.ReadAll(resp.Body)
   if err != nil {
       fmt.Println("Error reading the response body:", err)
       return
   }

   fmt.Println(string(body))
}

// StartServer starts the HTTP server on port 8080
func StartServer() {
   // Set up HTTP server routes
   http.HandleFunc("/", BackUpLocalData)

   // Start the HTTP server on port 8080
   fmt.Println("Starting server on :8080")
   if err := http.ListenAndServe(":8080", nil); err != nil {
       fmt.Println("Error starting server:", err)
   }
}

// BackUpLocalData handles HTTP requests and performs a backup
func BackUpLocalData(w http.ResponseWriter, r *http.Request) {
   fmt.Fprintf(w, "calling the API after every 10 seconds at %s", time.Now().Format("2006-01-02 15:04:05"))
}

open the main.go directory in the terminal, and run the following command sequentially to import the packages

go mod init
go mod tidy

To run the program , please run the following command

go run main.go

Explanation :

The program makes use of various Packages, including the following:

  • fmt: Used for formatted printing.
  • io: Used for reading the response body.
  • net/http: Used for managing HTTP requests and responses.
  • time: Used for functions related to time.
  • github.com/robfig/cron: Used for scheduling cron jobs.

Main Function

  • The main function serves as the starting point of the program.
  • InitCronScheduler is invoked to set up and initiate the cron scheduler.
  • A deferred function defer c.Stop() is used to ensure that the cron scheduler halts when the main function concludes.
  • StartServer is invoked to initiate the HTTP server.

InitCronScheduler Function

  • InitCronScheduler initializes and starts the cron scheduler.
  • A new cron instance is created with cron.New().
  • A cron job is added with c.AddFunc(“@every 00h00m10s”, BackUpLocalDataCall) to run the BackUpLocalDataCall function every second.
  • The cron scheduler is started with c.Start().
  • A message is printed to indicate that the cron scheduler is initialized.
  • The cron instance is returned.

BackUpLocalDataCall Function

  • BackUpLocalDataCall is the function executed by the cron job.
  • An HTTP GET request is made to http://localhost:8080 using http.Get.
  • If an error occurs, it is printed, and the function returns.
  • The response body is read with ioutil.ReadAll.
  • If an error occurs while reading the response body, it is printed, and the function returns.
  • The response body is printed as a string.

StartServer Function

  • The StartServer Function initiates the HTTP server on port 8080.
  • Requests to the / route are managed by the BackUpLocalData function using http.HandleFunc.
  • The server is launched using http.ListenAndServe(“:8080”, nil).
  • Any errors that occur during server startup are printed.

BackUpLocalData Function

  • The BackUpLocalData Function handles HTTP requests made to the root path.
  • It responds with a message displaying the current time using fmt.Fprintf.
  • The current time is formatted in a specific layout using time.Now().Format(“2006-01-02 15:04:05”).

Summary

  • To display the time of the backup, the program establishes an HTTP server on port 8080 that responds with a message.
  • The cron scheduler, initialized within the program, sends an HTTP GET request to this server endpoint every ten seconds.
  • Both the server and the cron scheduler operate concurrently, with the scheduler regularly initiating requests to the server.

In the examples provided above, you’ve seen how cron jobs operate. One might question how to set a cron expression format to schedule tasks at specific intervals or times.


How to set cron syntax ?
The cron expression format used in the robfig cron package (also known as “cron syntax”) allows scheduling tasks based on time and date. Here’s an updated explanation of the format:
A cron expression consists of mandatory five space separated fields representing different time units in orderly manner :
Cron expression format :

Minute (0 - 59)
Hour (0 - 23)
Day of the month (1 - 31)
Month (1 - 12 or JAN - DEC)
Day of the week (0 - 7 or SUN - SAT)
  1. The minute parameter specifies the minute of the hour for the task to run, ranging from 0 to 59.

  2. The hour parameter specifies the hour of the day for the task to run, ranging from 0 to 23.
  3. The day of the month parameter specifies the day of the month for the task to run, ranging from 1
    to 31.
  4. The month parameter specifies the month of the year for the task to run, ranging from 1 to 12, or using the abbreviations JAN to DEC.
  5. The day of the week parameter specifies the day of the week for the task to run, ranging from 0 to 7, with 0 and 7 representing Sunday.

Field Overview

Field Name
Mandatory ?
Allowed Values
Allowed Special Characters
Minutes
Yes
0-59
* / , -
Hours
Yes
0-23
* / , -
Day of Month
Yes
1-31
* / , - ?
Month
Yes
1-12 or JAN-DEC
* / , -
Day of Week
Yes
0-6 or SUN-SAT
* / , - ?

 

Special Characters Overview

Character
Description
Example
Meaning
*
An asterisk denotes that the cron expression will correspond to all potential values for that field.
* * * * *
scheduled job will run every minute.
/
The use of a slash indicates the incremental ranges, often presented in the format START-END/. In this format, START represents the initial value, and END denotes the maximum value for that particular field. It is used to define increments or intervals.
0-30/15 in the minutes field
The slash (/) in a cron syntax defines increments, such as 0-30/15 in the minutes field, which means every 15 minutes starting from the 0th minute.
,
Items in a list are separated by a comma.
1,3,5 are the day of the week
The comma (,) in a cron expression specifies a list of values, such as 1,3,5 in the day of the week field, meaning the job will run on Mondays, Wednesdays, and Fridays
-
Ranges are defined by hyphens.
8-18 in the hours field
The hyphen (-) in a cron syntax specifies a range, such as 8-18 in the hours field, meaning the job will run every hour between 8 AM and 6 PM inclusive.
?
Question mark can be used instead of * for leaving either day-of-month or day-of-week blank.
15 14 ? 1 MON
Job will run at 2:15 PM every Monday in January, ignoring the specific day of the month.

 

Here are the commonly used cron expression formats:

Expression
Description
0 * * * *
Every 00 minutes
0 0 * * *
Every day at midnight i.e. 00:00:00 AM
0 0 1 * *
Every month on the 1st at midnight
0 0 1 1 *
Every year on January 1st at midnight 00:00:00 AM
0 12 1 * *
At noon on the 1st of every month
0 12 * * *
Every day at noon
15 10 * * *
Every day at 10:15 AM
0 10 1 * *
At 10 AM on the 1st of every month ​
0 10 1 1 *
At 10 AM on January 1st every year
0 0 * * 1-5
Every weekday at midnight (Monday through Friday) i.e. 00:00:00 AM
0 0 1,15 * *
At midnight on the 1st day and 15th day of every month
*/15 * * * *
Every 15th minute (0, 15, 30, 45)
0 0 1-7 * *
At midnight on the 1st through 7th of every month
0 12 1 1,4,7,10 *
At noon on the 1st day of every 3rd month (January, April, July, October)
0 12 * * 2,4,6
At noon on every Tuesday, Thursday, and Saturday
0 12,13,14 * * *
Every day at noon, 1 PM, and 2 PM
*/30 8-18 * * *
Every 30 minutes between 8 AM and 6 PM
@yearly (or @annually)
Every year on January 1st at midnight 00:00:00 AM
@monthly
Every month on the 1st at midnight ​
@weekly
Every week at 00:00:00 AM on Sunday
@daily
Every day at 00:00:00 AM
@hourly
Every hour at 00 minute i.e. 17:00:00 PM , 18:00:00 PM
@every 1h30m10s
Every 1 hour 30 minutes and 10 seconds

For more detailed information, you can refer to the official documentation of the robfig package

 

Best Practices

  • When dealing with long-running tasks, utilize goroutines and context to prevent blocking the main function.
  • Implement monitoring to receive alerts in case of a cron job failure.
  • Enable graceful shutdown of your application by stopping the cron scheduler.