Created
September 5, 2011 17:57
-
-
Save jnwhiteh/1195562 to your computer and use it in GitHub Desktop.
Problem with channel receive
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package foo | |
import ( | |
"log" | |
) | |
// A simple server that will respond to request messages | |
type Server struct { | |
in chan m_req | |
out chan m_res | |
done chan bool | |
} | |
func NewServer() *Server { | |
server := &Server{ | |
make(chan m_req), | |
make(chan m_res), | |
make(chan bool), | |
} | |
go server.loop() | |
return server | |
} | |
func (s *Server) loop() { | |
var in <-chan m_req = s.in | |
var out chan<- m_res = s.out | |
// Get requests from 'in' and then respond accordingly on 'out' | |
for req := range in { | |
switch req := req.(type) { | |
case m_req_square: | |
log.Printf("Got an square message") | |
result := req.x * req.x | |
out <- m_res_square{result} | |
case m_req_cube: | |
log.Printf("Got a cube message") | |
result := req.x * req.x * req.x | |
out <- m_res_cube{result} | |
case m_req_close: | |
log.Printf("Got a close message") | |
out <- m_res_close{} | |
// ignore for the moment that s.in and s.out never get closed here | |
goto stop | |
} | |
} | |
stop: | |
s.done <- true | |
} | |
func (s *Server) Square(x int) int { | |
s.in <- m_req_square{x} | |
res := (<-s.out).(m_res_square) | |
return res.x | |
} | |
func (s *Server) Cube(x int) int { | |
s.in <- m_req_cube{x} | |
res := (<-s.out).(m_res_cube) | |
return res.x | |
} | |
func (s *Server) Close() { | |
s.in <- m_req_close{} | |
// The following code works fine: | |
//<-s.out | |
// FIXME: This code blocks indefinitely if the m_res_close struct is empty | |
res := (<-s.out).(m_res_close) | |
_ = res | |
// This works as well | |
// msg := <-s.out | |
// res := msg.(m_res_close) | |
// _ = res | |
} | |
// define some message types | |
type m_req interface { | |
is_m_req() | |
} | |
type m_res interface { | |
is_m_res() | |
} | |
type m_req_square struct{ x int } | |
type m_req_cube struct{ x int } | |
type m_req_close struct{} | |
type m_res_square struct{ x int } | |
type m_res_cube struct{ x int } | |
type m_res_close struct{} | |
func (m m_req_square) is_m_req() {} | |
func (m m_req_cube) is_m_req() {} | |
func (m m_req_close) is_m_req() {} | |
func (m m_res_square) is_m_res() {} | |
func (m m_res_cube) is_m_res() {} | |
func (m m_res_close) is_m_res() {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package foo | |
import ( | |
"testing" | |
) | |
func TestShutdown(test *testing.T) { | |
server := NewServer() | |
res := server.Square(3) | |
if res != 9 { | |
test.Errorf("Expected 9, got %d", res) | |
} | |
res = server.Cube(2) | |
if res != 8 { | |
test.Errorf("Expected 8, got %d", res) | |
} | |
server.Close() | |
<-server.done | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
include $(GOROOT)/src/Make.inc | |
TARG=foo | |
GOFILES=\ | |
foo.go \ | |
include $(GOROOT)/src/Make.pkg |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment