// // the application wants to create a paxos peer. // the ports of all the paxos peers (including this one) // are in peers[]. this servers port is peers[me]. // func Make(peers []string, me int, rpcs *rpc.Server) *Paxos { px := &Paxos{} px.peers = peers px.me = me // Your initialization code here. if rpcs != nil { // caller will create socket &c rpcs.Register(px) } else { rpcs = rpc.NewServer() rpcs.Register(px) // prepare to receive connections from clients. // change "unix" to "tcp" to use over a network. os.Remove(peers[me]) // only needed for "unix" l, e := net.Listen("unix", peers[me]) if e != nil { log.Fatal("listen error: ", e) } px.l = l // please do not change any of the following code, // or do anything to subvert it. // create a thread to accept RPC connections go func() { for px.dead == false { conn, err := px.l.Accept() if err == nil && px.dead == false { if px.unreliable && (rand.Int63()%1000) < 100 { // discard the request. conn.Close() } else if px.unreliable && (rand.Int63()%1000) < 200 { // process the request but force discard of reply. c1 := conn.(*net.UnixConn) f, _ := c1.File() err := syscall.Shutdown(int(f.Fd()), syscall.SHUT_WR) if err != nil { fmt.Printf("shutdown: %v\n", err) } px.rpcCount++ go rpcs.ServeConn(conn) } else { px.rpcCount++ go rpcs.ServeConn(conn) } } else if err == nil { conn.Close() } if err != nil && px.dead == false { fmt.Printf("Paxos(%v) accept: %v\n", me, err.Error()) } } }() } return px }
// This serves a single RPC connection on the given RPC server on // a random port. func serve(server *rpc.Server) (err error) { if os.Getenv(MagicCookieKey) != MagicCookieValue { return errors.New("Please do not execute plugins directly. Packer will execute these for you.") } // If there is no explicit number of Go threads to use, then set it if os.Getenv("GOMAXPROCS") == "" { runtime.GOMAXPROCS(runtime.NumCPU()) } minPort, err := strconv.ParseInt(os.Getenv("PACKER_PLUGIN_MIN_PORT"), 10, 32) if err != nil { return } maxPort, err := strconv.ParseInt(os.Getenv("PACKER_PLUGIN_MAX_PORT"), 10, 32) if err != nil { return } log.Printf("Plugin minimum port: %d\n", minPort) log.Printf("Plugin maximum port: %d\n", maxPort) // Set the RPC port range packrpc.PortRange(int(minPort), int(maxPort)) var address string var listener net.Listener for port := minPort; port <= maxPort; port++ { address = fmt.Sprintf("127.0.0.1:%d", port) listener, err = net.Listen("tcp", address) if err != nil { err = nil continue } break } defer listener.Close() // Output the address to stdout log.Printf("Plugin address: %s\n", address) fmt.Println(address) os.Stdout.Sync() // Accept a connection log.Println("Waiting for connection...") conn, err := listener.Accept() if err != nil { log.Printf("Error accepting connection: %s\n", err.Error()) return } // Serve a single connection log.Println("Serving a plugin connection...") server.ServeConn(conn) return }
func waitForConnExit(c net.Conn, server *rpc.Server) (ret chan bool) { ret = make(chan bool) go func() { tcpConn := c.(*net.TCPConn) tcpConn.SetKeepAlive(true) server.ServeConn(c) ret <- true }() return ret }
func DispatchForever(connch <-chan net.Conn, srv *rpc.Server, clientch chan<- *rpc.Client) { for conn := range connch { muxed, err := muxconn.Split(conn, 2) if err != nil { log.Println("birpc: Failed to mux incoming connection from", conn.RemoteAddr().String(), "to", conn.LocalAddr().String(), ", dropping") continue } // Server on first muxed conn, client on second go srv.ServeConn(muxed[0]) clientch <- rpc.NewClient(muxed[1]) } }
// Serve announces an RPC service on the client using the given name // (which must currently be unique amongst all clients). func (c *Client) Serve(clientName string, rpcServer *rpc.Server) error { var clientId string rpcServer.RegisterName("ClientRPC", clientRPC{}) // TODO better name if err := c.Server.Call("Ncnet-publisher.Publish", &clientName, &clientId); err != nil { return err } clientconn, err := ncnet.Dial(c.Importer, clientId) if err != nil { return err } go rpcServer.ServeConn(clientconn) return nil }
func (lt *localRPCTransport) accept(server *rpc.Server, listener net.Listener) { for { conn, err := listener.Accept() if err != nil { if opError, ok := err.(*net.OpError); ok { if opError.Err.Error() == "use of closed network connection" { return } } glog.Errorf("rpc.Serve: accept: %s", err.Error()) } go server.ServeConn(conn) } }
func Dial(url string, srv *rpc.Server) (client *rpc.Client, err error) { conn, err := direct.Dial(url) if err != nil { return } muxed, err := muxconn.Split(conn, 2) if err != nil { return } // Server on second, client on first (reverse of above) client = rpc.NewClient(muxed[0]) go srv.ServeConn(muxed[1]) return }
func serveSingleConn(s *rpc.Server) string { l := netListenerInRange(portRangeMin, portRangeMax) // Accept a single connection in a goroutine and then exit go func() { defer l.Close() conn, err := l.Accept() if err != nil { panic(err) } s.ServeConn(conn) }() return l.Addr().String() }
func (c *Simple) waitForConnections(rpcs *rpc.Server) { for { conn, err := c.listener.Accept() if err == nil { if *use_codec { //rpcCodec := codec.GoRpc.ServerCodec(conn, &mh) rpcCodec := codec.MsgpackSpecRpc.ServerCodec(conn, &mh) go rpcs.ServeCodec(rpcCodec) } else { go rpcs.ServeConn(conn) } } else { // handle error //fmt.Println("ERROR: ", err) } } }
// serve starts listening for RPC calls, and creates a new thread for // each incoming connection. func serve(address string, rpcs *rpc.Server) { l, err := net.Listen("tcp", address) if err != nil { panic(err) } for { conn, err := l.Accept() if err != nil { panic(err) } go rpcs.ServeConn(conn) } }
// // the application wants to create a paxos peer. // the ports of all the paxos peers (including this one) // are in peers[]. this servers port is peers[me]. // func Make(peers []string, me int, rpcs *rpc.Server) *Paxos { px := &Paxos{} px.peers = peers px.stateMap = make(map[int]State) px.maxCanDisregard = -1 px.lastDoneSignalled = -1 flag.Parse() px.me = me if rpcs != nil { // caller will create socket &c rpcs.Register(px) } else { rpcs = rpc.NewServer() rpcs.Register(px) // prepare to receive connections from clients. // change "unix" to "tcp" to use over a network. os.Remove(peers[me]) // only needed for "unix" l, e := net.Listen("unix", peers[me]) if e != nil { glog.Fatalf("listen error: ", e) } px.l = l // create a thread to accept RPC connections go func() { for px.isdead() == false { conn, err := px.l.Accept() if err == nil && px.isdead() == false { atomic.AddInt32(&px.rpcCount, 1) go rpcs.ServeConn(conn) } else if err == nil { conn.Close() } if err != nil && px.isdead() == false { //////fmt.Printf("Paxos(%v) accept: %v\n", me, err.Error()) } } }() } return px }
func StartDNS(servers []string, rpcs *rpc.Server) *DNSserver { // call gob.Register on structures you want // Go's RPC library to marshall/unmarshall. gob.Register(DNSserver{}) gob.Register(GetServerArgs{}) gob.Register(GetServerReply{}) dns := new(DNSserver) dns.servers = servers dns.address = portDNS() if rpcs != nil { // caller will create socket &c rpcs.Register(dns) } else { rpcs = rpc.NewServer() rpcs.Register(dns) os.Remove(dns.address) l, e := net.Listen("unix", dns.address) if e != nil { log.Fatal("listen error: ", e) } dns.l = l // please do not change any of the following code, // or do anything to subvert it. // create a thread to accept RPC connections go func() { for { conn, err := dns.l.Accept() if err == nil { go rpcs.ServeConn(conn) } if err != nil { fmt.Printf("DNSerror: %v\n", err.Error()) } } }() } return dns }
// // servers[] contains the ports of the set of // servers that will cooperate via Paxos to // form the fault-tolerant shardmaster service. // me is the index of the current server in servers[]. // func FinishStartServer(sm *ShardMaster, servers []string, me int, rpcs *rpc.Server) *ShardMaster { os.Remove(servers[me]) l, e := net.Listen("unix", servers[me]) if e != nil { log.Fatal("listen error: ", e) } sm.l = l go sm.LogWalker() // please do not change any of the following code, // or do anything to subvert it. go func() { for sm.dead == false { conn, err := sm.l.Accept() if err == nil && sm.dead == false { if sm.unreliable && (rand.Int63()%1000) < 100 { // discard the request. conn.Close() } else if sm.unreliable && (rand.Int63()%1000) < 200 { // process the request but force discard of reply. c1 := conn.(*net.UnixConn) f, _ := c1.File() err := syscall.Shutdown(int(f.Fd()), syscall.SHUT_WR) if err != nil { fmt.Printf("shutdown: %v\n", err) } go rpcs.ServeConn(conn) } else { go rpcs.ServeConn(conn) } } else if err == nil { conn.Close() } if err != nil && sm.dead == false { fmt.Printf("ShardMaster(%v) accept: %v\n", me, err.Error()) sm.Kill() } } }() return sm }
// RPCAccept accepts connections on the listener and dispatches them to the // RPC server for service. Unfortunately the native Go rpc.Accept function // fatals on any accept error, including temporary failures and closure of // the listener. func RPCAccept(ln net.Listener, server *rpc.Server) error { errClosing := errors.New("use of closed network connection") for { conn, err := ln.Accept() if err != nil { if ne, ok := err.(net.Error); ok && ne.Temporary() { log.Warningf("RPC accept temporary error: %v", err) time.Sleep(1 * time.Second) continue } if oe, ok := err.(*net.OpError); ok && oe.Err.Error() == errClosing.Error() { log.Infoln("RPC accept connection closed") return nil } log.Errorf("RPC accept error: %v", err) return err } go server.ServeConn(conn) } }
func (lt *localRPCTransport) accept(server *rpc.Server, listener net.Listener) { for { conn, err := listener.Accept() if err != nil { if strings.HasSuffix(err.Error(), "use of closed network connection") { return } // TODO(bdarnell): are any transient errors possible here? log.Fatalf("localRPCTransport.accept: %s", err) continue } lt.mu.Lock() lt.conns[conn] = struct{}{} lt.mu.Unlock() go func(conn net.Conn) { defer func() { lt.mu.Lock() defer lt.mu.Unlock() delete(lt.conns, conn) }() server.ServeConn(conn) }(conn) } }
// // the application wants to create a paxos peer. // the ports of all the paxos peers (including this one) // are in peers[]. this servers port is peers[me]. // func NewPaxos(peers []string, me int, rpcs *rpc.Server) *Paxos { px := &Paxos{} px.peers = peers px.me = me px.instances = make(map[int]*InstanceState) px.localMin = -1 px.globalMin = -1 // init the min heap px.minHeap = MakeIntHeap() px.minChan = make(chan N, len(px.peers)) if rpcs != nil { // caller will create socket &c rpcs.Register(px) } else { rpcs = rpc.NewServer() rpcs.Register(px) // prepare to receive connections from clients. l, e := net.Listen("tcp", peers[me]) if e != nil { log.Fatal("listen error: ", e) } px.l = l // create a thread to accept RPC connections go func() { for px.dead == false { conn, err := px.l.Accept() if err == nil && px.dead == false { if px.unreliable && (rand.Int63()%1000) < 100 { // simply ignores the request conn.Close() } else if px.unreliable && (rand.Int63()%1000) < 200 { // process the request but force discard of reply. // close the write of the connection c1 := conn.(*net.TCPConn) err := c1.CloseWrite() // equivalent to below syscall: // f, _ := c1.File() // err := syscall.Shutdown(int(f.Fd()), syscall.SHUT_WR) if err != nil { fmt.Printf("shutdown: %v\n", err) } // serve the rpc px.rpcCount++ go rpcs.ServeConn(conn) } else { px.rpcCount++ go rpcs.ServeConn(conn) } } else if err == nil { conn.Close() } if err != nil && px.dead == false { fmt.Printf("Paxos(%v) accept: %v\n", me, err.Error()) } } }() // launch background GC thread go px.gc(px.minChan) } return px }
// Serve handles RPC commands from stdin, writing responses to stdout, until stdin is closed. func Serve(server *rpc.Server) { server.ServeConn(stdio{os.Stdin, os.Stdout}) }
// // the application wants to create a paxos peer. // the ports of all the paxos peers (including this one) // are in peers[]. this servers port is peers[me]. // func Make(peers []string, me int, rpcs *rpc.Server, network bool, tag string) *Paxos { px := &Paxos{} // Read memory options px.persistent = persistent px.recovery = recovery px.dbUseCompression = dbUseCompression px.dbUseCache = dbUseCache px.dbCacheSize = dbCacheSize px.writeToMemory = writeToMemory // Network stuff px.peers = peers px.me = me px.network = network px.reachable = make([]bool, len(px.peers)) for i := range px.peers { px.reachable[i] = true } px.deaf = false // Paxos state px.instances = make(map[int]Proposal) px.leader = make(map[int]int) px.proposed = make(map[int]bool) px.maxInstance = -1 px.done = make(map[int]int) for i := 0; i < len(px.peers); i++ { px.done[i] = -1 } px.doneChannels = make(map[int]chan bool) // Persistence stuff waitChan := make(chan int) go func() { waitChan <- 1 px.startup(tag) }() <-waitChan if rpcs != nil { // caller will create socket &c if !printRPCerrors { disableLog() rpcs.Register(px) enableLog() } else { rpcs.Register(px) } } else { rpcs = rpc.NewServer() if !printRPCerrors { disableLog() rpcs.Register(px) enableLog() } else { rpcs.Register(px) } // prepare to receive connections from clients. // change "unix" to "tcp" to use over a network. if px.network { l, e := net.Listen("tcp", ":"+strconv.Itoa(startport)) if e != nil { log.Fatal("listen error: ", e) } px.l = l } else { os.Remove(peers[me]) // only needed for "unix" l, e := net.Listen("unix", peers[me]) if e != nil { log.Fatal("listen error: ", e) } px.l = l } // please do not change any of the following code, // or do anything to subvert it. // create a thread to accept RPC connections go func() { for px.dead == false { conn, err := px.l.Accept() if err == nil && px.dead == false { if px.deaf || (px.unreliable && (rand.Int63()%1000) < 100) { // discard the request. conn.Close() } else if px.unreliable && (rand.Int63()%1000) < 200 { // process the request but force discard of reply. if !px.network { c1 := conn.(*net.UnixConn) f, _ := c1.File() err := syscall.Shutdown(int(f.Fd()), syscall.SHUT_WR) if err != nil { fmt.Printf("shutdown: %v\n", err) } } else { //respond to imaginary port? c1 := conn.(*net.TCPConn) f, _ := c1.File() err := syscall.Shutdown(int(f.Fd()), syscall.SHUT_WR) if err != nil { fmt.Printf("shutdown: %v\n", err) } } px.rpcCount++ go rpcs.ServeConn(conn) } else { px.rpcCount++ go rpcs.ServeConn(conn) } } else if err == nil { conn.Close() } if err != nil && px.dead == false { fmt.Printf("Paxos(%v) accept: %v\n", me, err.Error()) } } }() } return px }
// // the application wants to create a paxos peer. // the ports of all the paxos peers (including this one) // are in peers[]. this servers port is peers[me]. // func Make(peers []string, me int, rpcs *rpc.Server) *Paxos { px := &Paxos{} px.peers = peers px.me = me // Your initialization code here. px.instances = make(map[int]InstanceStatus) // Status of each sequence number px.doneResponses = make(map[string]int) // Responses from each peer from Done method px.minSequence = 0 // Minimum stored sequence px.maxSequence = 0 // Maximum stored sequence // Not sure exactly what gob.Register does, so not sure if these are needed... gob.Register(Proposal{}) gob.Register(Decision{}) gob.Register(ForgetSequence{}) if rpcs != nil { // caller will create socket &c rpcs.Register(px) } else { rpcs = rpc.NewServer() rpcs.Register(px) // prepare to receive connections from clients. // change "unix" to "tcp" to use over a network. os.Remove(peers[me]) // only needed for "unix" l, e := net.Listen("unix", peers[me]) if e != nil { log.Fatal("listen error: ", e) } px.l = l // please do not change any of the following code, // or do anything to subvert it. // create a thread to accept RPC connections go func() { for px.dead == false { conn, err := px.l.Accept() if err == nil && px.dead == false { if px.unreliable && (rand.Int63()%1000) < 100 { // discard the request. conn.Close() } else if px.unreliable && (rand.Int63()%1000) < 200 { // process the request but force discard of reply. c1 := conn.(*net.UnixConn) f, _ := c1.File() err := syscall.Shutdown(int(f.Fd()), syscall.SHUT_WR) if err != nil { fmt.Printf("shutdown: %v\n", err) } px.rpcCount++ go rpcs.ServeConn(conn) } else { px.rpcCount++ go rpcs.ServeConn(conn) } } else if err == nil { conn.Close() } if err != nil && px.dead == false { fmt.Printf("Paxos(%v) accept: %v\n", me, err.Error()) } } }() } return px }
// // the application wants to create a paxos peer. // the ports of all the paxos peers (including this one) // are in peers[]. this servers port is peers[me]. // func Make(peers []string, me int, rpcs *rpc.Server) *Paxos { px := &Paxos{} px.peers = peers px.me = me fmt.Println("Peer Number: ", len(peers)) px.fates = make(map[int]Fate) px.seens = make(map[int]int) px.accepts = make(map[int]int) px.values = make(map[int]interface{}) px.dones = make([]int, len(peers)) px.highest = -1 px.maxSeen = px.me if rpcs != nil { // caller will create socket &c rpcs.Register(px) } else { rpcs = rpc.NewServer() rpcs.Register(px) // prepare to receive connections from clients. // change "unix" to "tcp" to use over a network. os.Remove(peers[me]) // only needed for "unix" l, e := net.Listen("unix", peers[me]) if e != nil { log.Fatal("listen error: ", e) } px.l = l // please do not change any of the following code, // or do anything to subvert it. // create a thread to accept RPC connections go func() { for px.isdead() == false { conn, err := px.l.Accept() if err == nil && px.isdead() == false { if px.isunreliable() && (rand.Int63()%1000) < 100 { // discard the request. conn.Close() } else if px.isunreliable() && (rand.Int63()%1000) < 200 { // process the request but force discard of reply. c1 := conn.(*net.UnixConn) f, _ := c1.File() err := syscall.Shutdown(int(f.Fd()), syscall.SHUT_WR) if err != nil { fmt.Printf("shutdown: %v\n", err) } atomic.AddInt32(&px.rpcCount, 1) go rpcs.ServeConn(conn) } else { atomic.AddInt32(&px.rpcCount, 1) go rpcs.ServeConn(conn) } } else if err == nil { conn.Close() } if err != nil && px.isdead() == false { fmt.Printf("Paxos(%v) accept: %v\n", me, err.Error()) } } }() } return px }
// // servers[] contains the ports of the set of // servers that will cooperate via Paxos to // form the fault-tolerant key/value service. // me is the index of the current server in servers[]. // func StartServer(servers []string, me int, port_meteor string, rpcs *rpc.Server) *MMDatabase { // call gob.Register on structures you want // Go's RPC library to marshall/unmarshall. gob.Register(Message{}) gob.Register(GetCoordListArgs{}) gob.Register(GetCoordListReply{}) gob.Register(ReplicaPutArgs{}) gob.Register(ReplicaPutReply{}) gob.Register(CoordPutArgs{}) gob.Register(CoordPutReply{}) gob.Register(GetArgs{}) gob.Register(GetReply{}) db := new(MMDatabase) db.dead = false db.me = me db.port_meteor = port_meteor db.servers = servers db.nServers = len(servers) db.nReplicas = 3 db.handoffMessages = make([]*Message, 0) if rpcs != nil { // caller will create socket &c rpcs.Register(db) } else { rpcs = rpc.NewServer() rpcs.Register(db) os.Remove(servers[me]) l, e := net.Listen("unix", servers[me]) if e != nil { log.Fatal("listen error: ", e) } db.l = l // please do not change any of the following code, // or do anything to subvert it. // create a thread to accept RPC connections go func() { for db.dead == false { conn, err := db.l.Accept() if err == nil && db.dead == false { if db.unreliable && (rand.Int63()%1000) < 100 { // discard the request. conn.Close() } else if db.unreliable && (rand.Int63()%1000) < 200 { // process the request but force discard of reply. c1 := conn.(*net.UnixConn) f, _ := c1.File() err := syscall.Shutdown(int(f.Fd()), syscall.SHUT_WR) if err != nil { fmt.Printf("shutdown: %v\n", err) } db.rpcCount++ go rpcs.ServeConn(conn) } else { db.rpcCount++ go rpcs.ServeConn(conn) } } else if err == nil { conn.Close() } if err != nil && db.dead == false { fmt.Printf("MMDatabase(%v) accept: %v\n", me, err.Error()) } } }() } go db.runHandoffLoop() return db }
func FinishMake(px *Paxos, rpcs *rpc.Server) *Paxos { px.instances = make(map[int]*Instance) px.multi_locks = make(map[int]*sync.Mutex) px.majority = len(px.peers) / 2 px.prevDone = -1 px.PingTimes = make(map[int]time.Time) for index, _ := range px.peers { px.PingTimes[index] = time.Now() } if px.me+1 == len(px.peers) { px.Leader = true } else { px.Leader = false } px.NewLeader = false px.MajorityMax = -1 if rpcs != nil { // caller will create socket &c rpcs.Register(px) } else { rpcs = rpc.NewServer() rpcs.Register(px) // prepare to receive connections from clients. // change "unix" to "tcp" to use over a network. os.Remove(px.peers[px.me]) // only needed for "unix" l, e := net.Listen("unix", px.peers[px.me]) if e != nil { log.Fatal("listen error: ", e) } px.l = l // please do not change any of the following code, // or do anything to subvert it. // create a thread to accept RPC connections go func() { for px.dead == false { conn, err := px.l.Accept() if err == nil && px.dead == false { if px.unreliable && (rand.Int63()%1000) < 100 { // discard the request. conn.Close() } else if px.unreliable && (rand.Int63()%1000) < 200 { // process the request but force discard of reply. c1 := conn.(*net.UnixConn) f, _ := c1.File() err := syscall.Shutdown(int(f.Fd()), syscall.SHUT_WR) if err != nil { fmt.Printf("shutdown: %v\n", err) } px.rpcCount++ go rpcs.ServeConn(conn) } else { px.rpcCount++ go rpcs.ServeConn(conn) } } else if err == nil { conn.Close() } if err != nil && px.dead == false { fmt.Printf("Paxos(%v) accept: %v\n", px.me, err.Error()) } } }() } go px.MultiPaxos() return px }
// // the application wants to create a paxos peer. // the ports of all the paxos peers (including this one) // are in peers[]. this servers port is peers[me]. // func Make(peers []string, me int, rpcs *rpc.Server) *Paxos { px := &Paxos{} px.peers = peers px.me = me fmt.Printf("peers: %v\n", px.peers) px.UID = GetMD5Hash(peers[me]) os.Mkdir("logs", 0700) px.logPath = "logs/peer-" + px.UID os.Mkdir(px.logPath, 0700) px.DeleteBarrier = (1 << 31) - 1 px.initializeEncoder() // Your initialization code here. px.instances = make(map[int]Instance) px.maxProposalNs = make(map[int]int64) px.maxAcceptNs = make(map[int]int64) px.maxAcceptVs = make(map[int]interface{}) px.minSeqNums = make([]int, len(peers), len(peers)) px.maxAcceptPeerIds = make(map[int]int) for z := 0; z < len(peers); z++ { px.minSeqNums[z] = -1 } if rpcs != nil { // caller will create socket &c rpcs.Register(px) } else { rpcs = rpc.NewServer() rpcs.Register(px) // prepare to receive connections from clients. // change "unix" to "tcp" to use over a network. os.Remove(peers[me]) // only needed for "unix" l, e := net.Listen(Network, peers[me]) if e != nil { log.Fatal("listen error: ", e) } px.l = l // please do not change any of the following code, // or do anything to subvert it. // create a thread to accept RPC connections go func() { for px.dead == false { conn, err := px.l.Accept() if err == nil && px.dead == false { if px.unreliable && (rand.Int63()%1000) < 100 { // discard the request. conn.Close() } else if px.unreliable && (rand.Int63()%1000) < 200 { // process the request but force discard of reply. c1 := conn.(*net.UnixConn) f, _ := c1.File() err := syscall.Shutdown(int(f.Fd()), syscall.SHUT_WR) if err != nil { fmt.Printf("shutdown: %v\n", err) } px.rpcCount++ go rpcs.ServeConn(conn) } else { px.rpcCount++ go rpcs.ServeConn(conn) } } else if err == nil { conn.Close() } if err != nil && px.dead == false { fmt.Printf("Paxos(%v) accept: %v\n", me, err.Error()) } } // Close decision log file px.decisionFile.Close() }() } return px }
// // the application wants to create a paxos peer. // the ports of all the paxos peers (including this one) // are in peers[]. this servers port is peers[me]. // func Make(peers []string, me int, rpcs *rpc.Server) *Paxos { px := &Paxos{} px.peers = peers px.me = me // Your initialization code here. px.acceptorInstances = make(map[int]*PxAcceptorInstance) px.proposerInstances = make(map[int]*PxProposerInstance) px.peerDones = minimumSetInit(len(px.peers)) px.maxSeq = -1 px.maxKnownSeq = -1 px.minSeq = 0 // Start garbage collection thread go func() { for px.isdead() == false { px.garbageCollect() time.Sleep(100 * time.Millisecond) } }() if rpcs != nil { // caller will create socket &c rpcs.Register(px) } else { rpcs = rpc.NewServer() rpcs.Register(px) // prepare to receive connections from clients. // change "unix" to "tcp" to use over a network. os.Remove(peers[me]) // only needed for "unix" log.Printf("listen: %v\n", peers[me]) l, e := net.Listen("unix", peers[me]) if e != nil { log.Fatal("listen error: ", e) } px.l = l // please do not change any of the following code, // or do anything to subvert it. // create a thread to accept RPC connections go func() { for px.isdead() == false { conn, err := px.l.Accept() if err == nil && px.isdead() == false { if px.isunreliable() && (rand.Int63()%1000) < 100 { // discard the request. conn.Close() } else if px.isunreliable() && (rand.Int63()%1000) < 200 { // process the request but force discard of reply. c1 := conn.(*net.UnixConn) f, _ := c1.File() err := syscall.Shutdown(int(f.Fd()), syscall.SHUT_WR) if err != nil { fmt.Printf("shutdown: %v\n", err) } atomic.AddInt32(&px.rpcCount, 1) go rpcs.ServeConn(conn) } else { atomic.AddInt32(&px.rpcCount, 1) go rpcs.ServeConn(conn) } } else if err == nil { conn.Close() } if err != nil && px.isdead() == false { fmt.Printf("Paxos(%v) accept: %v\n", me, err.Error()) } } }() } return px }
// // the application wants to create a paxos peer. // the ports of all the paxos peers (including this one) // are in peers[]. this servers port is peers[me]. // func Make(peers []string, me int, rpcs *rpc.Server) *Paxos { var formatter = logging.MustStringFormatter(`%{color} %{shortfunc} : %{message} %{color:reset}`) logging.SetLevel(logging.CRITICAL, "paxos") logging.SetFormatter(formatter) px := &Paxos{} px.peers = peers px.me = me px.done = make([]int, len(px.peers)) for i := range px.done { px.done[i] = -1 } // Your initialization code here. px.instances = make(map[int]*PaxosInstance) if rpcs != nil { // caller will create socket &c rpcs.Register(px) } else { rpcs = rpc.NewServer() rpcs.Register(px) // prepare to receive connections from clients. // change "unix" to "tcp" to use over a network. os.Remove(peers[me]) // only needed for "unix" l, e := net.Listen("unix", peers[me]) if e != nil { log.Debug("listen error: ", e) } px.l = l // please do not change any of the following code, // or do anything to subvert it. // create a thread to accept RPC connections go func() { for px.isdead() == false { conn, err := px.l.Accept() if err == nil && px.isdead() == false { if px.isunreliable() && (rand.Int63()%1000) < 100 { // discard the request. conn.Close() } else if px.isunreliable() && (rand.Int63()%1000) < 200 { // process the request but force discard of reply. c1 := conn.(*net.UnixConn) f, _ := c1.File() err := syscall.Shutdown(int(f.Fd()), syscall.SHUT_WR) if err != nil { fmt.Printf("shutdown: %v\n", err) } atomic.AddInt32(&px.rpcCount, 1) go rpcs.ServeConn(conn) } else { atomic.AddInt32(&px.rpcCount, 1) go rpcs.ServeConn(conn) } } else if err == nil { conn.Close() } if err != nil && px.isdead() == false { fmt.Printf("Paxos(%v) accept: %v\n", me, err.Error()) } } }() } return px }