How to pass output from select { } to outside of select { } as global scope?


(Parker Jun) #1

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?


(Boban Acimovic) #2

Here you shadowed ret defined above, this should be:

case ret = <-ch:


(system) #3

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