Пример #1
0
/**@brief Get value given a key for storage server
 * @param key
 * @return value
 * @return error
 */
func (ls *Libstore) iGet(key string) (string, error) {
	var cli *rpc.Client
	var args storageproto.GetArgs = storageproto.GetArgs{key, false, ls.Addr}
	var reply storageproto.GetReply
	var err error

	//try cache first
	if tmp, err := ls.Leases.Get(key, &args); err == nil {
		reply.Value = tmp.(string)
		return reply.Value, nil
	}

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

	//lsplog.Vlogf(0, "libstore Get %s\n", key)

	cli, err = ls.GetServer(key)
	if lsplog.CheckReport(1, err) {
		return "", err
	}

	//listen on no port to accept revoke
	if ls.Addr == "" {
		args.WantLease = false
	}

	//lsplog.Vlogf(0, "Get args:%v\n", args)

	err = cli.Call("StorageRPC.Get", &args, &reply)
	if lsplog.CheckReport(1, err) {
		return "", err
	}

	//lsplog.Vlogf(0, "Get reply:%v#!!\n", reply)
	//fmt.Printf("Get reply granted:%v#!#\n", reply.Lease.Granted)

	if reply.Lease.Granted {
		ls.Leases.LeaseGranted(key, reply.Value, reply.Lease)
	}

	if reply.Status != storageproto.OK {
		return "", MakeErr("Get()", reply.Status)
	}

	return reply.Value, nil
}
Пример #2
0
func (pc *ProxyCounter) GetList(args *storageproto.GetArgs, reply *storageproto.GetListReply) error {
	if pc.override {
		reply.Status = pc.overrideStatus
		return pc.overrideErr
	}
	byteCount := len(args.Key)
	if args.WantLease {
		atomic.AddUint32(&pc.leaseRequestCount, 1)
	}
	if pc.disableLease {
		args.WantLease = false
	}
	err := pc.srv.Call("StorageRPC.GetList", args, reply)
	for _, s := range reply.Value {
		byteCount += len(s)
	}
	if reply.Lease.Granted {
		if pc.overrideLeaseSeconds > 0 {
			reply.Lease.ValidSeconds = pc.overrideLeaseSeconds
		}
		atomic.AddUint32(&pc.leaseGrantedCount, 1)
	}
	atomic.AddUint32(&pc.rpcCount, 1)
	atomic.AddUint32(&pc.byteCount, uint32(byteCount))
	return err
}
Пример #3
0
func (ls *Libstore) checkWhetherLeaseNeeded(args *storageproto.GetArgs, key string) {
	if ls.flags == ALWAYS_LEASE {
		args.WantLease = true
		args.LeaseClient = ls.cacheCallbackHostPort
	} else if ls.cacheCallbackHostPort == "" {
		args.WantLease = false
	} else {
		ls.requestsLocker.Lock()
		if ls.requests[key] == nil {
			lsplog.Vlogf(3, "[checkWhetherLeaseNeeded] First requested")
			req := &Request{1, time.Now().Add(time.Duration(storageproto.QUERY_CACHE_SECONDS) * time.Second)}
			ls.requests[key] = req
		} else {
			req := ls.requests[key]
			if time.Now().Before(req.ts) {
				req.frequency = req.frequency + 1
				if req.frequency >= storageproto.QUERY_CACHE_THRESH {
					lsplog.Vlogf(3, "[checkWhetherLeaseNeeded] Going to ask for a lease")
					args.LeaseClient = ls.cacheCallbackHostPort
					args.WantLease = true
				} else {
					args.WantLease = false
				}
			} else {
				delete(ls.requests, key)
				args.WantLease = false
			}
		}
		ls.requestsLocker.Unlock()
	}
}
Пример #4
0
/**@brief given a key, get list of strings
 * @param key
 * @return string[]
 * @return error
 */
func (ls *Libstore) iGetList(key string) ([]string, error) {
	var cli *rpc.Client
	var args storageproto.GetArgs = storageproto.GetArgs{key, false, ls.Addr}
	var reply storageproto.GetListReply
	var err error

	//try cache first
	if tmp, err := ls.Leases.Get(key, &args); err == nil {
		reply.Value = tmp.([]string)
		return reply.Value, nil
	}

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

	cli, err = ls.GetServer(key)
	if lsplog.CheckReport(1, err) {
		return nil, err
	}

	//lsplog.Vlogf(0, "GetList args %v", args)

	err = cli.Call("StorageRPC.GetList", &args, &reply)
	if lsplog.CheckReport(1, err) {
		return nil, err
	}

	//lsplog.Vlogf(0, "GetList reply %v", reply)

	if reply.Lease.Granted {
		ls.Leases.LeaseGranted(key, reply.Value, reply.Lease)
	}

	if reply.Status != storageproto.OK {
		return nil, MakeErr("GetList()", reply.Status)
	}

	return reply.Value, nil
}
Пример #5
0
/**@brief Get is the most important function for cache, it will first clear all
 *        the expire entries, and then fetch the cache content or add the count
 *        of wantlease flag
 * @param key
 * @param GetArgs
 * @return interface{}(string or []string)
 * @return error
 */
