[Golang] Implementing Timeout Feature in Golang for Efficient Task Processing and Error Handling

Golang timeout feature - Illustration depicting a clock and a task symbolizing the implementation of a timeout feature in Golang

Let’s dive into an exciting scenario to explore how we can jazz up our Golang code with a cool timeout feature!

Imagine this: you’re building an awesome application and you want to delegate a task to a third-party API. But here’s the catch - the processing time for this task is unpredictable. To add some spice to the mix, you decide to set a timeout for the task. If the third-party API takes too long and doesn’t return the result within the timeout, we’ll label it as error and move on, regardless of whether it eventually responds or not. We’re all about efficiency here! However, if the API does manage to return the result within the timeout, we’ll update the task status accordingly.

So, let’s get cracking and learn how to implement this nifty timeout feature in Golang!

package main

import (
	"fmt"
	"sync"
	"time"
)

type Task struct {
	ID     int
	Status string
}

func main() {
	tasks := []Task{
		{ID: 1, Status: "pending"},
		{ID: 2, Status: "pending"},
		{ID: 3, Status: "pending"},
	}

	timerMap := make(map[*Task]*time.Timer)
	var mutex sync.Mutex

	for i := range tasks {
		task := &tasks[i]
		
		// Simulate an API request to third-party API
		...

		// Create a timer for this task
		timer := time.AfterFunc(time.Second*60, func() {
			// Timer expired
			// Lock the mutex to avoid race conditions
			mutex.Lock()
			defer mutex.Unlock()

			// Check if the task is still pending
			if task.Status == "pending" {
				task.Status = "error"
				fmt.Printf("Task %d timed out\n", task.ID)
			}
		})

		// Store the timer in the map
		mutex.Lock()
		timerMap[task] = timer
		mutex.Unlock()

	}

	// Simulate third-party API return the result via webhook
	...

	time.Sleep(time.Second * 30)
	task := &tasks[0]
	task.Status = "success"
	mutex.Lock()
	timer, ok := timerMap[task]
	if ok {
		timer.Stop()
		delete(timerMap, task)
		fmt.Printf("Timer for task %d cancelled\n", task.ID)
	}
	mutex.Unlock()

	...
}

Line 27: You will send the task definition to the third-party API.
Line 30: Meanwhile, you start a timer for the task wtiht a timeout of 60 seconds.
Line 38: If the task is still pending after 60 seconds, you will update the task status to error.
line 44-46: To avoid race conditions, we use a mutex to synchronize access to the timerMap and the tasks in the tasks array.
line 50: Simulate if the API returns the result within 30 seconds.
line 60: After the third-party API call is made to update a task’s status before the timer expires, we cancel the timer for that task.


If this post helped you to solve a problem or provided you with new insights, please upvote it and share your experience in the comments below. Your comments can help others who may be facing similar challenges. Thank you!
Buy Me A Coffee
DigitalOcean Referral Badge
Sign up to get $200, 60-day account credit !