Example #1
0
/**@brief append newitem to list
 * @param key
 * @param newitem
 * @return error
 */
func (ls *Libstore) iAppendToList(key, newitem string) error {
	var cli *rpc.Client
	var args storageproto.PutArgs = storageproto.PutArgs{key, newitem}
	var reply storageproto.PutReply
	var err error

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

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

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

	//lsplog.Vlogf(0, "AppendToList reply %v\n", reply)

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

	return nil
}
Example #2
0
/**@brief add subscription to certain user
 * @param SubscriptionArgs
 * @param SubscriptionReply
 * @return error
 */
func (ts *Tribserver) AddSubscription(
	args *tribproto.SubscriptionArgs,
	reply *tribproto.SubscriptionReply) error {
	var fllw_key string
	var trib_key string
	var err error

	//check whether userid exist
	trib_key = fmt.Sprintf("%s:T", args.Userid)
	_, err = ts.Store.GetList(trib_key)
	if lsplog.CheckReport(1, err) {
		reply.Status = tribproto.ENOSUCHUSER
		return nil
	}

	//check whether target user exist
	trib_key = fmt.Sprintf("%s:T", args.Targetuser)
	_, err = ts.Store.GetList(trib_key)
	if lsplog.CheckReport(1, err) {
		reply.Status = tribproto.ENOSUCHTARGETUSER
		return nil
	}

	fllw_key = fmt.Sprintf("%s:F", args.Userid)
	err = ts.Store.AppendToList(fllw_key, args.Targetuser)

	if lsplog.CheckReport(1, err) {
		reply.Status = tribproto.EEXISTS
	} else {
		reply.Status = tribproto.OK
	}

	return nil
}
Example #3
0
/**@brief helper function for sorting
 * @param server master storage server addr
 * @param myhostport trib server's port
 * @param flags
 * @return *Libstore
 * @return error
 */
func iNewLibstore(server, myhostport string, flags int) (*Libstore, error) {
	var store Libstore
	var master *rpc.Client
	var args storageproto.GetServersArgs
	var reply storageproto.RegisterReply
	var err error

	store.Addr = myhostport
	store.Flags = flags

	if store.Addr != "" {
		rpc.Register(cacherpc.NewCacheRPC(&store))
	}

	lsplog.Vlogf(3, "libstore try to connect to master storage %s", server)

	master, err = rpc.DialHTTP("tcp", server)
	if lsplog.CheckReport(1, err) {
		return nil, err
	}

	lsplog.Vlogf(3, "try to call GetServers")

	master.Call("StorageRPC.GetServers", &args, &reply)

	if !reply.Ready {
		for i := 0; i < 5; i++ {
			time.Sleep(1000 * time.Millisecond)
			master.Call("StorageRPC.GetServers", &args, &reply)
		}
	}

	err = master.Close()
	if lsplog.CheckReport(1, err) {
		lsplog.Vlogf(3, "WARNING close master failed")
	}

	// couldn't get list of servers from master
	if (reply.Ready == false) || (reply.Servers == nil) {
		return nil, lsplog.MakeErr("Storage system not ready.")
	}

	store.Nodes = reply.Servers
	store.RPCConn = make([]*rpc.Client, len(store.Nodes))

	sort.Sort(store.Nodes)
	/*
	  for i := 0; i < len(store.Nodes); i++ {
	    fmt.Printf("%v\n", store.Nodes[i])
	  }*/

	store.Leases = cache.NewCache()
	if lsplog.CheckReport(1, err) {
		return nil, err
	}

	lsplog.Vlogf(3, "libstore create complete")

	return &store, nil
}
Example #4
0
/**@brief store key-value into backend
 * @param key string
 * @param value string
 * @return error
 */
