func (slv *slave) SendAuthToMaster() error { slv.mtx.Lock() var cli = slv.cli slv.mtx.Unlock() if cli == nil { return nil } if len(slv.adminPwd) == 0 { return nil } var p proto.PkgOneOp p.DbId = proto.AdminDbId p.Cmd = proto.CmdAuth p.RowKey = []byte(slv.adminPwd) var pkg = make([]byte, p.Length()) _, err := p.Encode(pkg) if err != nil { return err } cli.AddResp(pkg) return nil }
func myGet(in proto.PkgOneOp, au Authorize, wa *WriteAccess, t *testing.T) proto.PkgOneOp { var pkg = make([]byte, in.Length()) _, err := in.Encode(pkg) if err != nil { t.Fatalf("Encode failed: ", err) } pkg = testTbl.Get(&PkgArgs{in.Cmd, in.DbId, in.Seq, pkg}, au, wa) var out proto.PkgOneOp _, err = out.Decode(pkg) if err != nil { t.Fatalf("Decode failed: ", err) } if out.ErrCode < 0 { t.Fatalf("Failed with ErrCode %d", out.ErrCode) } if out.DbId != in.DbId || out.Seq != in.Seq || out.TableId != in.TableId { t.Fatalf("DbId/Seq/TableId mismatch") } if bytes.Compare(out.RowKey, in.RowKey) != 0 || bytes.Compare(out.ColKey, in.ColKey) != 0 { t.Fatalf("RowKey/ColKey mismatch") } if in.Cas == 0 && out.Cas != 0 { t.Fatalf("Invalid default Cas value") } return out }
func (ms *master) convertMigPkg(pkg []byte, head *proto.PkgHead) ([]byte, error) { _, err := head.Decode(pkg) if err != nil { return nil, err } if !ms.migration { return pkg, nil } switch head.Cmd { case proto.CmdIncr: fallthrough case proto.CmdDel: fallthrough case proto.CmdSet: var p proto.PkgOneOp _, err = p.Decode(pkg) if err != nil { return nil, err } if ms.slotId == ctrl.GetSlotId(p.DbId, p.TableId, p.RowKey) { return pkg, nil } else { return nil, nil } case proto.CmdSync: fallthrough case proto.CmdMIncr: fallthrough case proto.CmdMDel: fallthrough case proto.CmdMSet: var p proto.PkgMultiOp _, err = p.Decode(pkg) if err != nil { return nil, err } var kvs []proto.KeyValue for i := 0; i < len(p.Kvs); i++ { if ms.slotId == ctrl.GetSlotId(p.DbId, p.Kvs[i].TableId, p.Kvs[i].RowKey) { kvs = append(kvs, p.Kvs[i]) } } if len(kvs) == 0 { return nil, nil } else { p.Kvs = kvs pkg = make([]byte, p.Length()) _, err = p.Encode(pkg) if err != nil { return nil, err } return pkg, nil } } return nil, nil }
func (ms *master) syncStatus(key string, lastSeq uint64) { var p proto.PkgOneOp p.Cmd = proto.CmdSyncSt p.DbId = proto.AdminDbId p.Seq = lastSeq p.RowKey = []byte(key) var pkg = make([]byte, p.Length()) p.Encode(pkg) ms.cli.AddResp(pkg) }
func (srv *Server) syncStatus(req *Request) { var cliType uint32 = ClientTypeNormal if req.Cli != nil { cliType = req.Cli.ClientType() } switch cliType { case ClientTypeSlave: var in proto.PkgOneOp _, err := in.Decode(req.Pkg) if err != nil || len(in.RowKey) == 0 { return } rowKey := string(in.RowKey) switch rowKey { case store.KeyFullSyncEnd: srv.mc.SetStatus(ctrl.SlaveIncrSync) log.Printf("Switch sync status to SlaveIncrSync\n") case store.KeyIncrSyncEnd: var st = srv.mc.Status() srv.mc.SetStatus(ctrl.SlaveReady) var now = time.Now() srv.rwMtx.Lock() var lastTime = srv.readyTime srv.readyTime = now srv.rwMtx.Unlock() if st != ctrl.SlaveReady || now.Sub(lastTime).Seconds() > 120 { log.Printf("Switch sync status to SlaveReady") } case store.KeySyncLogMissing: srv.mc.SetStatus(ctrl.SlaveNeedClear) lastSeq, _ := srv.bin.GetMasterSeq() // Any better solution? log.Fatalf("Slave lastSeq %d is out of sync, please clear old data! "+ "(Restart may fix this issue)", lastSeq) } if req.Seq > 0 { in.RowKey = nil // Set it as an empty OP req.Pkg = make([]byte, in.Length()) in.Encode(req.Pkg) srv.sendResp(true, req, nil) } case ClientTypeNormal: log.Printf("User cannot send SYNCST command\n") case ClientTypeMaster: log.Printf("Slave SYNCST failed: [%d, %d]\n", req.DbId, req.Seq) req.Cli.Close() } }
func (srv *Server) replyOneOp(req *Request, errCode int8) { var out proto.PkgOneOp out.Cmd = req.Cmd out.DbId = req.DbId out.Seq = req.Seq out.ErrCode = errCode if out.ErrCode != 0 { out.CtrlFlag |= proto.CtrlErrCode } var pkg = make([]byte, out.Length()) _, err := out.Encode(pkg) if err != nil { log.Fatalf("Encode failed: %s\n", err) } srv.sendResp(false, req, pkg) }
// Get, Set, Del, Incr, ZGet, ZSet, ZDel, ZIncr func (c *Context) goOneOp(zop bool, cmd, tableId uint8, rowKey, colKey, value []byte, score int64, cas uint32, done chan *Call) (*Call, error) { call := c.cli.newCall(cmd, done) if call.err != nil { return call, call.err } var p proto.PkgOneOp p.Seq = call.seq p.DbId = c.dbId p.Cmd = call.cmd p.TableId = tableId p.RowKey = rowKey p.ColKey = colKey p.SetCas(cas) p.SetScore(score) p.SetValue(value) // ZGet, ZSet, ZDel, ZIncr if zop { p.PkgFlag |= proto.FlagZop } var pkgLen = p.Length() if pkgLen > proto.MaxPkgLen { c.cli.errCall(call, ErrInvPkgLen) return call, call.err } call.pkg = make([]byte, pkgLen) _, err := p.Encode(call.pkg) if err != nil { c.cli.errCall(call, err) return call, err } // put request pkg to sending channel c.cli.sending <- call return call, nil }
func mySet(in proto.PkgOneOp, au Authorize, wa *WriteAccess, expected bool, t *testing.T) proto.PkgOneOp { var pkg = make([]byte, in.Length()) _, err := in.Encode(pkg) if err != nil { t.Fatalf("Encode failed: ", err) } pkg, ok := testTbl.Set(&PkgArgs{in.Cmd, in.DbId, in.Seq, pkg}, au, wa) if ok != expected { if expected { t.Fatalf("Set failed") } else { t.Fatalf("Set should fail") } } var out proto.PkgOneOp _, err = out.Decode(pkg) if err != nil { t.Fatalf("Decode failed: ", err) } if expected { if out.ErrCode != 0 { t.Fatalf("Failed with ErrCode %d", out.ErrCode) } } if len(out.Value) != 0 || out.Score != 0 || out.Cas != 0 { t.Fatalf("Invalid default values") } if out.Seq != in.Seq || out.DbId != in.DbId || out.TableId != in.TableId { t.Fatalf("Seq/DbId/TableId mismatch") } if bytes.Compare(out.RowKey, in.RowKey) != 0 || bytes.Compare(out.ColKey, in.ColKey) != 0 { t.Fatalf("RowKey/ColKey mismatch") } return out }