Search code examples
multithreadinggodaemonbackground-processgoroutine

Golang daemon with goroutines won't stop executing


I've created a daemon that has the goal to consume queues in parallel. To test if it keeps executing in the background I've implemented a function that creates a file every 10 seconds until it reaches X, where X is the highest number of processes that I configured for the queues. The parameters for the queues are defined on the config.yaml file.

The problem now is that even though I stop and remove the daemon, it seems that the program keeps running and creating files... I've tried building and running the program again, exiting it, ending the processes, deleting the files, but nothing seems to work, files keep being created on the program directory.

You can check the program code here, and the config file here. Do you have any idea how I can solve this problem? Thanks in advance!


Solution

  • This code will never exit until it does processing for len(queues) times. It is not a concurrent code - all in main body - and there is no signal to tell the code to stop. The problem is here:

    case "run":
        // Installing the service
        installed, err := service.Install()
        logError(err, installed)
        // Starting the service
        started, err := service.Start()
        logError(err, started)
        if err == nil {
            // Creating a goroutine and executing the queue's processes in parallel
            for i := 0; i < len(queues); i++ {
                go startProcessing(queues[i])
                time.Sleep(time.Second) // Waiting for other functions to execute
            }
            select {} // To prevent the goroutine from exiting the main func
        }
        fmt.Println(started)
    

    As it can be seen the select{} line will sit there and run for ever! :) It is better to move this case clauses, into their's own goroutines and have a quit signal there like this:

    select {
        case <-quit:
            return
    }
    

    Though this is not the cleanest way to handle start/stop in Go apps; it just shows the problem.