| // Copyright 2021 The etcd Authors |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| package storage |
| |
| import ( |
| "sync" |
| |
| "go.uber.org/zap" |
| |
| "go.etcd.io/etcd/raft/v3/raftpb" |
| "go.etcd.io/etcd/server/v3/etcdserver/cindex" |
| "go.etcd.io/etcd/server/v3/storage/backend" |
| "go.etcd.io/etcd/server/v3/storage/schema" |
| ) |
| |
| type BackendHooks struct { |
| indexer cindex.ConsistentIndexer |
| lg *zap.Logger |
| |
| // confState to Be written in the next submitted Backend transaction (if dirty) |
| confState raftpb.ConfState |
| // first write changes it to 'dirty'. false by default, so |
| // not initialized `confState` is meaningless. |
| confStateDirty bool |
| confStateLock sync.Mutex |
| } |
| |
| func NewBackendHooks(lg *zap.Logger, indexer cindex.ConsistentIndexer) *BackendHooks { |
| return &BackendHooks{lg: lg, indexer: indexer} |
| } |
| |
| func (bh *BackendHooks) OnPreCommitUnsafe(tx backend.BatchTx) { |
| bh.indexer.UnsafeSave(tx) |
| bh.confStateLock.Lock() |
| defer bh.confStateLock.Unlock() |
| if bh.confStateDirty { |
| schema.MustUnsafeSaveConfStateToBackend(bh.lg, tx, &bh.confState) |
| // save bh.confState |
| bh.confStateDirty = false |
| } |
| } |
| |
| func (bh *BackendHooks) SetConfState(confState *raftpb.ConfState) { |
| bh.confStateLock.Lock() |
| defer bh.confStateLock.Unlock() |
| bh.confState = *confState |
| bh.confStateDirty = true |
| } |