In Go
I can write such code for creating a gorouting that sleeps 5
sec.
func sleep(link chan interface{}){
time.Sleep(5 * time.Second)
fmt.Println("I've slept for 5 sec")
link <- struct {}{}
}
func main() {
var link = make(chan interface{})
go sleep(link)
time.Sleep(1 * time.Second)
// here I want to change the remaining sleeping time of `sleep` goroutine to 0.5 sec
<- link
}
What if in main
function I change my mind and decide that the sleeper should sleep not 5
sec but 3
. How can it done if goroutine already started to sleep (and sleeping, for example, for 1
sec)?
UPDATE
I mean is there something whereby I can manage that unique goroutine while it sleeps. Like giving commands to it about decreasing or increasing time of sleep:
func main() {
// ...
time.Sleep(1)
something.ManageRemainingTime(10)
time.Sleep(5)
something.ManageRemainingTime(100)
time.Sleep(8)
something.ManageRemainingTime(0.5)
// ...
}
If you just need a way to "wakeup" a sleeping goroutine, you could use sync.Once
to ensure your function only gets called once, and then return a channel so you can set a sooner "trigger time", so something this:
func sleep(callback func(), seconds int) chan int {
once := sync.Once{}
wakeup := make(chan int)
go func() {
for sleep := range wakeup {
go func() {
time.Sleep(time.Duration(sleep) * time.Second)
once.Do(callback)
}()
}
}()
wakeup <- seconds
return wakeup
}
func main() {
wg := sync.WaitGroup{}
wg.Add(1)
t := time.Now()
wakeup := sleep(func() {
fmt.Println("Hello, playground")
wg.Done()
}, 5)
wakeup <- 2
wg.Wait()
fmt.Println(time.Since(t))
}