6.824
6.824 copied to clipboard
About Lab4 ShardKV Challenge 2
Challenge 2 descirbe a situation
Say that some replica group G3, when transitioning to C, needs shard S1 from G1, and shard S2 from G2. We really want G3 > to immediately start serving a shard once it has received the necessary state, even if it is still waiting for some other shards. > For example, if G1 is down, G3 should still start serving requests for S2 once it receives the appropriate data from G2, despite the transition to C not yet having completed.
In your code, the reonfiguration code is an "atomic" operation. you should get all fetched shard data, and then write into raft and apply. And then it can serve for client.
Personally, it cannot do the above situation.
By the way, thanks for your sharing code which helped me a lot.
func (kv *ShardKV) getReconfigureEntry(nextConfig shardmaster.Config) (Op, bool) {
entry := Op{}
entry.Command = "reconfigure"
entry.Config = nextConfig
for i := 0; i < shardmaster.NShards; i++ {
entry.Data[i] = make(map[string]string)
}
entry.Ack = make(map[int64]int64)
ok := true
var ackMu sync.Mutex
var wg sync.WaitGroup
transferShards := kv.getShardsToTransfer(nextConfig)
for gid, shardIds := range transferShards {
wg.Add(1)
go func(gid int, args TransferShardArgs, reply TransferShardReply) {
defer wg.Done()
if kv.sendTransferShard(gid, &args, &reply) {
ackMu.Lock()
// copy only shards requested from that replica group to reconfigure args
for _, shardId := range args.ShardIds {
shardData := reply.Data[shardId]
for k, v := range shardData {
entry.Data[shardId][k] = v
}
}
// merge ack map from that replica group to reconfigure args
for clientId := range reply.Ack {
if _, ok := entry.Ack[clientId]; !ok || entry.Ack[clientId] < reply.Ack[clientId] {
entry.Ack[clientId] = reply.Ack[clientId]
}
}
ackMu.Unlock()
} else {
ok = false
}
}(gid, TransferShardArgs{Num: nextConfig.Num, ShardIds: shardIds}, TransferShardReply{})
}
wg.Wait()
return entry, ok
}