func main() { flag.Parse() if flag.NArg() < 2 { fmt.Println("Usage: client ServiceName numRuns") return } svcName := flag.Arg(0) numRuns, _ := strconv.Atoi(flag.Arg(1)) conn1, _ := net.Dial("unix", ServantAddr1) fmt.Println("conn to servant1 up") conn2, _ := net.Dial("unix", ServantAddr2) fmt.Println("conn to servant2 up") //create router and connect it to both active and standby servants rot := router.New(router.StrID(), 32, router.BroadcastPolicy /* , "cli", router.ScopeLocal*/) proxy1 := router.NewProxy(rot, "proxy1", nil, nil) proxy2 := router.NewProxy(rot, "proxy2", nil, nil) proxy1.ConnectRemote(conn1, router.GobMarshaling, router.XOnOffFlowController) proxy2.ConnectRemote(conn2, router.GobMarshaling, router.XOnOffFlowController) reqChan := make(chan string) rspChan := make(chan string) bindChan := make(chan *router.BindEvent, 1) rot.AttachSendChan(router.StrID("/App/"+svcName+"/Request"), reqChan, bindChan) rot.AttachRecvChan(router.StrID("/App/"+svcName+"/Response"), rspChan) //make sure client connect to 2 servants before sending requests for { if (<-bindChan).Count > 1 { break } } cont := true for i := 0; i < numRuns && cont; i++ { req := fmt.Sprintf("request %d", i) fmt.Printf("client sent request [%s] to serivce [%s]\n", req, svcName) reqChan <- req timer := time.NewTimer(6e8) //the wait for response will time out in less than 1 sec select { case rsp, chOpen := <-rspChan: if !chOpen { fmt.Println("client response closed, exit") cont = false } else { fmt.Printf("client recv response ( %s )\n", rsp) } case <-timer.C: fmt.Printf("time out for reqest [%s]\n", req) i-- //resend it } timer.Stop() } fmt.Printf("client exit\n") conn1.Close() conn2.Close() rot.Close() }
func main() { done := make(chan bool) //create active/standby servant activeServant := NewServant("servant1", Active, done) standbyServant := NewServant("servant2", Standby, done) //connect servants by connecting their proxies configured with filters filter := &ServantFilter{[]string{"/Sys/Ctrl/Heartbeat"}} //only allow heartbeats between active/standby proxy1 := router.NewProxy(activeServant.Rot, "", filter, nil) proxy2 := router.NewProxy(standbyServant.Rot, "", filter, nil) proxy1.Connect(proxy2) //wait for servants to exit <-done <-done }
func (s *Servant) Run(done chan bool) { addr := ServantAddr1 if s.role == Standby { addr = ServantAddr2 } os.Remove(addr) l, _ := net.Listen("unix", addr) //blocked all internal ctrl msgs clientFilter := &ClientFilter{[]string{"/Sys/", "/Fault/", "/DB/"}} //keep accepting client conn and connect local router to it for { conn, err := l.Accept() if err != nil { fmt.Println(err) continue } fmt.Println(s.name, "connect one client") //proxy use flow control //proxies will be cleaned up when client disconnect proxy := router.NewProxy(s.Rot, "", clientFilter, nil) err = proxy.ConnectRemote(conn, router.GobMarshaling, router.XOnOffFlowController) if err != nil { fmt.Println(err) continue } } //in fact never reach here s.Rot.Close() l.Close() done <- true }