func (cache *Cache) Get(
	key string, args *storageproto.GetArgs) (interface{}, error) {
	var entry *Entry
	var valid bool
	var data interface{}

	//fmt.Printf("Cache get: %s\n", key)

	cache.Lock.Lock()
	cache.ClearExpired()

	entry, valid = cache.Map[key]
	if !valid {
		entry = new(Entry)
		entry.Queries = list.New()
		entry.Queries.PushBack(time.Now())

		//fmt.Printf("Cache entry: %+v\n", *entry)
		//fmt.Printf("Queries: %+v\n", entry.Queries)
		cache.Map[key] = entry

		cache.Lock.Unlock()
		return "", lsplog.MakeErr("Not found.")
	}

	if entry.Granted {
		data = entry.Data
		cache.Lock.Unlock()

		//fmt.Printf("Already in Cache %s->%v\n", key, data)

		return data, nil
	}

	entry.Queries.PushBack(time.Now())

	//fmt.Printf("Cache entry: %v\n", *entry)

	if entry.Queries.Len() > storageproto.QUERY_CACHE_THRESH {
		//fmt.Printf("QUERY_CACHE_THRESH reached. Asking for lease.\n")
		args.WantLease = true
	}

	cache.Lock.Unlock()

	return "", lsplog.MakeErr("Not in cache")
}
Пример #6
0
func (ss *Storageserver) GetList(args *storageproto.GetArgs, reply *storageproto.GetListReply) error {

	//fmt.Println("called getList")
	//fmt.Printf("key: %v\n", args.Key)

	rightServer := ss.checkServer(args.Key)

	if rightServer == false {
		reply.Status = storageproto.EWRONGSERVER
		return nil
	}

	<-ss.leaseMapM
	leaseInfo, exists := ss.leaseMap[args.Key]
	ss.leaseMapM <- 1

	if exists == true {
		list := *leaseInfo.ClientKeys
		for i := 0; i < len(list); i++ {
			if list[i] == args.LeaseClient {
				args.WantLease = false
			}
		}
	}

	if args.WantLease == true {
		//grant lease
		//is there any reason to not grant it?
		reply.Lease.Granted = true
		reply.Lease.ValidSeconds = storageproto.LEASE_SECONDS
		if exists == true {
			<-leaseInfo.Mutex
			*leaseInfo.ClientKeys = append(*leaseInfo.ClientKeys, args.LeaseClient)
			leaseInfo.Mutex <- 1
			// fmt.Printf("**GETLIST added %v to %v lease list\n", args.LeaseClient, args.Key)
			ss.PrintLeaseMap()
		} else {
			keys := []string{}
			keys = append(keys, args.LeaseClient)
			<-ss.leaseMapM
			mutex := make(chan int, 1)
			mutex <- 1
			ss.leaseMap[args.Key] = &LeaseInfo{Mutex: mutex, ClientKeys: &keys}
			ss.leaseMapM <- 1
			// fmt.Printf("**GETLIST added %v to %v lease list\n", args.LeaseClient, args.Key)
			ss.PrintLeaseMap()
		}

		<-ss.clientLeaseMapM
		leaseExpiration := time.Now().Add((storageproto.LEASE_SECONDS + storageproto.LEASE_GUARD_SECONDS) * time.Second).UnixNano()
		ss.clientLeaseMap[args.LeaseClient+"@"+args.Key] = leaseExpiration
		ss.clientLeaseMapM <- 1

	} else {
		reply.Lease.Granted = false
		reply.Lease.ValidSeconds = 0
	}

	<-ss.listMapM
	list, ok := ss.listMap[args.Key]
	ss.listMapM <- 1

	if ok != true {
		reply.Status = storageproto.EITEMNOTFOUND
		reply.Value = []string{}
	} else {
		reply.Status = storageproto.OK
		reply.Value = list
	}

	return nil
}