Exemplo n.º 1
0
func (ss *cohortStorageServer) RegisterServer(args *storagerpc.RegisterArgs, reply *storagerpc.RegisterReply) error {
	// Node not yet seen by MasterServer
	ss.rw.Lock()
	if _, ok := ss.exists[args.ServerInfo.NodeId]; !ok {
		ss.exists[args.ServerInfo.NodeId] = true
		ss.servers = append(ss.servers, args.ServerInfo)
	}

	if len(ss.servers) < ss.numNodes {
		ss.rw.Unlock()
		reply.Status = storagerpc.NotReady
		return nil
	}

	/// sort the nodes by nodeID starting from lowest
	nodeSorter := func(n1, n2 *storagerpc.Node) bool {
		return n1.NodeId < n2.NodeId
	}
	By(nodeSorter).Sort(ss.servers)

	ss.rw.Unlock()
	reply.Status = storagerpc.OK
	reply.Servers = ss.servers
	return nil
}
Exemplo n.º 2
0
func NewCohortStorageServer(masterHostPort, selfHostPort string, nodeId uint32, numNodes int) (CohortStorageServer, error) {
	ss := new(cohortStorageServer)

	ss.nodeId = nodeId
	ss.masterHostPort = masterHostPort
	ss.selfHostPort = selfHostPort

	ss.servers = make([]storagerpc.Node, 0, numNodes) // Consistent hashing ring. Empty if not instance is not master.
	ss.storage = make(map[string]string)
	ss.locks = make(map[string]*sync.RWMutex)
	ss.exists = make(map[uint32]bool)
	ss.rw = new(sync.RWMutex)

	ss.undoLog = make(map[int]LogEntry) // TransactionId to Store 1. Key 2. TransactionId. (Old)Value
	ss.redoLog = make(map[int]LogEntry) // TransactionId to Store 1. Key 2. TransactionID. (New)Value

	ss.numNodes = numNodes
	ss.tickers = make(map[string]uint64)
	ss.setTickers()

	// server is the master and must init the ring and listen for 'RegisterServer' calls
	if masterHostPort == "" {
		ss.master = true
		masterNode := storagerpc.Node{HostPort: selfHostPort, NodeId: nodeId, Master: true}
		ss.exists[nodeId] = true
		ss.servers = append(ss.servers, masterNode)

		for errCount := 0; ; errCount++ {
			err := rpc.RegisterName("CohortStorageServer", storagerpc.Wrap(ss))
			if err != nil {
				if errCount == 5 {
					return nil, err
				}
				time.Sleep(time.Second)
				continue
			} else {
				break
			}
		}

		var err error
		listener, err := net.Listen("tcp", selfHostPort)
		log.Println("Master listening on: ", selfHostPort)
		if err != nil {
			return nil, err
		}

		rpc.HandleHTTP()
		go http.Serve(listener, nil)

		return ss, nil
	}

	// server is a slave in the ring
	cli, err := util.TryDial(masterHostPort)
	if err != nil {
		log.Println("error: ", err)
		return nil, err
	}
	// Try to register the slave into the ring with the masterNode
	slaveNode := storagerpc.Node{HostPort: selfHostPort, NodeId: nodeId, Master: false}
	args := &storagerpc.RegisterArgs{ServerInfo: slaveNode}
	var reply storagerpc.RegisterReply
	// break out when status == storagerpc.OK
	for reply.Status = storagerpc.NotReady; reply.Status == storagerpc.NotReady; time.Sleep(time.Second) {
		if err := cli.Call("CohortStorageServer.RegisterServer", args, &reply); err != nil {
			log.Println("Failed to RegisterServer: ", err)
			return nil, err
		}
	}

	ss.servers = reply.Servers

	for errCount := 0; ; errCount++ {
		err := rpc.RegisterName("CohortStorageServer", storagerpc.Wrap(ss))
		if err != nil {
			if errCount == 5 {
				return nil, err
			}
			time.Sleep(time.Second)
			continue
		} else {
			break
		}
	}

	listener, err := net.Listen("tcp", selfHostPort)
	if err != nil {
		return nil, err
	}

	rpc.HandleHTTP()
	go http.Serve(listener, nil)

	return ss, nil
}