DEV Community

Cover image for Solving simple time based problems with go lang.
Silva Chijioke Michael
Silva Chijioke Michael

Posted on

Solving simple time based problems with go lang.

so interestingly i was assigned a task i really enjoyed, this had to do with repeatedly looping over a set of documents in the db, making some transactions and finally updating documents based on certain conditions.
The first idea was to use a Cron Job(well obviously) everyone knows what a cron job does, but interestingly the problem was to be solved using Go Lang which is one of our stacks on my current team.

I shared the problem with the backend team and we discussed different methods to approach the problem and at the end of the day it boiled down to setting up a cron job that runs repeatedly at โ€œx timeโ€ or using the Go timer package.

I used the go timer package and i used it mainly for two reasons:

  1. Ease of use: it was already pre-installed, easy to use and provides a plethora of methods and properties that could be used to solve basically all the problems presented on a low level (it gives total control)

  2. Less complexity: I was already using go lang, there was no real need to install a separate package to over engineer a somewhat simple problem.

Hereโ€™s a simple snippet of how to solve the same type of problem:

  1. We define our timed funtion for this example we'll be using the go MongoDB and mux router
// assuming we want the function to run at 12am daily
func initTimer(conn *db.MongoDB, router *mux.Router) {
    currentTime := time.Now()

    // Calculate the duration until 12 AM
    desiredTime := time.Date(currentTime.Year(), currentTime.Month(), currentTime.Day(), 0, 0, 0, 0, currentTime.Location())
    if desiredTime.Before(currentTime) {
        // If 12AM has already passed today, schedule it for 12AM tomorrow
        desiredTime = desiredTime.Add(24 * time.Hour)
    }

    // Calculate the duration until the 12AM
    duration := desiredTime.Sub(currentTime)

    // Wait until it's time to execute the function
    <-time.After(duration)
    go ourTransaction(conn, router)
}

func ourTransaction(conn *db.MongoDB, router *mux.Router) {
   entity := pkg.InitTrxn(conn, router) //init package


    //initial transaction to counter build during updates (optional)
    go entity.RunTrxn()

    // re-run this function every 24hrs by setting up a new ticker using the "time.NewTicker" function
    var ticker *time.Ticker = time.NewTicker(24 * time.Hour)

    //repeat actions at intervals using the "ticker.C" field
    for tickTime := range ticker.C {
        go entity.RunTrxn() // a resource intensive function
        log.Println("i'm running at time:", tickTime)
    }
}
Enter fullscreen mode Exit fullscreen mode
  • We initialize the timed functions in our main.go package
func main(){
// initialize 
    go initTimer(dbConn, router) // run on a separate thread 
}
Enter fullscreen mode Exit fullscreen mode
  • In my case the the transaction needed me to make an update base on last action time (..actally i just want to show more stuff done with the go timer package ๐Ÿ˜).
package packageName

func (t trxnStruct) RunTrxn() {
       items, err := t.GetAllItems()
       if err != nil{
          log.Panicf("Error at getting items %s", err)
          }

       for _, item := range items {

       // get time difference between last transaction time  and current time using the "time.since" function
         timeDifferenceSinceLastTrxn = time.Since(item.LastTransactionTime)

        inActiveDays := int(timeDifferenceSinceLastTrxn.Hours() / 24) //convert to days
        item.InActiveDays = inActiveDays
         maxdaysofInactivity := 10 

        if item.InActiveDays > maxdaysofInactivity{
           item.Status = constants.INACTIVE 
          }

        t.UpdateItem(item.ID, item) // repo funtion to update DB Record

      }
   return
}
Enter fullscreen mode Exit fullscreen mode

In conclusion, the go timer package is a robust and yet easy to use package with a lot of useful tools to help solve your time based based problems. you can find more info from the docs [https://pkg.go.dev/time]

Top comments (0)