Hello.
I have a major problem with select { }. I must use select { } as a need a forced timeout in most of my functions. And the only way to make with asynchronous parts of code is to use select { }. But the problem is that i simply can not pass anything at all outside of select { }. It is like a black hole, holds everything inside of select { }, but once select { } is finished, variables are gone / not changed.
I Can not pass string variable outside of select { }.
Case (simplified):
Synchronous script which uses select { } with two options
First one is timeout (3 seconds)
Second one is default which is using channel to change value of a string.
When we check result of a string inside the select { } - it shows correctly.
But once we leave select { }, variable saved his old value, which were before select { }.
package main
import (
"log"
"time"
)
func main() {
timeout := time.After(3 * time.Second)
pollInt := time.Second
var ret string = "EMPTY"
OuterLoop:
for {
select {
case <-timeout:
log.Printf("[select][timeout] select timeout, break select and for loops")
break OuterLoop
default:
log.Printf("[select][default] Processing our actions")
ch := make(chan string, 1)
go func(ch chan string) {
var res string = "NOT EMPTY"
ch <- res
}(ch)
select {
case ret := <-ch:
log.Printf("channel has a result")
log.Printf("showing content of string AT THE SELECT: %v", ret)
case <-time.After(1 * time.Second):
log.Printf("timeout")
}
}
log.Printf("[for] Sleep for a second..")
time.Sleep(pollInt)
}
log.Printf("Starting to do some important actions.. (regardless was previous actions success or timeout)")
/* ... */
log.Printf("showing content of string: %v", ret)
if ret == "NOT EMPTY" {
log.Printf("SCRIPT FINISHED CORRECTLY")
} else {
log.Printf("SCRIPT FAILED")
}
}
Result of script run:
2009/11/10 23:00:00 [select][default] Processing our actions
2009/11/10 23:00:00 channel has a result
2009/11/10 23:00:00 showing content of string AT THE SELECT: NOT EMPTY
2009/11/10 23:00:00 [for] Sleep for a second…
2009/11/10 23:00:01 [select][default] Processing our actions
2009/11/10 23:00:01 channel has a result
2009/11/10 23:00:01 showing content of string AT THE SELECT: NOT EMPTY
2009/11/10 23:00:01 [for] Sleep for a second…
2009/11/10 23:00:02 [select][default] Processing our actions
2009/11/10 23:00:02 channel has a result
2009/11/10 23:00:02 showing content of string AT THE SELECT: NOT EMPTY
2009/11/10 23:00:02 [for] Sleep for a second…
2009/11/10 23:00:03 [select][timeout] select timeout, break select and for loops
2009/11/10 23:00:03 Starting to do some important actions… (regardless was previous actions success or timeout)
2009/11/10 23:00:03 showing content of string: EMPTY
2009/11/10 23:00:03 SCRIPT FAILED
But it need to be:
2009/11/10 23:00:00 [select][default] Processing our actions
2009/11/10 23:00:00 channel has a result
2009/11/10 23:00:00 showing content of string AT THE SELECT: NOT EMPTY
2009/11/10 23:00:00 [for] Sleep for a second…
2009/11/10 23:00:01 [select][default] Processing our actions
2009/11/10 23:00:01 channel has a result
2009/11/10 23:00:01 showing content of string AT THE SELECT: NOT EMPTY
2009/11/10 23:00:01 [for] Sleep for a second…
2009/11/10 23:00:02 [select][default] Processing our actions
2009/11/10 23:00:02 channel has a result
2009/11/10 23:00:02 showing content of string AT THE SELECT: NOT EMPTY
2009/11/10 23:00:02 [for] Sleep for a second…
2009/11/10 23:00:03 [select][timeout] select timeout, break select and for loops
2009/11/10 23:00:03 Starting to do some important actions… (regardless was previous actions success or timeout)
2009/11/10 23:00:03 showing content of string: NOT EMPTY
2009/11/10 23:00:03 SCRIPT FINISHED CORRECTLY
Playground: https://play.golang.org/p/uPKZtQQkm7p
Any idea?