Sobes.tech
Junior — Senior

Detection and elimination of goroutine leaks in Go applications

livecode

Task condition

In this code fragment, there is a potential issue related to goroutine management and possible resource leaks. It is necessary to analyze the program, identify its weaknesses, and propose a correct solution.

package main

import (
  "fmt"
  "runtime"
  "time"
)

func main() {
  for i := 0; i < 100; i++ {
    requestData(1)
  }

  time.Sleep(time.Second * 1)
  fmt.Printf("Number of hanging goroutines: %d\n", runtime.NumGoroutine())
}

func requestData(timeout time.Duration) string {
  dataChan := make(chan string)

  go func() {
    dataChan <- requestFromSlowServer()
  }()

  select {
  case result := <-dataChan:
    fmt.Printf("[+] request returned: %s\n", result)
    return result
  case <-time.After(timeout):
    fmt.Println("[!!] request timeout!")
    return ""
  }
}

func requestFromSlowServer() string {
  time.Sleep(time.Second * 1)
  return "very important data"
}

The task is to understand why 'hanging' goroutines remain after the loop ends and to suggest code modifications that ensure the correct termination of all launched processes regardless of timeouts.