Пример #1
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) *KVPaxos {
	// call gob.Register on structures you want
	// Go's RPC library to marshall/unmarshall.
	gob.Register(Op{})

	kv := new(KVPaxos)
	kv.me = me

	// initialization
	kv.kvData = make(map[string]string)
	kv.preReply = make(map[string]*Op)
	kv.seqChan = make(map[int]chan *Op)
	kv.maxInstanceID = -1

	rpcs := rpc.NewServer()
	rpcs.Register(kv)

	kv.px = paxos.Make(servers, me, rpcs)

	os.Remove(servers[me])
	l, e := net.Listen("unix", servers[me])
	if e != nil {
		log.Fatal("listen error: ", e)
	}
	kv.l = l

	// please do not change any of the following code,
	// or do anything to subvert it.

	go func() {
		for kv.dead == false {
			conn, err := kv.l.Accept()
			if err == nil && kv.dead == false {
				if kv.unreliable && (rand.Int63()%1000) < 100 {
					// discard the request.
					conn.Close()
				} else if kv.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 && kv.dead == false {
				fmt.Printf("KVPaxos(%v) accept: %v\n", me, err.Error())
				kv.kill()
			}
		}
	}()
	go kv.updateStatus()
	return kv
}
Пример #2
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) *KVPaxos {
	// Go's RPC library to marshall/unmarshall.
	gob.Register(Op{})
	kv := new(KVPaxos)
	kv.me = me
	kv.seenMap = make(map[int64]bool)
	kv.kvData = make(map[string]string)
	kv.toprocess = 1
	rpcs := rpc.NewServer()
	rpcs.Register(kv)
	kv.px = paxos.Make(servers, me, rpcs)
	os.Remove(servers[me])
	l, e := net.Listen("unix", servers[me])
	if e != nil {
		glog.Fatal("listen error: ", e)
	}
	kv.l = l

	go func() {
		for kv.isdead() == false {
			conn, err := kv.l.Accept()
			if err == nil && kv.isdead() == false {
				go rpcs.ServeConn(conn)
			} else if err == nil {
				conn.Close()
			}
			if err != nil && kv.isdead() == false {
				glog.Warningln("KVPaxos(%v) accept: %v\n", me, err.Error())
				kv.kill()
			}
		}
	}()

	return kv
}
Пример #3
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) *KVPaxos {
	// this call is all that's needed to persuade
	// Go's RPC library to marshall/unmarshall
	// struct Op.
	gob.Register(Op{})

	kv := new(KVPaxos)
	kv.me = me

	// Your initialization code here.
	kv.mydb = map[string]string{}
	kv.history = map[int64]string{}
	kv.DoneInst = 0

	rpcs := rpc.NewServer()
	rpcs.Register(kv)

	kv.px = paxos.Make(servers, me, rpcs)

	os.Remove(servers[me])
	l, e := net.Listen("unix", servers[me])
	if e != nil {
		log.Fatal("listen error: ", e)
	}
	kv.l = l

	// please do not change any of the following code,
	// or do anything to subvert it.

	go func() {
		for kv.dead == false {
			conn, err := kv.l.Accept()
			if err == nil && kv.dead == false {
				if kv.unreliable && (rand.Int63()%1000) < 100 {
					// discard the request.
					conn.Close()
				} else if kv.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 && kv.dead == false {
				fmt.Printf("KVPaxos(%v) accept: %v\n", me, err.Error())
				kv.kill()
			}
		}
	}()

	return kv
}
Пример #4
0
func StartServer(servers []string, me int) *ShardMaster {
	gob.Register(Op{})
	sm := new(ShardMaster)

	path_parts := strings.Split(servers[me], "/")
	sm.db_path = db_path + path_parts[len(path_parts)-1]
	os.Remove(sm.db_path)
	sm.db = dbaccess.GetDatabase(sm.db_path)

	// Put my index
	sm.db.PutInt(METADATA, "me", me)
	sm.me = me

	// Enter peers
	sm.db.PutStringList(METADATA, "servers", servers)

	first_conf := new(Config)
	first_conf.Groups = map[int64][]string{}
	sm.DBPutConfig(0, first_conf)
	sm.db.PutInt(METADATA, "num_configs", 1)

	rpcs := rpc.NewServer()
	rpcs.Register(sm)

	sm.px = paxos.Make(servers, me, rpcs)
	FinishStartServer(sm, servers, me, rpcs)
	return sm
}
Пример #5
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 StartServer(servers []string, me int) *ShardMaster {
	gob.Register(Op{})

	sm := new(ShardMaster)
	sm.me = me

	sm.configs = make([]Config, 1)
	sm.configs[0].Groups = map[int64][]string{}

	//your initialization
	sm.cfgnum = 0

	rpcs := rpc.NewServer()
	rpcs.Register(sm)

	sm.px = paxos.Make(servers, me, rpcs)

	os.Remove(servers[me])
	l, e := net.Listen("unix", servers[me])
	if e != nil {
		log.Fatal("listen error: ", e)
	}
	sm.l = l

	// 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
}
Пример #6
0
func NewKVPaxosMap(peers []string, me int) *KVPaxosMap {
	m := &KVPaxosMap{}
	m.lock = sync.Mutex{}
	m.px = paxos.Make(peers, me, nil)
	m.done = 0
	m.data = make(map[string]string)
	m.dead = false
	return m
}
Пример #7
0
func NewEPServer(pxpeers []string, me int, sio *socketio.Server) *EPServer {
	gob.Register(PxLogEntry{})

	es := &EPServer{}
	es.sio = sio
	es.px = paxos.Make(pxpeers, me, nil)
	es.skts = make(map[string]string)
	es.pads = make(map[string]*PadManager)
	es.commitPoint = 0

	return es
}
Пример #8
0
func StartWhanauPaxos(servers []string, me int, uid string,
	rpcs *rpc.Server) *WhanauPaxos {

	wp := new(WhanauPaxos)

	if rpcs != nil {
		// caller will create socket &c
		rpcs.Register(wp)
	} else {
		rpcs := rpc.NewServer()
		rpcs.Register(wp)
	}

	newservers := make([]string, len(servers))
	for i, _ := range servers {
		newservers[i] = port(uid+"-wp", i)
	}

	wp.handledRequests = make(map[int64]interface{})
	wp.px = paxos.Make(newservers, me, nil)
	wp.db = make(map[KeyType]TrueValueType)
	wp.pending_writes = make(map[PendingInsertsKey]string)
	wp.currSeq = 0
	wp.currView = 0
	wp.me = me
	wp.myaddr = servers[me]
	wp.uid = uid

	gob.Register(Op{})
	gob.Register(PaxosGetArgs{})
	gob.Register(PaxosPutArgs{})
	gob.Register(PaxosGetReply{})
	gob.Register(PaxosPutReply{})
	gob.Register(PaxosPendingInsertsArgs{})
	gob.Register(PaxosPendingInsertsReply{})

	return wp
}
Пример #9
0
func MakeServer(servers []string, me int, dc DeveloperCoord, numTaskReplicas int, seed int64, socktype string) *Coordinator {
	gob.Register(Op{})
	gob.Register(map[string]interface{}{})
	gob.Register([]interface{}{})

	co := new(Coordinator)
	co.socktype = socktype
	co.me = me
	co.dc = dc
	co.currentView = View{0, false, nil, map[TaskID]TaskParams{}, map[TaskID][]ClientID{}, map[TaskID][]ClientID{}, map[TaskID]TaskInfo{}, map[ClientID]string{}}
	co.initialized = false
	co.leaderID = 0
	co.leaderNum = 0
	co.currentSeq = -1
	co.lastQueries = map[ClientID]int{}
	co.lastLeaderElection = time.Now()

	co.seed = seed
	co.numTaskReplicas = numTaskReplicas
	co.unassignedTasks = list.New()
	co.activeTasks = map[ClientID]map[TaskID]bool{}
	co.availableClients = map[ClientID]int{}
	co.killedTasks = map[TaskID]bool{}
	co.finishedTasks = map[TaskID]bool{}

	co.isFinished = false

	rpcs := rpc.NewServer()
	rpcs.Register(co)

	co.px = paxos.Make(servers, me, rpcs, socktype)

	// TODO: change this implementation for TCP sockets when necessary
	os.Remove(servers[me])
	l, e := net.Listen(co.socktype, servers[me])
	if e != nil {
		log.Fatal("listen error: ", e)
	}
	co.l = l

	// Code to listen and serve requests
	go func() {
		for !co.dead {
			conn, err := co.l.Accept()
			if err == nil && !co.dead {
				if co.unreliable && (rand.Int63()%1000) < 100 {
					// discard the request
					conn.Close()
				} else if co.unreliable && (rand.Int63()%1000) < 200 {
					// process request but discard 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 && !co.dead {
				fmt.Printf("Coordinator(%v) accept: %v\n", me, err.Error())
				co.Kill()
			}
		}
	}()

	return co
}
Пример #10
0
//
// Start a shardkv server.
// gid is the ID of the server's replica group.
// shardmasters[] contains the ports of the
//   servers that implement the shardmaster.
// servers[] contains the ports of the servers
//   in this replica group.
// me is the index of this server in servers[].
//
func StartServer(gid int64, shardmasters []string,
	servers []string, me int) *ShardKV {
	gob.Register(Op{})
	gob.Register(GetArgs{})
	gob.Register(PutArgs{})
	gob.Register(ReConfigStartArgs{})
	gob.Register(ReConfigEndArgs{})
	gob.Register(ReceiveShardArgs{})
	gob.Register(SentShardArgs{})
	gob.Register(NoopArgs{})
	gob.Register(KVPair{})

	kv := new(ShardKV)
	kv.me = me
	kv.gid = gid
	kv.sm = shardmaster.MakeClerk(shardmasters)
	// Your initialization code here.
	// Don't call Join().
	kv.config_prior = shardmaster.Config{}        // initial prior Config
	kv.config_prior.Groups = map[int64][]string{} // initialize map
	kv.config_now = shardmaster.Config{}          // initial prior Config
	kv.config_now.Groups = map[int64][]string{}   // initialize map
	kv.shards = make([]bool, shardmaster.NShards)
	kv.transition_to = -1
	kv.storage = map[string]string{} // key/value data storage
	kv.cache = map[string]Reply{}    // "client_id:request_id" -> reply cache
	kv.operation_number = -1         // first agreement number will be 0

	rpcs := rpc.NewServer()
	rpcs.Register(kv)

	kv.px = paxos.Make(servers, me, rpcs)

	os.Remove(servers[me])
	l, e := net.Listen("unix", servers[me])
	if e != nil {
		log.Fatal("listen error: ", e)
	}
	kv.l = l

	// please do not change any of the following code,
	// or do anything to subvert it.

	go func() {
		for kv.dead == false {
			conn, err := kv.l.Accept()
			if err == nil && kv.dead == false {
				if kv.unreliable && (rand.Int63()%1000) < 100 {
					// discard the request.
					conn.Close()
				} else if kv.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 && kv.dead == false {
				fmt.Printf("ShardKV(%v) accept: %v\n", me, err.Error())
				kv.kill()
			}
		}
	}()

	go func() {
		for kv.dead == false {
			kv.tick()
			time.Sleep(250 * time.Millisecond)
		}
	}()

	return kv
}
Пример #11
0
//
// Start a shardkv server.
// gid is the ID of the server's replica group.
// shardmasters[] contains the ports of the
//   servers that implement the shardmaster.
// servers[] contains the ports of the servers
//   in this replica group.
// Me is the index of this server in servers[].
//
func StartServer(gid int64, shardmasters []string,
	servers []string, me int) *ShardKV {
	gob.Register(Op{})
	DPrintf("%d.%d starting", me, gid)
	kv := new(ShardKV)
	kv.me = me
	kv.gid = gid
	kv.sm = shardmaster.MakeClerk(shardmasters)
	kv.contOK = make(chan bool)

	// Your initialization code here.
	// Don't call Join().
	kv.config = &shardmaster.Config{}
	kv.shards = &shards{shards: make([]map[int]map[string]string,
		shardmaster.NShards), latest: 0}
	for i, _ := range kv.shards.shards {
		kv.shards.shards[i] = make(map[int]map[string]string)
	}
	kv.states = &clientStates{states: make([]map[int]map[string]*Op,
		shardmaster.NShards), latest: 0}
	for i, _ := range kv.states.states {
		kv.states.states[i] = make(map[int]map[string]*Op)
	}
	kv.outstanding = make(map[int]chan *Op)
	kv.highestApplied = -1
	kv.count = 0

	rpcs := rpc.NewServer()
	rpcs.Register(kv)

	kv.px = paxos.Make(servers, me, rpcs)

	os.Remove(servers[me])
	l, e := net.Listen("unix", servers[me])
	if e != nil {
		log.Fatal("listen error: ", e)
	}
	kv.l = l

	// please do not change any of the following code,
	// or do anything to subvert it.

	go func() {
		for kv.dead == false {
			conn, err := kv.l.Accept()
			if err == nil && kv.dead == false {
				if kv.unreliable && (rand.Int63()%1000) < 100 {
					// discard the request.
					conn.Close()
				} else if kv.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 && kv.dead == false {
				fmt.Printf("ShardKV(%v) accept: %v\n", me, err.Error())
				kv.kill()
			}
		}
	}()

	go func() {
		for kv.dead == false {
			kv.tick()
			time.Sleep(250 * time.Millisecond)
		}
	}()

	go kv.getStatus()
	return kv
}
Пример #12
0
func main() {
	var npaxos = flag.Int("npaxos", 3, "number of paxos instances")
	var ngroups = flag.Int("ngroups", 3, "number of shard groups")
	var nmasters = flag.Int("nmasters", 3, "number of shardmasters per shard group")
	var nreplicas = flag.Int("nreplicas", 3, "number of kvshard replicas per group")
	var clean = flag.Bool("clean", false, "clean the db")

	flag.Parse()
	args := flag.Args()
	if len(args) < 1 {
		fmt.Printf("Not enough arguments, must specify program type:\n" +
			"   paxos|shardmaster|shardkv\n")
		os.Exit(1)
	}

	switch args[0] {
	case "paxos":
		fmt.Println("Attempting to start paxos server...")
		if *clean {
			cleanDB("paxos")
		}
		peers := test.GetPaxos(*npaxos)
		me := whoami(peers)
		if me == -1 {
			fmt.Println("Host didn't find own IP in peer list! Exiting!")
			os.Exit(1)
		}
		paxos.Make(peers, me, nil, network, "somedbtag")
		fmt.Println("peers: ", peers)
		fmt.Println("me: ", me)
		fmt.Printf("Started paxos server.\n")

	case "shardmaster":
		fmt.Println("Attempting to start shardmaster server...")
		if *clean {
			cleanDB("shardmaster")
		}
		peers, _ := test.GetShardmasters(*nmasters, *ngroups)
		me := whoami(peers)
		if me == -1 {
			fmt.Println("Host didn't find own IP in peer list! Exiting!")
			os.Exit(1)
		}
		shardmaster.StartServer(peers, me, network)
		fmt.Println("peers: ", peers)
		fmt.Println("me: ", me)
		fmt.Printf("Started shardmaster.\n")

	case "shardkv":
		fmt.Println("------------------------------------------")
		fmt.Println(getIP(), "attempting to start shardkv server...")
		//---------Default Shardmaster Servers------------
		//group 100: 10.0.0.101
		//group 101: 10.0.0.102
		//group 102: 10.0.0.103
		//-----------Default ShardKV Servers--------------
		//group 100: 10.0.0.104, 10.0.0.105, 10.0.0.106
		//group 101: 10.0.0.107, 10.0.0.108, 10.0.0.109
		//group 102: 10.0.0.110, 10.0.0.111, 10.0.0.112
		metapeers, masters, _ := test.GetShardkvs(*nreplicas, *nmasters, *ngroups)
		fmt.Printf("peers: %v\n", metapeers)

		me := whoami(masters)
		if me != -1 {
			fmt.Println("Starting shardmaster instead.")
			if *clean {
				cleanDB("shardmaster")
			}
			shardmaster.StartServer(masters, me, network)
			fmt.Printf("peers: %v\n", masters)
			fmt.Printf("me: %d\n", me)
			fmt.Println("Success!")
			select {}
		}
		var gid int64
		peers := make([]string, *ngroups)
		for i, v := range metapeers {
			peers = v
			me = whoami(v)
			gid = int64(100 + i)
			if me != -1 {
				break
			}
		}
		if me == -1 {
			fmt.Printf("Exiting! Host didn't find own IP %s in peer list: %v! "+
				"or masters: %v\n",
				getIP(), metapeers, masters)
			os.Exit(1)
		}
		if *clean {
			cleanDB("shardkv")
		}
		fmt.Println("masters:", masters)
		fmt.Printf("peers: %v\n", peers)
		fmt.Printf("me: %d, gid :%d\n", me, gid)
		shardkv.StartServer(gid, masters, peers, me, network)

	default:
		fmt.Printf("Invalid program type, choose one:" +
			"   paxos|shardmaster|shardkv")
		os.Exit(1)
	}
	select {}
}
Пример #13
0
//
// Start a shardkv server.
// gid is the ID of the server's replica group.
// shardmasters[] contains the ports of the
//   servers that implement the shardmaster.
// servers[] contains the ports of the servers
//   in this replica group.
// Me is the index of this server in servers[].
//
func StartServer(gid int64, shardmasters []string,
	servers []string, me int) *ShardKV {
	gob.Register(Op{})

	kv := new(ShardKV)
	kv.me = me
	kv.gid = gid
	kv.sm = shardmaster.MakeClerk(shardmasters)

	// Your initialization code here.
	// Don't call Join().
	kv.reply_signal = make(map[OpID]chan bool)
	kv.store = make(map[int]map[string]string)
	kv.last_reply = make(map[int]ReplyRecord)

	kv.shard_record = make(map[int]map[int]map[string]string)
	kv.reply_record = make(map[int]map[int]ReplyRecord)
	kv.record_level = -1
	kv.min_confignums = make(map[int64]int)

	kv.InitNewConfig(kv.sm.Query(-1))

	rpcs := rpc.NewServer()
	rpcs.Register(kv)
	kv.px = paxos.Make(servers, me, rpcs)

	kv.config_to_seq = make(map[int]int)

	os.Remove(servers[me])
	l, e := net.Listen("unix", servers[me])
	if e != nil {
		log.Fatal("listen error: ", e)
	}
	kv.l = l

	go kv.LogWalker()
	go kv.ManageConfigMins()
	// please do not change any of the following code,
	// or do anything to subvert it.

	go func() {
		for kv.dead == false {
			conn, err := kv.l.Accept()
			if err == nil && kv.dead == false {
				if kv.unreliable && (rand.Int63()%1000) < 100 {
					// discard the request.
					conn.Close()
				} else if kv.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 && kv.dead == false {
				fmt.Printf("ShardKV(%v) accept: %v\n", me, err.Error())
				kv.kill()
			}
		}
	}()

	go func() {
		time.Sleep(time.Duration(kv.me*10) * time.Millisecond)
		for kv.dead == false {
			kv.tick()
			time.Sleep(250 * time.Millisecond)
		}
	}()

	return kv
}
Пример #14
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 StartServer(servers []string, me int) *ShardMaster {
	gob.Register(Op{})
	// RPC library needs to know how to marshall/unmarshall the different types of Args
	gob.Register(JoinArgs{})
	gob.Register(LeaveArgs{})
	gob.Register(MoveArgs{})
	gob.Register(QueryArgs{})
	gob.Register(NoopArgs{})

	sm := new(ShardMaster)
	sm.me = me

	sm.configs = make([]Config, 1)              // initially just a 0th Config
	sm.configs[0].Groups = map[int64][]string{} // initialize map
	sm.operation_number = -1                    // first agreement number is 0

	rpcs := rpc.NewServer()
	rpcs.Register(sm)

	sm.px = paxos.Make(servers, me, rpcs)

	os.Remove(servers[me])
	l, e := net.Listen("unix", servers[me])
	if e != nil {
		log.Fatal("listen error: ", e)
	}
	sm.l = l

	// 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
}
Пример #15
0
//
// Start a shardkv server.
// gid is the ID of the server's replica group.
// shardmasters[] contains the ports of the
//   servers that implement the shardmaster.
// servers[] contains the ports of the servers
//   in this replica group.
// Me is the index of this server in servers[].
//
func StartServer(gid int64,
	shardmasters []string,
	servers []string, me int,
	messagebrokers []string) *ShardKV {
	gob.Register(Op{})
	gob.Register(PutArgs{})
	gob.Register(GetArgs{})
	gob.Register(SubscribeArgs{})
	gob.Register(ReconfigArgs{})
	gob.Register(TransferArgs{})

	kv := new(ShardKV)
	kv.me = me
	kv.gid = gid
	kv.sm = shardmaster.MakeClerk(shardmasters)
	kv.mb = messagebroker.MakeNotifier(messagebrokers)
	kv.config = kv.sm.Query(0)

	kv.table = make(map[string]*Entry)
	kv.tableCache = make(map[int]map[string]*Entry)
	kv.reqs = make(map[string]*Result)
	kv.reqsCache = make(map[int]map[string]*Result)

	kv.lastAppliedSeq = -1

	rpcs := rpc.NewServer()
	rpcs.Register(kv)

	kv.px = paxos.Make(servers, me, rpcs)

	os.Remove(servers[me])
	l, e := net.Listen("unix", servers[me])
	if e != nil {
		log.Fatal("listen error: ", e)
	}
	kv.l = l

	// please do not change any of the following code,
	// or do anything to subvert it.

	go func() {
		for kv.dead == false {
			conn, err := kv.l.Accept()
			if err == nil && kv.dead == false {
				if kv.unreliable && (rand.Int63()%1000) < 100 {
					// discard the request.
					conn.Close()
				} else if kv.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 && kv.dead == false {
				fmt.Printf("ShardKV(%v) accept: %v\n", me, err.Error())
				kv.Kill()
			}
		}
	}()

	go func() {
		for !kv.dead {
			kv.tick()
			time.Sleep(250 * time.Millisecond)
		}
	}()

	go kv.logSync()

	return kv
}
Пример #16
0
func StartServer(servers []string, me int) *MBServer {
	gob.Register(Op{})
	gob.Register(PublishArgs{})
	gob.Register(NotifyPutArgs{})
	gob.Register(NotifySubscribeArgs{})

	mb := new(MBServer)
	mb.me = me
	mb.reqs = make(map[string]map[int64]Err)
	mb.buffer = make(map[string]map[int64]*PublishArgs)
	mb.next = make(map[string]int64)
	mb.subscribers = make(map[string]*Subscriber)
	mb.lastAppliedSeq = -1

	rpcs := rpc.NewServer()
	rpcs.Register(mb)

	mb.px = paxos.Make(servers, me, rpcs)

	os.Remove(servers[me])
	l, e := net.Listen("unix", servers[me])
	if e != nil {
		log.Fatal("listen error: ", e)
	}
	mb.l = l

	// please do not change any of the following code,
	// or do anything to subvert it.

	go func() {
		for mb.dead == false {
			conn, err := mb.l.Accept()
			if err == nil && mb.dead == false {
				if mb.unreliable && (rand.Int63()%1000) < 100 {
					// discard the request.
					conn.Close()
				} else if mb.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 && mb.dead == false {
				fmt.Printf("MBServer(%v) accept: %v\n", me, err.Error())
				mb.Kill()
			}
		}
	}()

	go mb.logSync()

	return mb
}
Пример #17
0
//
// Start a shardkv server.
// gid is the ID of the server's replica group.
// shardmasters[] contains the ports of the
//   servers that implement the shardmaster.
// servers[] contains the ports of the servers
//   in this replica group.
// Me is the index of this server in servers[].
// dir is the directory name under which this
//   replica should store all its files.
//   each replica is passed a different directory.
// restart is false the very first time this server
//   is started, and true to indicate a re-start
//   after a crash or after a crash with disk loss.
//
func StartServer(gid int64, shardmasters []string,
	servers []string, me int, dir string, restart bool) *DisKV {

	kv := new(DisKV)
	kv.me = me
	kv.gid = gid
	kv.sm = shardmaster.MakeClerk(shardmasters)
	kv.dir = dir

	// Your initialization code here.
	// Don't call Join().

	// log.SetOutput(ioutil.Discard)

	gob.Register(Op{})

	rpcs := rpc.NewServer()
	rpcs.Register(kv)

	kv.px = paxos.Make(servers, me, rpcs)

	// log.SetOutput(os.Stdout)

	os.Remove(servers[me])
	l, e := net.Listen("unix", servers[me])
	if e != nil {
		log.Fatal("listen error: ", e)
	}
	kv.l = l

	// please do not change any of the following code,
	// or do anything to subvert it.

	go func() {
		for kv.isdead() == false {
			conn, err := kv.l.Accept()
			if err == nil && kv.isdead() == false {
				if kv.isunreliable() && (rand.Int63()%1000) < 100 {
					// discard the request.
					conn.Close()
				} else if kv.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)
					}
					go rpcs.ServeConn(conn)
				} else {
					go rpcs.ServeConn(conn)
				}
			} else if err == nil {
				conn.Close()
			}
			if err != nil && kv.isdead() == false {
				fmt.Printf("DisKV(%v) accept: %v\n", me, err.Error())
				kv.kill()
			}
		}
	}()

	go func() {
		for kv.isdead() == false {
			kv.tick()
			time.Sleep(250 * time.Millisecond)
		}
	}()

	return kv
}
Пример #18
0
//
// Start a shardkv server.
// gid is the ID of the server's replica group.
// shardmasters[] contains the ports of the
//   servers that implement the shardmaster.
// servers[] contains the ports of the servers
//   in this replica group.
// Me is the index of this server in servers[].
//
func StartServer(gid int64, shardmasters []string,
	servers []string, me int) *ShardKV {
	gob.Register(Op{})
	gob.Register(&ConfigBid{})
	gob.Register(&StartHandoff{})
	gob.Register(&EndHandoff{})
	gob.Register(&ShardData{})
	gob.Register(&PutArgs{})
	gob.Register(&GetArgs{})
	gob.Register(&GetShardArgs{})
	gob.Register(&PingArgs{})

	kv := new(ShardKV)
	kv.me = me
	kv.gid = gid
	kv.sm = shardmaster.MakeClerk(shardmasters)

	for i := range kv.dataForShard {
		kv.dataForShard[i] = &ShardData{
			Id:   i,
			Data: make(map[string]string),
		}
	}

	kv.cond = sync.NewCond(&kv.dataForShard[shardmaster.NShards].mu)

	kv.dataForShard[shardmaster.NShards].active = true
	kv.dataForShard[shardmaster.NShards].Num = -1

	kv.requests = make(map[int64]*RequestState)

	kv.subscribe = make(chan ExecuteRequest)
	kv.commitRequest = make(chan Op)
	kv.commitResponse = make(chan int)
	kv.ping = make(chan PingArgs, 100)

	go kv.commitRequests()

	go kv.executeStateMachine()

	rpcs := rpc.NewServer()
	rpcs.Register(kv)

	kv.px = paxos.Make(servers, me, rpcs)

	os.Remove(servers[me])
	l, e := net.Listen("unix", servers[me])
	if e != nil {
		log.Fatal("listen error: ", e)
	}
	kv.l = l

	// please do not change any of the following code,
	// or do anything to subvert it.

	go func() {
		for kv.dead == false {
			conn, err := kv.l.Accept()
			if err == nil && kv.dead == false {
				if kv.unreliable && (rand.Int63()%1000) < 100 {
					// discard the request.
					conn.Close()
				} else if kv.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 && kv.dead == false {
				fmt.Printf("ShardKV(%v) accept: %v\n", me, err.Error())
				kv.kill()
			}
		}
	}()

	go func() {
		for kv.dead == false {
			kv.tick()
			time.Sleep(250 * time.Millisecond)
		}
	}()

	return kv
}
Пример #19
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) *KVPaxos {
	// call gob.Register on structures you want
	// Go's RPC library to marshall/unmarshall.
	gob.Register(Op{})

	kv := new(KVPaxos)
	kv.me = me

	// Your initialization code here.
	kv.contiguous = -1
	kv.storage = make(map[string]string)
	kv.xactions = make(map[string]xaction)

	rpcs := rpc.NewServer()
	rpcs.Register(kv)

	kv.px = paxos.Make(servers, me, rpcs)

	// go func() { // background process to always update the state of the KVPaxos to be correct about decisions.
	//   for !kv.dead {
	//     kv.mu.Lock()
	//     // fmt.Printf("tick....")
	//     kv.px.Start(kv.contiguous+1, Op{Action:NOOP})
	//     kv.mu.Unlock()
	//     time.Sleep(NOOP_TICK)
	//   }
	// }()

	os.Remove(servers[me])
	l, e := net.Listen("unix", servers[me])
	if e != nil {
		log.Fatal("listen error: ", e)
	}
	kv.l = l

	// please do not change any of the following code,
	// or do anything to subvert it.

	go func() {
		for kv.dead == false {
			conn, err := kv.l.Accept()
			if err == nil && kv.dead == false {
				if kv.unreliable && (rand.Int63()%1000) < 100 {
					// discard the request.
					conn.Close()
				} else if kv.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 && kv.dead == false {
				fmt.Printf("KVPaxos(%v) accept: %v\n", me, err.Error())
				kv.kill()
			}
		}
	}()

	return kv
}
//
// Start a shardkv server.
// gid is the ID of the server's replica group.
// shardmasters[] contains the ports of the
//   servers that implement the shardmaster.
// servers[] contains the ports of the servers
//   in this replica group.
// Me is the index of this server in servers[].
// dir is the directory name under which this
//   replica should store all its files.
//   each replica is passed a different directory.
// restart is false the very first time this server
//   is started, and true to indicate a re-start
//   after a crash or after a crash with disk loss.
//
func StartServer(gid int64, shardmasters []string,
	servers []string, me int, dir string, restart bool) *DisKV {

	kv := new(DisKV)
	kv.me = me
	kv.gid = gid
	kv.sm = shardmaster.MakeClerk(shardmasters)
	kv.dir = dir

	// Your initialization code here.
	// Don't call Join().
	kv.config = shardmaster.Config{Num: -1}
	kv.data = make(map[string]string)
	kv.seen = make(map[string]int)
	kv.replyOfErr = make(map[string]Err)
	kv.replyOfValue = make(map[string]string)
	kv.seq = -1

	// log.SetOutput(ioutil.Discard)

	gob.Register(Op{})

	rpcs := rpc.NewServer()
	rpcs.Register(kv)

	kv.px = paxos.Make(servers, me, rpcs)

	// log.SetOutput(os.Stdout)

	os.Remove(servers[me])
	l, e := net.Listen("unix", servers[me])
	if e != nil {
		log.Fatal("listen error: ", e)
	}
	kv.l = l

	// reload the data from disk if restart
	if restart {
		// fmt.Printf("Restart !")
		for i := 0; i < shardmaster.NShards; i++ {
			kv.data = kv.fileReadShard(i, kv.data)
		}

		var data PersistentData
		err := kv.readPersistentData(&data)
		if err == nil {
			kv.seen = data.Seen
			kv.replyOfErr = data.ReplyOfErr
			kv.replyOfValue = data.ReplyOfValue
			kv.seq = data.Seq
		}
		// fmt.Printf("Restart!\n")
		// fmt.Printf("%v\n", err)
		// fmt.Printf("%v\n", data.Seen)
		// fmt.Printf("%v\n", data.ReplyOfErr)
		// fmt.Printf("%v\n", data.ReplyOfValue)
		// fmt.Printf("%v\n", data.Seq)
		// kv.seq = data.Seq
		// kv.px = &data.Px
	}

	// please do not change any of the following code,
	// or do anything to subvert it.

	go func() {
		for kv.isdead() == false {
			conn, err := kv.l.Accept()
			if err == nil && kv.isdead() == false {
				if kv.isunreliable() && (rand.Int63()%1000) < 100 {
					// discard the request.
					conn.Close()
				} else if kv.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)
					}
					go rpcs.ServeConn(conn)
				} else {
					go rpcs.ServeConn(conn)
				}
			} else if err == nil {
				conn.Close()
			}
			if err != nil && kv.isdead() == false {
				fmt.Printf("DisKV(%v) accept: %v\n", me, err.Error())
				kv.kill()
			}
		}
	}()

	go func() {
		for kv.isdead() == false {
			kv.tick()
			time.Sleep(50 * time.Millisecond)
		}
	}()

	return kv
}
Пример #21
0
//
// Start a shardkv server.
// gid is the ID of the server's replica group.
// shardmasters[] contains the ports of the
//   servers that implement the shardmaster.
// servers[] contains the ports of the servers
//   in this replica group.
// Me is the index of this server in servers[].
//
func StartServer(gid int64, shardmasters []string,
	servers []string, me int) *ShardKV {
	gob.Register(Op{})
	gob.Register(ServerState{})

	kv := new(ShardKV)
	kv.me = me
	kv.gid = gid
	kv.sm = shardmaster.MakeClerk(shardmasters)

	// Your initialization code here.
	// Don't call Join().
	kv.localLog = make(map[int]Op)
	kv.Counter = 1
	kv.horizon = 0
	kv.configNum = -1
	kv.max = 0
	// setup cell storage
	id := int(rand.Int31n(1000000)) // TODO: change to be recoverable?
	kv.storage = MakeStorage(id, 1000000000, "127.0.0.1:27017")
	kv.storage.Clear()

	kv.current = ServerState{make(map[int]map[string]string), make(map[string]ClientReply)}
	kv.results = make(map[string]ClientReply)
	kv.configs = make(map[int]shardmaster.Config)
	kv.configs[-1] = shardmaster.Config{}

	rpcs := rpc.NewServer()
	rpcs.Register(kv)

	kv.px = paxos.Make(servers, me, rpcs)
	kv.uid = strconv.FormatInt(nrand(), 10)

	// Logging
	kv.logFilename = fmt.Sprintf("logs/paxos_log_%d_%d.log", kv.me, kv.gid)
	var err error
	kv.logFile, err = os.OpenFile(kv.logFilename, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
	if err != nil {
		log.Fatal(err)
	}
	kv.enc = gob.NewEncoder(kv.logFile)

	//  go kv.logBackground()

	os.Remove(servers[me])
	l, e := net.Listen(Network, servers[me])
	if e != nil {
		log.Fatal("listen error: ", e)
	}
	kv.l = l

	// please do not change any of the following code,
	// or do anything to subvert it.

	go func() {
		for kv.dead == false {
			conn, err := kv.l.Accept()
			if err == nil && kv.dead == false {
				if kv.unreliable && (rand.Int63()%1000) < 100 {
					// discard the request.
					conn.Close()
				} else if kv.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 {
						DPrintf("shutdown: %v\n", err)
					}
					go rpcs.ServeConn(conn)
				} else {
					go rpcs.ServeConn(conn)
				}
			} else if err == nil {
				conn.Close()
			}
			if err != nil && kv.dead == false {
				DPrintf("ShardKV(%v) accept: %v\n", me, err.Error())
				kv.Kill()
			}
		}
	}()

	go func() {
		for kv.dead == false {
			kv.tick()
			time.Sleep(250 * time.Millisecond)
		}
	}()

	return kv
}
Пример #22
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 StartServer(servers []string, me int, network bool) *ShardMaster {
	gob.Register(Op{})

	var err error
	if Log == 1 {
		//set up logging
		os.Remove("shardmaster.log")
		logfile, err = os.OpenFile("shardmaster.log", os.O_RDWR|os.O_CREATE|os.O_APPEND|os.O_SYNC, 0666)

		if err != nil {
			log.Fatalf("error opening file: %v", err)
		} else {
			log.Printf("opened shardmaster.log for logging")
		}
		enableLog()
	}
	DPrintf("Shardamaster %s server started with peers", servers[me], servers)
	sm := new(ShardMaster)
	// Read memory options
	sm.persistent = persistent
	sm.recovery = recovery
	sm.dbUseCompression = dbUseCompression
	sm.dbUseCache = dbUseCache
	sm.dbCacheSize = dbCacheSize
	sm.writeToMemory = writeToMemory

	// Network stuff
	sm.me = me
	sm.network = network

	// Shardmaster state
	sm.processedSeq = -1
	sm.maxConfig = 0
	sm.configs = make(map[int]*Config)
	sm.configs[0] = &Config{}
	sm.configs[0].Groups = map[int64][]string{}

	// Persistence stuff
	waitChan := make(chan int)
	go func() {
		waitChan <- 1
		sm.startup(servers)
	}()
	<-waitChan

	rpcs := rpc.NewServer()
	if !printRPCerrors {
		disableLog()
		rpcs.Register(sm)
		//fmt.Println("registering")
		enableLog()
	} else {
		rpcs.Register(sm)
	}

	sm.px = paxos.Make(servers, me, rpcs, network, "shardmaster")

	if sm.network {
		port := servers[me][len(servers[me])-5 : len(servers[me])]
		fmt.Printf("I am peers[%d] = %s, about to listen on port %s\n", me,
			servers[me], port)
		l, e := net.Listen("tcp", port)
		if e != nil {
			log.Fatal("listen error: ", e)
		}
		sm.l = l
	} else {
		os.Remove(servers[me])
		l, e := net.Listen("unix", servers[me])
		if e != nil {
			log.Fatal("listen error: ", e)
		}
		sm.l = l
	}
	// 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.deaf || (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.
					if !sm.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)
						}
					}
					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
}
Пример #23
0
//
// Start a shardkv server.
// gid is the ID of the server's replica group.
// shardmasters[] contains the ports of the
//   servers that implement the shardmaster.
// servers[] contains the ports of the servers
//   in this replica group.
// Me is the index of this server in servers[].
//
func StartServer(gid int64, shardmasters []string,
	servers []string, me int) *ShardKV {
	gob.Register(Op{})

	kv := new(ShardKV)
	kv.me = me
	kv.gid = gid
	kv.uid = strconv.Itoa(me) + string("-") + strconv.FormatInt(gid, 10)
	kv.sm = shardmaster.MakeClerk(shardmasters)
	kv.servers = servers

	// Your initialization code here.
	kv.logged = make(map[int64]bool)
	kv.values = make(map[string]string)
	// Don't call Join().

	rpcs := rpc.NewServer()
	rpcs.Register(kv)

	kv.px = paxos.Make(servers, me, rpcs)

	os.Remove(servers[me])
	l, e := net.Listen("unix", servers[me])
	if e != nil {
		log.Fatal("listen error: ", e)
	}
	kv.l = l

	// please do not change any of the following code,
	// or do anything to subvert it.

	go func() {
		for kv.dead == false {
			conn, err := kv.l.Accept()
			if err == nil && kv.dead == false {
				if kv.unreliable && (rand.Int63()%1000) < 100 {
					// discard the request.
					conn.Close()
				} else if kv.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 && kv.dead == false {
				fmt.Printf("ShardKV(%v) accept: %v\n", me, err.Error())
				kv.kill()
			}
		}
	}()

	go func() {
		for kv.dead == false {
			kv.tick()
			time.Sleep(250 * time.Millisecond)
		}
	}()

	return kv
}
Пример #24
0
//
// Start a shardkv server.
// gid is the ID of the server's replica group.
// shardmasters[] contains the ports of the
//   servers that implement the shardmaster.
// servers[] contains the ports of the servers
//   in this replica group.
// Me is the index of this server in servers[].
//
func StartServer(gid int64, shardmasters []string,
	servers []string, me int) *ShardKV {
	gob.Register(Op{})
	gob.Register(ClientResponse{})

	kv := new(ShardKV)
	kv.me = me
	kv.gid = gid
	kv.sm = shardmaster.MakeClerk(shardmasters)

	// Your initialization code here.
	// Don't call Join().
	DPrintf("\n\n%v-%v: My servers are %v\n\nMy shardmasters are %v\n\n", kv.gid, kv.me, servers, shardmasters)
	toPrint = make(map[int64]string)
	kv.kvDatabase = make(map[int]map[string]string)
	kv.currentConfig = shardmaster.Config{}
	kv.myShards = make(map[int]bool)
	kv.receivedShards = make(map[int]*ShardArgs)
	kv.maxSequenceCommitted = -1
	kv.seenXID = make(map[int]map[int64]bool)
	kv.clientResponses = make(map[int]map[int64]*ClientResponse)
	kv.replyChannels = make(map[int64]chan Op)

	rpcs := rpc.NewServer()
	rpcs.Register(kv)

	kv.px = paxos.Make(servers, me, rpcs)

	os.Remove(servers[me])
	l, e := net.Listen("unix", servers[me])
	if e != nil {
		log.Fatal("listen error: ", e)
	}
	kv.l = l

	// please do not change any of the following code,
	// or do anything to subvert it.

	go func() {
		for kv.dead == false {
			conn, err := kv.l.Accept()
			if err == nil && kv.dead == false {
				if kv.unreliable && (rand.Int63()%1000) < 100 {
					// discard the request.
					conn.Close()
				} else if kv.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 && kv.dead == false {
				fmt.Printf("ShardKV(%v) accept: %v\n", me, err.Error())
				kv.kill()
			}
		}
	}()

	go func() {
		for kv.dead == false {
			kv.tick()
			time.Sleep(250 * time.Millisecond)
		}
	}()

	return kv
}
Пример #25
0
//
// Start a shardkv server.
// gid is the ID of the server's replica group.
// shardmasters[] contains the ports of the
//   servers that implement the shardmaster.
// servers[] contains the ports of the servers
//   in this replica group.
// Me is the index of this server in servers[].
//
func StartServer(gid int64, shardmasters []string,
	servers []string, me int) *ShardKV {
	gob.Register(Op{})
	gob.Register(shardmaster.Config{})
	gob.Register(Xaction{})
	gob.Register(GetArgs{})
	gob.Register(PutArgs{})
	gob.Register(GimmeDataArgs{})
	gob.Register(GimmeDataReply{})

	kv := new(ShardKV)
	kv.me = me
	kv.gid = gid
	kv.sm = shardmaster.MakeClerk(shardmasters)

	// Your initialization code here.
	// Don't call Join().
	kv.now = kv.sm.Query(0)
	kv.next = kv.sm.Query(0)
	kv.contiguous = -1
	kv.storage = make(map[string]string)
	kv.xactions = make(map[string]Xaction)
	kv.versions = make(map[int]Snapshot)

	rpcs := rpc.NewServer()
	rpcs.Register(kv)

	kv.px = paxos.Make(servers, me, rpcs)

	os.Remove(servers[me])
	l, e := net.Listen("unix", servers[me])
	if e != nil {
		log.Fatal("listen error: ", e)
	}
	kv.l = l

	// please do not change any of the following code,
	// or do anything to subvert it.

	go func() {
		for kv.dead == false {
			conn, err := kv.l.Accept()
			if err == nil && kv.dead == false {
				if kv.unreliable && (rand.Int63()%1000) < 100 {
					// discard the request.
					conn.Close()
				} else if kv.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 && kv.dead == false {
				fmt.Printf("ShardKV(%v) accept: %v\n", me, err.Error())
				kv.kill()
			}
		}
	}()

	go func() {
		for kv.dead == false {
			kv.tick()
			time.Sleep(250 * time.Millisecond)
		}
	}()

	return kv
}
Пример #26
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) *KVPaxos {
	// this call is all that's needed to persuade
	// Go's RPC library to marshall/unmarshall
	// struct Op.
	gob.Register(Op{})

	kv := new(KVPaxos)
	kv.me = me
	// Your initialization code here.
	kv.kvstore = KVStorage{state: map[string]string{},
		operation_number: -1,
	}
	/* Only makes state map useable (non-nil). Maps nested inside of a state entry
	like state[5] will be nil maps which need to be initialized when state[5] is
	set*/
	kv.kvcache = KVCache{state: make(map[int]map[int]*CacheEntry)}

	rpcs := rpc.NewServer()
	rpcs.Register(kv)

	kv.px = paxos.Make(servers, me, rpcs)

	os.Remove(servers[me])
	l, e := net.Listen("unix", servers[me])
	if e != nil {
		log.Fatal("listen error: ", e)
	}
	kv.l = l

	// please do not change any of the following code,
	// or do anything to subvert it.

	go func() {
		for kv.dead == false {
			conn, err := kv.l.Accept()
			if err == nil && kv.dead == false {
				if kv.unreliable && (rand.Int63()%1000) < 100 {
					// discard the request.
					conn.Close()
				} else if kv.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 && kv.dead == false {
				fmt.Printf("KVPaxos(%v) accept: %v\n", me, err.Error())
				kv.kill()
			}
		}
	}()

	return kv
}