How to manage goroutine in case of webserver and longer running process

Issue is Mentioned on stackoverflow

I have a program that is rtsp cameras to hls format using ffmpeg for streaming. creating goroutines for each rtsp link as ffmpeg runs in background

Streams are added by following code.

func StreamProcess(data <-chan StreamData, ctx context.Context) {
for v := range data {
    ctx, _ := context.WithCancel(ctx)
    go func() {
        if !getStreams(v.camera_id) {
            var stream StreamState
            stream.camera_id = v.camera_id
            stream.state = true
            go Stream(v, ctx)
            wg.Wait()
        } else {
            return
        }
    }()
}   

}

Streaming function which runs ffmpeg command.

func Stream(meta StreamData, ctx context.Context) error {
    log.Println("Started Streaming")
    ffmpegCmd := exec.Command("ffmpeg", "-i", meta.rtsp, "-pix_fmt", "yuv420p", "-c:v", "libx264", "-preset", "ultrafast", "-b:v", "600k", "-c:a", "aac", "-b:a", "160k", "-f", "rtsp", fmt.Sprintf("rtsp://localhost:8554/%s", meta.camera_id))
    output, _ := ffmpegCmd.CombinedOutput()

    log.Println(string(output))

    for {
        select {
        case <-ctx.Done():
           log.Println("killing process")
           ffmpegCmd.Process.Kill()
           return nil
        }
    }}

my Goal is to stop each os.exec process (ffmpeg command) or at least close all goroutines that are under ffmpeg commands without closing fiber server.

Hi @Nitin_Kalmaste ,

I think there is an error in the StreamProcess: for each item in data you launch a new goroutine, and this goroutine checks if getStreams returns true or false and does something based on it. Look at what happens if getStream returns false for a given item - you create a new streamState variable, fill in its values, but then you do not make use of it, it is not being used anythere - most likely you need to use it for something.

Back to your question: when you close the context, each Stream goroutine will return because of case <-ctx.Done. If you want to close them without closing the context, simply add an extra chan parameter to the Stream method, and check if that channel is closed similar to how you check ctx.Done. The select will have then 2 cases, one is the ctx.Done and the other is the channel.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.