func (ss *StorageServer) RegisterServer(
	args *sp.RegisterArgs, reply *sp.RegisterReply) error {

	lsplog.Vlogf(3, "[StorageServer] RegisterServer invoked\n")

	if ss.ismaster == false {
		lsplog.Vlogf(2, "[StorageServer] calling non-master node for register\n")
		return lsplog.MakeErr("calling non-master node for register")
	}

	ss.mu.Lock()
	defer ss.mu.Unlock()

	if _, ok := ss.nodes[args.ServerInfo]; !ok {
		ss.nodes[args.ServerInfo] = true
	}

	reply.Ready = false
	if ss.numnodes == len(ss.nodes) {
		reply.Ready = true
		for node, _ := range ss.nodes {
			reply.Servers = append(reply.Servers, node)
		}
	}
	return nil
}
Beispiel #2
0
func (c *Cache) Get(key string, args *sp.GetArgs) (interface{}, error) {
	c.mu.Lock()
	c.evict()

	e, ok := c.cache[key]
	if !ok {
		e = &entry{ll: list.New()}
		c.cache[key] = e
	}
	c.mu.Unlock()

	e.mu.Lock()
	defer e.mu.Unlock()

	if e.granted {
		return e.val, nil
	}

	e.ll.PushBack(time.Now())
	if e.ll.Len() > sp.QUERY_CACHE_THRESH {
		args.WantLease = true
	}

	return nil, lsplog.MakeErr("key nonexist in cache")
}
func (ls *Libstore) iGet(key string) (string, error) {
	var args sp.GetArgs = sp.GetArgs{key, false, ls.hostport}
	var reply sp.GetReply

	if val, err := ls.leases.Get(key, &args); err == nil {
		return val.(string), nil
	}

	if (ls.flags & ALWAYS_LEASE) != 0 {
		args.WantLease = true
	}

	cli, err := ls.pickServer(key)
	if err != nil {
		return "", err
	}

	err = cli.Call("StorageRPC.Get", &args, &reply)
	if err != nil {
		lsplog.Vlogf(3, "[Libstore] rpc call error: %v\n", err)
		return "", err
	}

	if reply.Status != sp.OK {
		lsplog.Vlogf(3, "[Libstore] Get error, status=%d\n", reply.Status)
		return "", lsplog.MakeErr("Get error")
	}

	if reply.Lease.Granted {
		ls.leases.Grant(key, reply.Value, reply.Lease)
	}

	return reply.Value, nil
}
func (ss *StorageServer) GetServers(args *sp.GetServersArgs, reply *sp.RegisterReply) error {
	lsplog.Vlogf(3, "[StorageServer] GetServers invoked\n")

	if ss.ismaster == false {
		lsplog.Vlogf(2, "[StorageServer] calling non-master node for GetServers\n")
		return lsplog.MakeErr("calling non-master node for GetServers")
	}

	ss.mu.RLock()
	defer ss.mu.RUnlock()

	if ss.numnodes != len(ss.nodes) {
		reply.Ready = false
		return nil
	}

	for node, _ := range ss.nodes {
		reply.Servers = append(reply.Servers, node)
	}
	reply.Ready = true
	return nil
}
func iNewLibstore(master, myhostport string, flags int) (*Libstore, error) {
	lsplog.SetVerbose(3)

	if myhostport == "" {
		panic("[Libstore] hostport shouldn't be null")
	}

	cli, err := rpc.DialHTTP("tcp", master)
	if err != nil {
		lsplog.Vlogf(1, "[Libstore] DialHTTP error: %v\n", err)
		return nil, err
	}
	defer cli.Close()

	var args sp.GetServersArgs
	var reply sp.RegisterReply

	for i := 0; i < 5; i++ {
		cli.Call("StorageRPC.GetServers", &args, &reply)
		if reply.Ready {
			break
		}
	}
	if !reply.Ready {
		return nil, lsplog.MakeErr("StorageServer not ready")
	}

	ls := new(Libstore)

	ls.hostport = myhostport
	ls.flags = flags
	ls.nodes = reply.Servers
	ls.leases = cache.NewCache()
	ls.rpcConn = make([]*rpc.Client, len(ls.nodes))

	sort.Sort(ls.nodes)

	return ls, nil
}
func (ls *Libstore) iAppendToList(key, newitem string) error {
	cli, err := ls.pickServer(key)
	if err != nil {
		return err
	}

	var args sp.PutArgs
	var reply sp.PutReply

	args.Key, args.Value = key, newitem

	err = cli.Call("StorageRPC.AppendToList", &args, &reply)
	if err != nil {
		lsplog.Vlogf(3, "[Libstore] rpc call error: %v\n", err)
		return err
	}

	if reply.Status != sp.OK {
		lsplog.Vlogf(3, "[Libstore] AppendToList error, status=%d\n", reply.Status)
		return lsplog.MakeErr("AppendToList error")
	}
	return nil
}