mirror of
https://github.com/HDT3213/godis.git
synced 2025-10-05 08:46:56 +08:00
raft cluster
wip: raft does not care about migrating wip: optimize code wip: raft election wip wip: fix raft leader missing log entries wip fix a dead lock batch set slot route wip: raft persist wip refactor cluster suite remove relay rename relay2 refactor: allow customizing client factory test raft refactor re-balance avoid errors caused by inconsistent status on follower nodes during raft commits test raft election
This commit is contained in:
@@ -33,6 +33,10 @@ type DB struct {
|
||||
// use this mutex for complicated command only, eg. rpush, incr ...
|
||||
locker *lock.Locks
|
||||
addAof func(CmdLine)
|
||||
|
||||
// callbacks
|
||||
insertCallback database.KeyEventCallback
|
||||
deleteCallback database.KeyEventCallback
|
||||
}
|
||||
|
||||
// ExecFunc is interface for command executor
|
||||
@@ -165,7 +169,13 @@ func (db *DB) GetEntity(key string) (*database.DataEntity, bool) {
|
||||
|
||||
// PutEntity a DataEntity into DB
|
||||
func (db *DB) PutEntity(key string, entity *database.DataEntity) int {
|
||||
return db.data.Put(key, entity)
|
||||
ret := db.data.Put(key, entity)
|
||||
// db.insertCallback may be set as nil, during `if` and actually callback
|
||||
// so introduce a local variable `cb`
|
||||
if cb := db.insertCallback; ret > 0 && cb != nil {
|
||||
cb(db.index, key, entity)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// PutIfExists edit an existing DataEntity
|
||||
@@ -175,15 +185,28 @@ func (db *DB) PutIfExists(key string, entity *database.DataEntity) int {
|
||||
|
||||
// PutIfAbsent insert an DataEntity only if the key not exists
|
||||
func (db *DB) PutIfAbsent(key string, entity *database.DataEntity) int {
|
||||
return db.data.PutIfAbsent(key, entity)
|
||||
ret := db.data.PutIfAbsent(key, entity)
|
||||
// db.insertCallback may be set as nil, during `if` and actually callback
|
||||
// so introduce a local variable `cb`
|
||||
if cb := db.insertCallback; ret > 0 && cb != nil {
|
||||
cb(db.index, key, entity)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// Remove the given key from db
|
||||
func (db *DB) Remove(key string) {
|
||||
db.data.Remove(key)
|
||||
raw, deleted := db.data.Remove(key)
|
||||
db.ttlMap.Remove(key)
|
||||
taskKey := genExpireTask(key)
|
||||
timewheel.Cancel(taskKey)
|
||||
if cb := db.deleteCallback; cb != nil {
|
||||
var entity *database.DataEntity
|
||||
if deleted > 0 {
|
||||
entity = raw.(*database.DataEntity)
|
||||
}
|
||||
cb(db.index, key, entity)
|
||||
}
|
||||
}
|
||||
|
||||
// Removes the given keys from db
|
||||
|
@@ -149,7 +149,7 @@ func execHDel(db *DB, args [][]byte) redis.Reply {
|
||||
|
||||
deleted := 0
|
||||
for _, field := range fields {
|
||||
result := dict.Remove(field)
|
||||
_, result := dict.Remove(field)
|
||||
deleted += result
|
||||
}
|
||||
if dict.Len() == 0 {
|
||||
|
@@ -30,6 +30,10 @@ type Server struct {
|
||||
role int32
|
||||
slaveStatus *slaveStatus
|
||||
masterStatus *masterStatus
|
||||
|
||||
// hooks
|
||||
insertCallback database.KeyEventCallback
|
||||
deleteCallback database.KeyEventCallback
|
||||
}
|
||||
|
||||
// NewStandaloneServer creates a standalone redis server, with multi database and all other funtions
|
||||
@@ -247,6 +251,20 @@ func (server *Server) ForEach(dbIndex int, cb func(key string, data *database.Da
|
||||
server.mustSelectDB(dbIndex).ForEach(cb)
|
||||
}
|
||||
|
||||
// GetEntity returns the data entity to the given key
|
||||
func (server *Server) GetEntity(dbIndex int, key string) (*database.DataEntity, bool) {
|
||||
return server.mustSelectDB(dbIndex).GetEntity(key)
|
||||
}
|
||||
|
||||
func (server *Server) GetExpiration(dbIndex int, key string) *time.Time {
|
||||
raw, ok := server.mustSelectDB(dbIndex).ttlMap.Get(key)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
expireTime, _ := raw.(time.Time)
|
||||
return &expireTime
|
||||
}
|
||||
|
||||
// ExecMulti executes multi commands transaction Atomically and Isolated
|
||||
func (server *Server) ExecMulti(conn redis.Connection, watching map[string]uint32, cmdLines []CmdLine) redis.Reply {
|
||||
selectedDB, errReply := server.selectDB(conn.GetDBIndex())
|
||||
@@ -349,3 +367,20 @@ func (server *Server) startReplCron() {
|
||||
}
|
||||
}(server)
|
||||
}
|
||||
|
||||
func (server *Server) SetKeyInsertedCallback(cb database.KeyEventCallback) {
|
||||
server.insertCallback = cb
|
||||
for i := range server.dbSet {
|
||||
db := server.mustSelectDB(i)
|
||||
db.insertCallback = cb
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (server *Server) SetKeyDeletedCallback(cb database.KeyEventCallback) {
|
||||
server.deleteCallback = cb
|
||||
for i := range server.dbSet {
|
||||
db := server.mustSelectDB(i)
|
||||
db.deleteCallback = cb
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user