func (ls *Libstore) iPut(key, value string) error {
	var cli *rpc.Client
	var args storageproto.PutArgs = storageproto.PutArgs{key, value}
	var reply storageproto.PutReply
	var err error

	//lsplog.Vlogf(0, "libstore put %s->%s!", key, value)

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

	//lsplog.Vlogf(0, "libstore getserver complete!")
	//lsplog.Vlogf(0, "put args %v\n", args)
	/*
	  fmt.Printf("put args %v\n", args)
	  fmt.Printf("here2\n")
	*/

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

	//fmt.Printf("put reply %v\n", reply)
	//lsplog.Vlogf(0, "put reply %v\n", reply)

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

	return nil
}
Example #5
0
/**@brief create a new user
 * @param CreateUserArgs
 * @param CreateUserReply
 * @return error
 */
func (ts *Tribserver) CreateUser(
	args *tribproto.CreateUserArgs, reply *tribproto.CreateUserReply) error {

	var trib_key, fllw_key string
	var err error

	trib_key = fmt.Sprintf("%s:T", args.Userid)
	fllw_key = fmt.Sprintf("%s:F", args.Userid)

	_, err = ts.Store.GetList(trib_key)
	if err == nil {
		lsplog.Vlogf(0, "try create user %s , but exist !", args.Userid)
		reply.Status = tribproto.EEXISTS
		return nil
	}

	err = ts.Store.Put(trib_key, "")
	if lsplog.CheckReport(2, err) {
		lsplog.Vlogf(0, "user %s , trib_key exist !", args.Userid)
		reply.Status = tribproto.EEXISTS
		return nil
	}

	err = ts.Store.Put(fllw_key, "")
	if lsplog.CheckReport(2, err) {
		reply.Status = tribproto.EEXISTS
		return nil
	}

	reply.Status = tribproto.OK

	lsplog.Vlogf(0, "create user status %d", tribproto.OK)

	return nil
}
Example #6
0
/**@brief collect all tribbles from all users followed
 * @param CreateUserArgs
 * @param CreateUserReply
 * @return error
 */
func (ts *Tribserver) GetTribblesBySubscription(
	args *tribproto.GetTribblesArgs, reply *tribproto.GetTribblesReply) error {
	var fllw_key string
	var fllw_ids []string
	var err error
	var getArgs tribproto.GetTribblesArgs
	var getReply tribproto.GetTribblesReply
	var tribs Tribs

	fllw_key = fmt.Sprintf("%s:F", args.Userid)
	fllw_ids, err = ts.Store.GetList(fllw_key)
	if lsplog.CheckReport(1, err) {
		reply.Status = tribproto.ENOSUCHUSER
		reply.Tribbles = nil
		return nil
	}

	fmt.Printf("complete geting list %d\n", len(fllw_ids))

	reply.Status = tribproto.OK

	for i := 0; i < len(fllw_ids); i++ {
		getArgs.Userid = fllw_ids[i]
		err = ts.GetTribbles(&getArgs, &getReply)

		fmt.Printf("try geting subscription user %d\n", i+1)

		if lsplog.CheckReport(1, err) {
			reply.Status = tribproto.ENOSUCHTARGETUSER
			reply.Tribbles = nil
			return nil
		}

		reply.Tribbles = append(reply.Tribbles, getReply.Tribbles...)
	}

	fmt.Printf("complete getting all subscribed tribs\n")

	//to satisfy go compiler type check
	tribs = reply.Tribbles
	//sort in time order
	sort.Sort(tribs)

	if len(reply.Tribbles) > 100 {
		reply.Tribbles = reply.Tribbles[:100]
	}
	return nil
}
Example #7
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
}
Example #8
0
/**@brief Hashes a key and returns an RPC connection to the server
         responsible for storing it. If an RPC connection is not
         established, create one and store it for future accesses.
* @param server master server addr
* @param myhostport trib server's port
* @param flags
* @return *Libstore
* @return error
*/
func (ls *Libstore) GetServer(key string) (*rpc.Client, error) {
	var id uint32
	var svr int
	var err error

	//lsplog.Vlogf(3, "libstore GetServer Invoked")

	id = Storehash(strings.Split(key, ":")[0])

	// returns the index of the first server after the key's hash
	svr = sort.Search(
		len(ls.Nodes), func(i int) bool { return ls.Nodes[i].NodeID >= id })
	svr = (svr) % len(ls.Nodes)

	//lsplog.Vlogf(0, "%s -> %d (%d)\n", key, id, svr)

	if ls.RPCConn[svr] == nil {
		lsplog.Vlogf(0, "Caching RPC connection to %s.\n", ls.Nodes[svr].HostPort)
		ls.RPCConn[svr], err = rpc.DialHTTP("tcp", ls.Nodes[svr].HostPort)
		if lsplog.CheckReport(1, err) {
			return nil, err
		}
	}

	return ls.RPCConn[svr], nil
}
Example #9
0
/**@brief Post Tribbles
 * @param PostTribbleArgs
 * @param PostTribbleReply
 * @return error
 */
func (ts *Tribserver) PostTribble(
	args *tribproto.PostTribbleArgs, reply *tribproto.PostTribbleReply) error {
	var trib_key string
	var trib tribproto.Tribble
	var enc []byte
	var err error

	//do not allow empty post
	if args.Contents == "" {
		return nil
	}

	trib_key = fmt.Sprintf("%s:T", args.Userid)
	_, err = ts.Store.GetList(trib_key)
	if lsplog.CheckReport(1, err) {
		reply.Status = tribproto.ENOSUCHUSER
		return nil
	}

	err = ts.Store.AppendToList(trib_key, strconv.Itoa(ts.Id))
	if lsplog.CheckReport(1, err) {
		reply.Status = tribproto.EEXISTS
		return nil
	}

	trib.Userid = args.Userid
	trib.Posted = time.Now()
	trib.Contents = args.Contents

	enc, err = json.Marshal(trib)
	if lsplog.CheckReport(1, err) {
		reply.Status = tribproto.OK
		return err
	}

	err = ts.Store.Put(strconv.Itoa(ts.Id), string(enc))
	if lsplog.CheckReport(1, err) {
		reply.Status = tribproto.OK
		return err
	}

	reply.Status = tribproto.OK
	ts.Id++

	return nil
}
Example #10
0
func boundedWaitCall(args *storageproto.RevokeLeaseArgs,
	reply *storageproto.RevokeLeaseReply, con *rpc.Client, doneChan chan int) {

	err := con.Call("CacheRPC.RevokeLease", &args, &reply)
	if lsplog.CheckReport(1, err) {
		fmt.Printf("Try revoke lease holder failed\n!")
	}

	doneChan <- 1
	return
}
Example #11
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
}
Example #12
0
/**@brief remove a item from backend storage
 * @param key
 * @param removeitem
 * @return error
 */
func (ls *Libstore) iRemoveFromList(key, removeitem string) error {
	var cli *rpc.Client
	var args storageproto.PutArgs = storageproto.PutArgs{key, removeitem}
	var reply storageproto.PutReply
	var err error

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

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

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

	return nil
}
Example #13
0
/**@brief get posted tribbles
 * @param GetTribblesArgs
 * @param GetTribblesReply
 * @return error
 */
