/**@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 }
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 }
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() } }
/**@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 }
/**@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") }
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 }