Removed StartSnapshot, FinishSnapshot, SetLatestSnapshot, and GetLatestSnapshot funcs from EchoVault interface as these are now private functions passed to the raft module using inversion of control

This commit is contained in:
Kelvin Mwinuka
2024-04-04 03:01:44 +08:00
parent 96968278e2
commit 3b0493e1d4
6 changed files with 581 additions and 552 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -28,7 +28,7 @@ type SnapshotOpts struct {
data map[string]internal.KeyData
startSnapshot func()
finishSnapshot func()
setLatestSnapshot func(msec int64)
setLatestSnapshotTime func(msec int64)
}
type Snapshot struct {
@@ -68,7 +68,7 @@ func (s *Snapshot) Persist(sink raft.SnapshotSink) error {
return err
}
s.options.setLatestSnapshot(int64(msec))
s.options.setLatestSnapshotTime(int64(msec))
return nil
}

View File

@@ -33,6 +33,9 @@ type FSMOpts struct {
GetState func() map[string]internal.KeyData
GetCommand func(command string) (types.Command, error)
DeleteKey func(ctx context.Context, key string) error
StartSnapshot func()
FinishSnapshot func()
SetLatestSnapshotTime func(msec int64)
}
type FSM struct {
@@ -120,9 +123,9 @@ func (fsm *FSM) Apply(log *raft.Log) interface{} {
func (fsm *FSM) Snapshot() (raft.FSMSnapshot, error) {
return NewFSMSnapshot(SnapshotOpts{
config: fsm.options.Config,
startSnapshot: fsm.options.EchoVault.StartSnapshot,
finishSnapshot: fsm.options.EchoVault.FinishSnapshot,
setLatestSnapshot: fsm.options.EchoVault.SetLatestSnapshot,
startSnapshot: fsm.options.StartSnapshot,
finishSnapshot: fsm.options.FinishSnapshot,
setLatestSnapshotTime: fsm.options.SetLatestSnapshotTime,
data: fsm.options.GetState(),
}), nil
}
@@ -159,7 +162,7 @@ func (fsm *FSM) Restore(snapshot io.ReadCloser) error {
fsm.options.EchoVault.KeyUnlock(ctx, k)
}
// Set latest snapshot milliseconds
fsm.options.EchoVault.SetLatestSnapshot(data.LatestSnapshotMilliseconds)
fsm.options.SetLatestSnapshotTime(data.LatestSnapshotMilliseconds)
return nil
}

View File

@@ -38,6 +38,9 @@ type Opts struct {
GetState func() map[string]internal.KeyData
GetCommand func(command string) (types.Command, error)
DeleteKey func(ctx context.Context, key string) error
StartSnapshot func()
FinishSnapshot func()
SetLatestSnapshotTime func(msec int64)
}
type Raft struct {
@@ -114,6 +117,9 @@ func (r *Raft) RaftInit(ctx context.Context) {
GetState: r.options.GetState,
GetCommand: r.options.GetCommand,
DeleteKey: r.options.DeleteKey,
StartSnapshot: r.options.StartSnapshot,
FinishSnapshot: r.options.FinishSnapshot,
SetLatestSnapshotTime: r.options.SetLatestSnapshotTime,
}),
logStore,
stableStore,

View File

@@ -89,24 +89,35 @@ type EchoVault struct {
aofEngine *aof.Engine // AOF engine for standalone mode
}
// WithContext is an options that for the NewEchoVault function that allows you to
// configure a custom context object to be used in EchoVault. If you don't provide this
// option, EchoVault will create its own internal context object.
func WithContext(ctx context.Context) func(echovault *EchoVault) {
return func(echovault *EchoVault) {
echovault.context = ctx
}
}
// WithConfig is an option for the NewEchoVault function that allows you to pass a
// custom configuration to EchoVault. If not specified, EchoVault will use the default
// configuration from config.DefaultConfig().
func WithConfig(config config.Config) func(echovault *EchoVault) {
return func(echovault *EchoVault) {
echovault.config = config
}
}
// WithCommands is an options for the NewEchoVault function that allows you to pass a
// list of commands that should be supported by your EchoVault instance. If you don't pass
// this option, EchoVault will start with no commands loaded.
func WithCommands(commands []types.Command) func(echovault *EchoVault) {
return func(echovault *EchoVault) {
echovault.commands = commands
}
}
// NewEchoVault creates a new EchoVault instance.
// This functions accepts the WithContext, WithConfig and WithCommands options.
func NewEchoVault(options ...func(echovault *EchoVault)) (*EchoVault, error) {
echovault := &EchoVault{
context: context.Background(),
@@ -135,6 +146,9 @@ func NewEchoVault(options ...func(echovault *EchoVault)) (*EchoVault, error) {
EchoVault: echovault,
GetCommand: echovault.getCommand,
DeleteKey: echovault.DeleteKey,
StartSnapshot: echovault.startSnapshot,
FinishSnapshot: echovault.finishSnapshot,
SetLatestSnapshotTime: echovault.setLatestSnapshot,
GetState: func() map[string]internal.KeyData {
state := make(map[string]internal.KeyData)
for k, v := range echovault.getState() {
@@ -160,10 +174,10 @@ func NewEchoVault(options ...func(echovault *EchoVault)) (*EchoVault, error) {
snapshot.WithDirectory(echovault.config.DataDir),
snapshot.WithThreshold(echovault.config.SnapShotThreshold),
snapshot.WithInterval(echovault.config.SnapshotInterval),
snapshot.WithStartSnapshotFunc(echovault.StartSnapshot),
snapshot.WithFinishSnapshotFunc(echovault.FinishSnapshot),
snapshot.WithSetLatestSnapshotTimeFunc(echovault.SetLatestSnapshot),
snapshot.WithGetLatestSnapshotTimeFunc(echovault.GetLatestSnapshot),
snapshot.WithStartSnapshotFunc(echovault.startSnapshot),
snapshot.WithFinishSnapshotFunc(echovault.finishSnapshot),
snapshot.WithSetLatestSnapshotTimeFunc(echovault.setLatestSnapshot),
snapshot.WithGetLatestSnapshotTimeFunc(echovault.getLatestSnapshotTime),
snapshot.WithGetStateFunc(func() map[string]internal.KeyData {
state := make(map[string]internal.KeyData)
for k, v := range echovault.getState() {
@@ -189,8 +203,8 @@ func NewEchoVault(options ...func(echovault *EchoVault)) (*EchoVault, error) {
echovault.aofEngine = aof.NewAOFEngine(
aof.WithDirectory(echovault.config.DataDir),
aof.WithStrategy(echovault.config.AOFSyncStrategy),
aof.WithStartRewriteFunc(echovault.StartRewriteAOF),
aof.WithFinishRewriteFunc(echovault.FinishRewriteAOF),
aof.WithStartRewriteFunc(echovault.startRewriteAOF),
aof.WithFinishRewriteFunc(echovault.finishRewriteAOF),
aof.WithGetStateFunc(func() map[string]internal.KeyData {
state := make(map[string]internal.KeyData)
for k, v := range echovault.getState() {
@@ -416,10 +430,16 @@ func (server *EchoVault) handleConnection(conn net.Conn) {
}
}
// Start starts the EchoVault instance's TCP listener.
// This allows the instance to accept connections handle client commands over TCP.
//
// You can still use command functions like echovault.SET if you're embedding EchoVault in you application.
// However, if you'd like to also accept TCP request on the same instance, you must call this function.
func (server *EchoVault) Start() {
server.startTCP()
}
// TakeSnapshot triggers a snapshot when called.
func (server *EchoVault) TakeSnapshot() error {
if server.snapshotInProgress.Load() {
return errors.New("snapshot already in progress")
@@ -442,27 +462,27 @@ func (server *EchoVault) TakeSnapshot() error {
return nil
}
func (server *EchoVault) StartSnapshot() {
func (server *EchoVault) startSnapshot() {
server.snapshotInProgress.Store(true)
}
func (server *EchoVault) FinishSnapshot() {
func (server *EchoVault) finishSnapshot() {
server.snapshotInProgress.Store(false)
}
func (server *EchoVault) SetLatestSnapshot(msec int64) {
func (server *EchoVault) setLatestSnapshot(msec int64) {
server.latestSnapshotMilliseconds.Store(msec)
}
func (server *EchoVault) GetLatestSnapshot() int64 {
func (server *EchoVault) getLatestSnapshotTime() int64 {
return server.latestSnapshotMilliseconds.Load()
}
func (server *EchoVault) StartRewriteAOF() {
func (server *EchoVault) startRewriteAOF() {
server.rewriteAOFInProgress.Store(true)
}
func (server *EchoVault) FinishRewriteAOF() {
func (server *EchoVault) finishRewriteAOF() {
server.rewriteAOFInProgress.Store(false)
}

View File

@@ -37,11 +37,11 @@ type EchoVault interface {
GetACL() interface{}
GetPubSub() interface{}
TakeSnapshot() error
StartSnapshot()
FinishSnapshot()
SetLatestSnapshot(msec int64)
GetLatestSnapshot() int64
RewriteAOF() error
//StartSnapshot()
//FinishSnapshot()
//SetLatestSnapshot(msec int64)
//GetLatestSnapshot() int64
}
type KeyExtractionFunc func(cmd []string) ([]string, error)