frangipani

package
v0.0.0-...-6819f01 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 20, 2022 License: GPL-3.0 Imports: 19 Imported by: 0

README

Explore Project: KV Raft Based On Frangipani

The idea of this project originated from the testing requirements in lab 3 - KV Raft.

WARN: this directory should be located under 6.824/src/. To test the code, you MUST implement the code in 6.824/raft first!!!

NOTE: I limited the performance of frangipani by adding a time.Sleep(5*time.Millisecond) before a client executing PutAppend. Otherwise, the system will execute too many PutAppends, consuming all memory and forcing the OS to abort the testing program.

TO unleash the full power of frangipani, please comment the time.Sleep statement in client.go:105.

Please refer to 6.824/docs/frangipani for detailed report.

Documentation

Index

Constants

View Source
const (
	OK             = "OK"
	ErrNoKey       = "ErrNoKey"
	ErrWrongLeader = "ErrWrongLeader"
	ErrRejectRenew = "ErrReject"
	ErrDup         = "ErrDup"
	ErrLocked      = "ErrLocked"
)
View Source
const Debug = true

Variables

This section is empty.

Functions

This section is empty.

Types

type Clerk

type Clerk struct {
	// contains filtered or unexported fields
}

func MakeClerk

func MakeClerk(servers []*labrpc.ClientEnd) *Clerk

func (*Clerk) Append

func (ck *Clerk) Append(key string, value string)

func (*Clerk) Get

func (ck *Clerk) Get(key string) string

fetch the current value for a key. returns "" if the key does not exist. keeps trying forever in the face of all other errors.

you can send an RPC with code like this: ok := ck.servers[i].Call("KVServer.Get", &args, &reply)

the types of args and reply (including whether they are pointers) must match the declared types of the RPC handler function's arguments. and reply must be passed as a pointer.

func (*Clerk) Put

func (ck *Clerk) Put(key string, value string)

func (*Clerk) PutAppend

func (ck *Clerk) PutAppend(key string, value string, op string)

shared by Put and Append.

you can send an RPC with code like this: ok := ck.servers[i].Call("KVServer.PutAppend", &args, &reply)

the types of args and reply (including whether they are pointers) must match the declared types of the RPC handler function's arguments. and reply must be passed as a pointer.

type ClerkMetaData

type ClerkMetaData struct {
	// contains filtered or unexported fields
}

type Err

type Err string

type GetArgs

type GetArgs struct {
	Key string
	// You'll have to add definitions here.
	ClerkID int64
}

type GetReply

type GetReply struct {
	Err        Err
	Value      string
	IssuedTime []byte // use GobDecode to decode
}

type KVServer

type KVServer struct {
	// contains filtered or unexported fields
}

func StartKVServer

func StartKVServer(servers []*labrpc.ClientEnd, me int, persister *raft.Persister, maxraftstate int) *KVServer

------------------------------------------------------------------------------- servers[] contains the ports of the set of servers that will cooperate via Raft to form the fault-tolerant key/value service. me is the index of the current server in servers[]. the k/v server should store snapshots through the underlying Raft implementation, which should call persister.SaveStateAndSnapshot() to atomically save the Raft state along with the snapshot. the k/v server should snapshot when Raft's saved state exceeds maxraftstate bytes, in order to allow Raft to garbage-collect its log. if maxraftstate is -1, you don't need to snapshot. StartKVServer() must return quickly, so it should start goroutines for any long-running work.

func (*KVServer) Get

func (kv *KVServer) Get(args *GetArgs, reply *GetReply)

func (*KVServer) Kill

func (kv *KVServer) Kill()

------------------------------------------------------------ the tester calls Kill() when a KVServer instance won't be needed again. for your convenience, we supply code to set rf.dead (without needing a lock), and a killed() method to test rf.dead in long-running loops. you can also add your own code to Kill(). you're not required to do anything about this, but it may be convenient (for example) to suppress debug output from a Kill()ed instance.

func (*KVServer) PutAppend

func (kv *KVServer) PutAppend(args *PutAppendArgs, reply *PutAppendReply)

func (*KVServer) RenewLease

func (kv *KVServer) RenewLease(args *RenewLeaseArgs, reply *RenewLeaseReply)

This op does not need to be replicated and can be immediately executed on the leader. But leader should ensure it is the newest. i.e. ReadReady

type LockManagerClient

type LockManagerClient struct {
	// contains filtered or unexported fields
}

Client side lock manager.

func (*LockManagerClient) GetLockedKeySet

func (lm *LockManagerClient) GetLockedKeySet() []string

func (*LockManagerClient) Init

func (lm *LockManagerClient) Init()

func (*LockManagerClient) IsLocked

func (lm *LockManagerClient) IsLocked(key string) bool

func (*LockManagerClient) Lock

func (lm *LockManagerClient) Lock(key string, issuedTime time.Time)

func (*LockManagerClient) LockExpired

func (lm *LockManagerClient) LockExpired(key string) bool

func (*LockManagerClient) LockRevoked

func (lm *LockManagerClient) LockRevoked(key string) bool

func (*LockManagerClient) RenewLock

func (lm *LockManagerClient) RenewLock(key string, issuedTime time.Time)

func (*LockManagerClient) Unlock

func (lm *LockManagerClient) Unlock(key string)

type LockManagerServer

type LockManagerServer struct {
	LockTable map[string]int64 // locked key -> clerkID
	CanRenew  map[string]bool
}

Server side lock manger.

func (*LockManagerServer) Init

func (lm *LockManagerServer) Init()

func (*LockManagerServer) IsLocked

func (lm *LockManagerServer) IsLocked(key string) bool

Query the lock table to see if the key is locked by anyone. It will disable the renewing of the lock, because when called, there is another clerk who wants to lock the key.

func (*LockManagerServer) IsLockedBy

func (lm *LockManagerServer) IsLockedBy(key string, clerkID int64) bool

Query the lock table to see if the key is locked by the clerk. It will NOT disable the renewing of the lock.

func (*LockManagerServer) Lock

func (lm *LockManagerServer) Lock(key string, clerkID int64) bool

func (*LockManagerServer) RenewLock

func (lm *LockManagerServer) RenewLock(key string, clerkID int64) bool

func (*LockManagerServer) Unlock

func (lm *LockManagerServer) Unlock(key string)

type Op

type Op struct {
	// Your definitions here.
	// Field names must start with capital letters,
	// otherwise RPC will break.
	OpType  string // either "Put" or "Get". Put will release the lock, while Get will acquire the lock.
	KVMap   map[string]string
	ClerkID int64
	SeqNo   int
}

type PutAppendArgs

type PutAppendArgs struct {
	KVMap map[string]string
	// You'll have to add definitions here.
	// Field names must start with capital letters,
	// otherwise RPC will break.
	ClerkID int64
	SeqNo   int
}

Put or Append

type PutAppendReply

type PutAppendReply struct {
	Err Err
}

type RenewLeaseArgs

type RenewLeaseArgs struct {
	ClerkID int64
	Keys    []string
}

type RenewLeaseReply

type RenewLeaseReply struct {
	IssuedTime [][]byte // each element is an encoded time.Time
	Err        Err
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL