Example #1
0
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()
}
Example #2
0
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
}
Example #3
0
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
}