func (ts *Tribserver) GetTribbles(
	args *tribproto.GetTribblesArgs, reply *tribproto.GetTribblesReply) error {
	var trib_key string
	var trib_ids []string
	var trib_enc string
	var err error
	var length int

	trib_key = fmt.Sprintf("%s:T", args.Userid)

	trib_ids, err = ts.Store.GetList(trib_key)
	if lsplog.CheckReport(1, err) {
		reply.Status = tribproto.ENOSUCHUSER
		reply.Tribbles = nil
		return nil
	}

	reply.Status = tribproto.OK
	if len(trib_ids) > 100 {
		length = 100
	} else {
		length = len(trib_ids)
	}

	reply.Tribbles = make([]tribproto.Tribble, length)

	for i := 0; i < length; i++ {
		trib_enc, err = ts.Store.Get(trib_ids[len(trib_ids)-1-i])
		if lsplog.CheckReport(1, err) {
			return lsplog.MakeErr("Get Tribbles Message Error")
		}
		//fmt.Printf("unmarshal string %s\n", trib_enc)
		_ = json.Unmarshal([]byte(trib_enc), &(reply.Tribbles[i]))
	}

	return nil
}
Example #14
0
/**@brief get tribbles from subscriped users
 * @param GetSubscriptionsArgs
 * @param GetSubscriptionsReply
 * @return error
 */
func (ts *Tribserver) GetSubscriptions(
	args *tribproto.GetSubscriptionsArgs,
	reply *tribproto.GetSubscriptionsReply) error {
	var fllw_key string
	var fllw_ids []string
	var err error

	fllw_key = fmt.Sprintf("%s:F", args.Userid)
	fllw_ids, err = ts.Store.GetList(fllw_key)
	if lsplog.CheckReport(1, err) {
		reply.Status = tribproto.ENOSUCHUSER
		reply.Userids = nil
		return nil
	}

	reply.Status = tribproto.OK
	reply.Userids = fllw_ids

	return nil
}
Example #15
0
/**@brief create a new tribserver
 * @param string
 * @param string
 * @return *tribserver
 */
func NewTribserver(storagemaster, myhostport string) *Tribserver {
	lsplog.SetVerbose(3)
	fmt.Printf("st_master:%s, port:%s\n", storagemaster, myhostport)

	var svr *Tribserver = new(Tribserver)
	var err error

	lsplog.Vlogf(3, "try to create libstore")
	// libstore.NONE forces no leases on Get and GetList requests
	svr.Store, err =
		libstore.NewLibstore(storagemaster, myhostport, libstore.NONE)

	if lsplog.CheckReport(1, err) {
		return nil
	}

	svr.Id = 1

	return svr
}
Example #16
0
func (ss *Storageserver) revokeLeaseHolders(key string) error {
	var args storageproto.RevokeLeaseArgs
	var reply storageproto.RevokeLeaseReply
	var doneChan chan int

	entry := (ss.leasePool[key])

	(*(entry.pending)) = true
	fmt.Printf("set key %s pending\n", key)

	for _, holder := range entry.holders {

		if isTimeout(holder) {
			fmt.Printf("revoke holder %s expire\n", key)
			continue
		}

		svr, err := rpc.DialHTTP("tcp", holder.holderAddr)
		if lsplog.CheckReport(1, err) {
			fmt.Printf("revoke dial %s failed", holder.holderAddr)
		}

		args.Key = key

		//ensure rpc is bounded waiting
		go boundedWaitCall(&args, &reply, svr, doneChan)

		select {
		case <-doneChan:
			break
		case <-time.After((storageproto.LEASE_SECONDS +
			storageproto.LEASE_GUARD_SECONDS) * time.Second):
			break
		}

		fmt.Printf("revoke complete rpc to holder %s\n", holder.holderAddr)
	}
	(*(entry.pending)) = false
	fmt.Printf("cannel key %s pending !\n", key)
	return nil
}
Example #17
0
func NewStorageserver(master string, numnodes int, portnum int,
	nodeid uint32) *Storageserver {

	lsplog.SetVerbose(3)
	fmt.Println("Create New Storage Server")
	fmt.Printf("master:%s, numnodes:%d, portnum:%d, nodeid:%d\n",
		master, numnodes, portnum, nodeid)
	var masterNode *rpc.Client
	var regArgs storageproto.RegisterArgs
	var regReply storageproto.RegisterReply
	var storage Storageserver
	var err error
	var nodes = make(map[storageproto.Node]bool)

	storage.nodeid = nodeid
	storage.leasePool = make(map[string]leaseEntry)

	selfAddr := fmt.Sprintf("localhost:%d", portnum)

	if master == selfAddr {
		fmt.Printf("for master node\n")

		//for master node
		storage.isMaster = true
		storage.portnum = portnum
		//storage.portnum = DEFAULT_MASTER_PORT
		storage.nodes = nodes
		storage.numnodes = numnodes

		//add masternode itself to nodes table
		//hostport := fmt.Sprintf("localhost:%d", DEFAULT_MASTER_PORT)
		self := storageproto.Node{master, nodeid}
		storage.nodes[self] = true
	} else {

		masterNode, err = rpc.DialHTTP("tcp", master)
		if lsplog.CheckReport(1, err) {
			return nil
		}

		regArgs.ServerInfo.HostPort = fmt.Sprintf("localhost:%d", portnum)
		regArgs.ServerInfo.NodeID = nodeid

		//for slave node
		storage.isMaster = false
		storage.portnum = portnum

		fmt.Printf("for slave node\n")
		fmt.Printf("begin try $$$\n")

		for i := 0; (regReply.Ready == false) && (i < 10); i++ {
			fmt.Printf("try %d times\n", i)
			masterNode.Call("StorageRPC.Register", &regArgs, &regReply)
			/*
			   if lsplog.CheckReport(1, err) {
			     lsplog.Vlogf(3, "slave %d call RegisterServer %d time failed",
			                                                 i + 1, portnum)
			   }*/
			time.Sleep(1000 * time.Millisecond)
		}
	}

	storage.hash = make(map[string][]byte)

	return &storage
}
Example #18
0
func main() {

	serverAddress := "127.0.0.1"
	serverPort := fmt.Sprintf("%d", 9010)
	client, _ := NewTribbleclient(serverAddress, serverPort)

	//create user
	status, err := client.CreateUser("1")
	fmt.Printf("status:%d\n", status)
	if lsplog.CheckReport(0, err) {
		return
	}

	//  //test duplicate create user !
	//  status, err = client.CreateUser("1")
	//  fmt.Printf("status:%d\n", status)
	//
	//  //test nonexist user post message
	//  status, err = client.PostTribble("2", "test1")
	//  fmt.Printf("status:%d\n", status)
	//  if lsplog.CheckReport(0, err) {
	//    return
	//  }

	//test post msg
	status, err = client.PostTribble("1", "test1")
	fmt.Printf("status:%d\n", status)

	//test get msg
	tribbles, status, err := client.GetTribbles("1")
	fmt.Printf("status:%d\n", status)
	PrintTribbles(tribbles)

	//create user 2
	status, err = client.CreateUser("2")
	fmt.Printf("status:%d\n", status)

	//user2 post message
	status, err = client.PostTribble("2", "test2")
	fmt.Printf("status:%d\n", status)

	//user2 get message
	tribbles, status, err = client.GetTribbles("2")
	fmt.Printf("status:%d\n", status)
	PrintTribbles(tribbles)

	//test user1 addsubscription user2
	status, err = client.AddSubscription("1", "2")
	fmt.Printf("status:%d\n", status)

	//  //test user1 getsubscription
	//  users, status, err := client.GetSubscriptions("1")
	//  fmt.Printf("status:%d\n", status)
	//  fmt.Println(strings.Join(users, ","))

	//test GetTribblesBySubscription
	tribbles, status, err = client.GetTribblesBySubscription("1")
	fmt.Printf("status:%d\n", status)
	PrintTribbles(tribbles)

	//test removesubscription
	status, err = client.RemoveSubscription("1", "2")
	fmt.Printf("status:%d\n", status)

	//test GetTribblesBySubscription
	tribbles, status, err = client.GetTribblesBySubscription("1")
	fmt.Printf("status:%d\n", status)
	PrintTribbles(tribbles)

}