6.5840/src/shardkv1/shardctrler/shardctrler.go
Frans Kaashoek 43a3ba2a00 update
2025-01-31 12:47:59 -05:00

116 lines
3.2 KiB
Go

package shardctrler
//
// Shardctrler implemented as a clerk.
//
import (
"sync/atomic"
"6.5840/kvraft1"
"6.5840/kvsrv1/rpc"
"6.5840/kvtest1"
"6.5840/shardkv1/shardcfg"
"6.5840/tester1"
)
const (
ErrDeposed = "ErrDeposed"
)
// The query clerk must support only Query(); it is intended for use
// by shardkv clerks to read the current configuration (see
// ../client.go).
type QueryClerk struct {
kvtest.IKVClerk
// Your data here.
}
// Make a query clerk for controller's kvraft group to invoke just
// Query()
func MakeQueryClerk(clnt *tester.Clnt, servers []string) *QueryClerk {
qck := &QueryClerk{
IKVClerk: kvraft.MakeClerk(clnt, servers),
}
// Your code here.
return qck
}
// Return the current configuration. You can use Get() to retrieve
// the string representing the configuration and shardcfg.ToShardCfg
// to unmarshal the string into a ShardConfig.
func (qck *QueryClerk) Query() (*shardcfg.ShardConfig, rpc.Tversion) {
// Your code here.
return nil, 0
}
// ShardCtrlerClerk for the shard controller. It implements the
// methods for Init(), Join(), Leave(), etc.
type ShardCtrlerClerk struct {
clnt *tester.Clnt
deposed int32 // set by Stepdown()
// Your data here.
}
// Make a ShardCltlerClerk for the shard controller, which stores its
// state in a kvraft group. You can call (and implement) the
// MakeClerk method in client.go to make a kvraft clerk for the kvraft
// group with the servers `servers`.
func MakeShardCtrlerClerk(clnt *tester.Clnt, servers []string) *ShardCtrlerClerk {
sck := &ShardCtrlerClerk{clnt: clnt}
// Your code here.
return sck
}
// Called once by the tester to supply the first configuration. You
// can marshal ShardConfig into a string using shardcfg.String(), and
// then Put it in the kvraft group for the controller at version 0.
// You can pick the key to name the configuration.
func (sck *ShardCtrlerClerk) Init(cfg *shardcfg.ShardConfig) rpc.Err {
// Your code here
return rpc.OK
}
// Add group gid. Use shardcfg.JoinBalance() to compute the new
// configuration; the supplied `srvrs` are the servers for the new
// group. You can find the servers for existing groups in the
// configuration (which you can retrieve using Query()) and you can
// make a clerk for a group by calling shardgrp.MakeClerk(sck.clnt,
// servers), and then invoke its Freeze/InstallShard methods.
func (sck *ShardCtrlerClerk) Join(gid tester.Tgid, srvs []string) rpc.Err {
// Your code here
return rpc.ErrNoKey
}
// Group gid leaves. You can use shardcfg.LeaveBalance() to compute
// the new configuration.
func (sck *ShardCtrlerClerk) Leave(gid tester.Tgid) rpc.Err {
// Your code here
return rpc.ErrNoKey
}
// the tester calls Stepdown() to force a ctrler to step down while it
// is perhaps in the middle of a join/move. for your convenience, we
// also supply isDeposed() method to test rf.dead in long-running
// loops
func (sck *ShardCtrlerClerk) Stepdown() {
atomic.StoreInt32(&sck.deposed, 1)
}
func (sck *ShardCtrlerClerk) isDeposed() bool {
z := atomic.LoadInt32(&sck.deposed)
return z == 1
}
// Return the current configuration
func (sck *ShardCtrlerClerk) Query() (*shardcfg.ShardConfig, rpc.Tversion, rpc.Err) {
// Your code here.
return nil, 0, ""
}