func (dt *DbTask) handleCmd(cmd string) bool { cont := true svcname := "" idx := strings.Index(cmd, ":") if idx > 0 { svcname = cmd[idx+1:] cmd = cmd[0:idx] } switch cmd { case "Start": dt.numTrans = 0 dt.role = Active case "Stop": dt.role = Standby case "Shutdown": cont = false case "AddService": if len(svcname) > 0 { ch := make(chan string) dt.dbRespChans[svcname] = ch dt.rot.AttachSendChan(router.StrID("/App/"+svcname+"/DB/Response"), ch) } case "DelService": if len(svcname) > 0 { ch, ok := dt.dbRespChans[svcname] if ok { dt.dbRespChans[svcname] = nil, false dt.rot.DetachChan(router.StrID("/App/"+svcname+"/DB/Response"), ch) } } default: } return cont }
func (ft *FaultMgrTask) handleCmd(cmd string) bool { cont := true svcname := "" idx := strings.Index(cmd, ":") if idx > 0 { svcname = cmd[idx+1:] cmd = cmd[0:idx] } switch cmd { case "Start": ft.role = Active case "Stop": ft.role = Standby case "Shutdown": cont = false case "AddService": if len(svcname) > 0 { ch := make(chan string) ft.svcCmdChans[svcname] = ch ft.rot.AttachSendChan(router.StrID("/App/"+svcname+"/Command"), ch) } case "DelService": if len(svcname) > 0 { ch, ok := ft.svcCmdChans[svcname] if ok { ft.svcCmdChans[svcname] = nil, false ft.rot.DetachChan(router.StrID("/App/"+svcname+"/Command"), ch) } } default: } return cont }
func (ft *FaultMgrTask) shutdown() { for k, v := range ft.svcCmdChans { ft.rot.DetachChan(router.StrID("/App/"+k+"/Command"), v) } ft.rot.DetachChan(router.StrID("/Sys/OutOfService"), ft.sysOOSChan) ft.rot.DetachChan(router.StrID("/Fault/DB/Exception"), ft.faultReportChan) ft.rot.DetachChan(router.StrID("/Fault/AppService/Exception"), ft.faultReportChan) ft.rot.DetachChan(router.StrID("/Sys/Command"), ft.sysCmdChan) }
func (dt *DbTask) shutdown() { //output_intf or send chans dt.FaultRaiser.Close() for k, v := range dt.dbRespChans { dt.rot.DetachChan(router.StrID("/App/"+k+"/DB/Response"), v) } //input_intf or recv chans dt.rot.DetachChan(router.StrID("/Sys/Command"), dt.sysCmdChan) dt.rot.DetachChan(router.StrID("/DB/Request"), dt.dbReqChan) }
func newPinger(rot router.Router, done chan<- bool, numRuns int) { //attach chans to router pingChan := make(chan *Msg) pongChan := make(chan *Msg) rot.AttachSendChan(router.StrID("ping"), pingChan) rot.AttachRecvChan(router.StrID("pong"), pongChan) //start pinger ping := &Pinger{pingChan, pongChan, done, numRuns} go ping.Run() }
func newPonger(rot router.Router, done chan<- bool) { //attach chans to router pingChan := make(chan Msg) pongChan := make(chan Msg) rot.AttachSendChan(router.StrID("pong"), pongChan) rot.AttachRecvChan(router.StrID("ping"), pingChan) //start ponger pong := &Ponger{pongChan, pingChan, done} go pong.Run() }
func (ft *FaultMgrTask) init(r router.Router, sn string, role ServantRole) { ft.rot = r ft.role = role ft.servName = sn ft.svcCmdChans = make(map[string](chan string)) ft.sysOOSChan = make(chan string) ft.faultReportChan = make(chan *router.FaultRecord) ft.sysCmdChan = make(chan string) ft.rot.AttachSendChan(router.StrID("/Sys/OutOfService"), ft.sysOOSChan) ft.rot.AttachRecvChan(router.StrID("/Sys/Command"), ft.sysCmdChan) //use a bindChan to keep faultReportChan open when all clients exit bc := make(chan *router.BindEvent, 1) ft.rot.AttachRecvChan(router.StrID("/Fault/DB/Exception"), ft.faultReportChan, bc) ft.rot.AttachRecvChan(router.StrID("/Fault/AppService/Exception"), ft.faultReportChan, bc) }
func (dt *DbTask) init(r router.Router, sn string, role ServantRole) { dt.rot = r dt.role = role dt.servName = sn dt.random = rand.New(rand.NewSource(time.Seconds())) dt.dbRespChans = make(map[string](chan string)) dt.dbReqChan = make(chan *DbReq) dt.sysCmdChan = make(chan string) //output_intf or send chans dt.FaultRaiser = router.NewFaultRaiser(router.StrID("/Fault/DB/Exception"), r, "DbTask") //input_intf or recv chans r.AttachRecvChan(router.StrID("/Sys/Command"), dt.sysCmdChan) //use a bindChan to keep dbReqChan open when all clients detach & exit bc := make(chan *router.BindEvent, 1) r.AttachRecvChan(router.StrID("/DB/Request"), dt.dbReqChan, bc) }
func main() { flag.Parse() if flag.NArg() < 1 { fmt.Println("Usage: pingpong5 num_runs hideTrace") return } else if flag.NArg() > 1 { showPingPong = false } numRuns, _ := strconv.Atoi(flag.Arg(0)) done := make(chan bool) connNow := make(chan bool) //start two goroutines to setup a unix sock connection //connect two routers thru unix sock //and then hook up Pinger and Ponger to the routers go func() { //setup Pinger sock conn //wait for ponger up <-connNow //set up an io conn to ponger thru tcp sock conn, _ := net.Dial("tcp", "", "[::]:9099") fmt.Println("ping conn up") //create router and connect it to io conn rot := router.New(router.StrID(), 32, router.BroadcastPolicy) rot.ConnectRemote(conn, router.GobMarshaling) //hook up Pinger and Ponger newPinger(rot, done, numRuns) }() go func() { //setup Ponger sock conn //wait to set up an io conn thru tcp sock l, _ := net.Listen("tcp", ":9099") connNow <- true //notify pinger that ponger's ready to accept conn, _ := l.Accept() fmt.Println("pong conn up") //create router and connect it to io conn rot := router.New(router.StrID(), 32, router.BroadcastPolicy) rot.ConnectRemote(conn, router.GobMarshaling) //hook up Ponger newPonger(rot, done) }() //wait for ping-pong to finish <-done <-done }
func newPonger(rot router.Router, done chan<- bool) { //attach chans to router pingChan := make(chan *Msg) pongChan := make(chan *Msg) //bindChan := make(chan *router.BindEvent, 1) rot.AttachSendChan(router.StrID("pong"), pongChan /*, bindChan*/) rot.AttachRecvChan(router.StrID("ping"), pingChan) //wait for pinger connecting /* for { if (<-bindChan).Count > 0 { break } } */ //start ponger pong := &Ponger{pongChan, pingChan, done} go pong.Run() }
func main() { flag.Parse() if flag.NArg() < 1 { fmt.Println("Usage: pingpong3 num_runs hideTrace") return } else if flag.NArg() > 1 { showPingPong = false } numRuns, _ := strconv.Atoi(flag.Arg(0)) //alloc two routers to connect them rot1 := router.New(router.StrID(), 32, router.BroadcastPolicy) rot2 := router.New(router.StrID(), 32, router.BroadcastPolicy) rot1.Connect(rot2) done := make(chan bool) //hook up Pinger and Ponger newPinger(rot1, done, numRuns) newPonger(rot2, done) //wait for ping-pong to finish <-done <-done }
func NewServant(n string, role ServantRole, done chan bool) *Servant { s := new(Servant) s.Rot = router.New(router.StrID(), 32, router.BroadcastPolicy /*, n, router.ScopeLocal*/) s.role = role s.name = n //start system tasks, ServiceTask will be created when clients connect NewSysMgrTask(s.Rot, n, role) NewDbTask(s.Rot, n, role) NewFaultMgrTask(s.Rot, n, role) //run Servant mainloop to wait for client connection go s.Run(done) return s }
func (at *ServiceTask) shutdown() { svcname := "/App/" + at.name //output_intf or send chans at.FaultRaiser.Close() at.rot.DetachChan(router.StrID(svcname+"/Response"), at.svcRespChan) at.rot.DetachChan(router.StrID("/DB/Request"), at.dbReqChan) //input_intf or recv chans at.rot.DetachChan(router.StrID(svcname+"/Request"), at.svcReqChan) at.rot.DetachChan(router.StrID("/Sys/Command"), at.sysCmdChan) at.rot.DetachChan(router.StrID(svcname+"/Command"), at.svcCmdChan) at.rot.DetachChan(router.StrID(svcname+"/DB/Response"), at.dbRespChan) }
func (at *ServiceTask) init(r router.Router, sn string, n string, role ServantRole) { at.rot = r at.name = n at.servantName = sn at.role = role at.random = rand.New(rand.NewSource(time.Seconds())) at.svcRespChan = make(chan string) at.dbReqChan = make(chan *DbReq) at.svcReqChan = make(chan string, router.DefDataChanBufSize) at.sysCmdChan = make(chan string) at.svcCmdChan = make(chan string) at.dbRespChan = make(chan string) at.bindChan = make(chan *router.BindEvent, 1) svcname := "/App/" + at.name //output_intf or send chans at.FaultRaiser = router.NewFaultRaiser(router.StrID("/Fault/AppService/Exception"), at.rot, at.name) at.rot.AttachSendChan(router.StrID("/DB/Request"), at.dbReqChan) at.rot.AttachSendChan(router.StrID(svcname+"/Response"), at.svcRespChan) //input_intf or recv chans at.rot.AttachRecvChan(router.StrID("/Sys/Command"), at.sysCmdChan) at.rot.AttachRecvChan(router.StrID(svcname+"/Command"), at.svcCmdChan) at.rot.AttachRecvChan(router.StrID(svcname+"/DB/Response"), at.dbRespChan) at.rot.AttachRecvChan(router.StrID(svcname+"/Request"), at.svcReqChan, at.bindChan) }
func main() { l, err := net.Listen("tcp", ":0") if err != nil { fmt.Println(err) return } fmt.Println(l.Addr().String()) subjMap := make(map[string]*Subject) rot := router.New(router.StrID(), 32, router.BroadcastPolicy /*, "chatsrv", router.ScopeLocal*/) //start server mainloop in a separate goroutine, and recv client conn in main goroutine go func() { //subscribe to remote publications, so learn what subjects are created pubChan := make(chan *router.IdChanInfoMsg) //attach a recv chan with a "chan BindEvent" //this recv chan will not be closed when all senders detach bindChan := make(chan *router.BindEvent, 1) rot.AttachRecvChan(rot.NewSysID(router.PubId, router.ScopeRemote), pubChan, bindChan) //stopChan to notify when all people leave a subject stopChan := make(chan string, 36) for { select { case idstr := <-stopChan: subjMap[idstr] = nil, false case pub := <-pubChan: //process recved client publication of subjects for _, v := range pub.Info { id := v.Id.(*router.StrId) //get the real id type subj, ok := subjMap[id.Val] if ok { continue } fmt.Printf("add subject: %v\n", id.Val) //add a new subject with ScopeRemote, so that msgs are forwarded //to peers in connected routers id.ScopeVal = router.ScopeRemote id.MemberVal = router.MemberLocal subj = newSubject() subjMap[id.Val] = subj //subscribe to new subjects, forward recved msgs to other rot.AttachSendChan(id, subj.sendChan) rot.AttachRecvChan(id, subj.recvChan) //start forwarding go func(subjname string) { for val := range subj.recvChan { fmt.Printf("chatsrv forward: subject[%v], msg[%s]\n", subjname, val) subj.sendChan <- val } stopChan <- subjname fmt.Printf("chatsrv stop forwarding for : %v\n", subjname) }(id.Val) } } } }() //keep accepting client conn and connect local router to it for { conn, err := l.Accept() if err != nil { fmt.Println(err) return } fmt.Println("one client connect") _, err = rot.ConnectRemote(conn, router.JsonMarshaling) if err != nil { fmt.Println(err) return } } //in fact never reach here rot.Close() l.Close() }