Thursday, May 16, 2024
HomeGolangGo routines with a versatile timeout - Getting Assist

Go routines with a versatile timeout – Getting Assist


Think about the state of affairs the place you could have a server that handler requests through a request handler (check with image). The handler (through its employees) can take a very long time, so that you want a timeout simply in case it by no means terminates. Requests that take a very long time are acceptable in our case, so long as any one of many employees is progressing. Nonetheless, the preliminary timeout that we set limits this. (I.e. is there a strategy to detect inactivity as an alternative of a relentless timeout?)

As an example, you could have 6 employees working beneath a context containing a timeout of 5 seconds. Employee n takes n seconds to finish (e.g. employee 3 takes 3 seconds to complete).
Since we’ve a timeout for five seconds, the sixth employee will timeout. So, my query is, can you modify this to refresh the timer at a later level throughout execution (e.g. when a employee completed or decides that it’s progressing)?

Seek advice from picture within the publish under

In concrete phrases, you may check out this program:

package deal principal

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

func principal() {
	fmt.Println("dealing with request")
	employees := 10

	var wg sync.WaitGroup
	wg.Add(employees)

	timeout := 5 * time.Second

	ctx, _ := context.WithTimeout(context.Background(), timeout)

	for i := 1; i <= employees; i++ {
		go employee(ctx, i, &wg)
	}

	wg.Wait()
	fmt.Println("All employees terminated")
}

// Employee will take index * time.Second to return
func employee(ctx context.Context, index int, wg *sync.WaitGroup) {
	defer wg.Carried out()
	// fmt.Println("Employee ", index, "ready for ", index, "seconds")

	choose {
	case <-ctx.Carried out():
		// Cancel employee
		fmt.Println("Employee ", index, "timed out")
		return
	case <-time.After(time.Period(index) * time.Second):
		// Course of completed after a while
		fmt.Println("Employee ", index, "completed")
	}
}

It outputs:

dealing with request
Employee  1 completed
Employee  2 completed
Employee  3 completed
Employee  4 completed
Employee  5 completed
Employee  6 timed out
All employees terminated

How can I permit employee 6 to complete, since it would nonetheless be inside the 5 seconds of the final inactive go routine.

I acquired a message on this line ;

ctx, _ := context.WithTimeout(context.Background(), timeout)

You might want to add a var to obtain the cancel perform so:
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()

And I have no idea whether it is doable on your isecase increment the numers of seconds to timeput, say for instance 10…

Context will not be designed the way in which you wish to use it. If I acquired your concept proper, you most likely can implement a heartbeat for employees and use it as a degree the place you outline, that they aren’t energetic anymore. Eg you could have a goroutine, which listens to the employees heartbeat and as quickly as considered one of them stops, it offers, 5 seconds for others to complete, if in these 5 seconds one other one has completed, then the timer counts one other 5 seconds and so forth. This mechanic will most likely clear up your problem, however it would require loads of extra work to do, since in case you nonetheless need your employees to timeout, you’ll have to cross their very own context and maintain someplace all of the cancel capabilities with the heartbeat channels.

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments