예제 #1
0
//
// 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
}
예제 #2
0
파일: plugin.go 프로젝트: khangtoh/packer
// 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
}
예제 #3
0
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
}
예제 #4
0
파일: birpc.go 프로젝트: funkygao/govtil
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])
	}
}
예제 #5
0
파일: ncrpc.go 프로젝트: zenoss/rog-go
// 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
}
예제 #6
0
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)
	}
}
예제 #7
0
파일: birpc.go 프로젝트: funkygao/govtil
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
}
예제 #8
0
파일: server.go 프로젝트: B-Rich/packer
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()
}
예제 #9
0
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)
		}
	}
}
예제 #10
0
파일: server.go 프로젝트: rlayte/toystore
// 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)
	}
}
예제 #11
0
파일: paxos.go 프로젝트: anupamaggarwal/yak
//
// 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
}
예제 #12
0
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
}
예제 #13
0
//
// 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
}
예제 #14
0
// 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)
	}
}
예제 #15
0
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)
	}
}
예제 #16
0
//
// 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
}
예제 #17
0
// 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})
}
예제 #18
0
파일: paxos.go 프로젝트: salibrandi/mexos
//
// 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
}
예제 #19
0
파일: paxos.go 프로젝트: salibrandi/mexos
//
// 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
}
예제 #20
0
//
// 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
}
예제 #21
0
//
// 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
}
예제 #22
0
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
}
예제 #23
0
//
// 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
}
예제 #24
0
//
// 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
}
예제 #25
0
//
// 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
}