forked from TrueCloudLab/frostfs-node
[#1549] shard: Turn to ModeDegraded
on metabase failure
Make `Shard` to work in degraded mode if metabase is unavailable on opening/init stage. Close metabase in non-degraded mode only. Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
parent
1684cd63fa
commit
263497a92b
1 changed files with 66 additions and 12 deletions
|
@ -12,10 +12,25 @@ import (
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func (s *Shard) handleMetabaseFailure(stage string, err error) error {
|
||||||
|
s.log.Error("metabase failure, switching mode",
|
||||||
|
zap.String("stage", stage),
|
||||||
|
zap.Stringer("mode", ModeDegraded),
|
||||||
|
zap.Error(err),
|
||||||
|
)
|
||||||
|
|
||||||
|
err = s.SetMode(ModeDegraded)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("could not switch to mode %s", ModeDegraded)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Open opens all Shard's components.
|
// Open opens all Shard's components.
|
||||||
func (s *Shard) Open() error {
|
func (s *Shard) Open() error {
|
||||||
components := []interface{ Open() error }{
|
components := []interface{ Open() error }{
|
||||||
s.blobStor, s.metaBase, s.pilorama,
|
s.blobStor, s.pilorama,
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.hasWriteCache() {
|
if s.hasWriteCache() {
|
||||||
|
@ -24,32 +39,67 @@ func (s *Shard) Open() error {
|
||||||
|
|
||||||
for _, component := range components {
|
for _, component := range components {
|
||||||
if err := component.Open(); err != nil {
|
if err := component.Open(); err != nil {
|
||||||
|
if component == s.metaBase {
|
||||||
|
err = s.handleMetabaseFailure("open", err)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
return fmt.Errorf("could not open %T: %w", component, err)
|
return fmt.Errorf("could not open %T: %w", component, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type metabaseSynchronizer Shard
|
||||||
|
|
||||||
|
func (x *metabaseSynchronizer) Init() error {
|
||||||
|
return (*Shard)(x).refillMetabase()
|
||||||
|
}
|
||||||
|
|
||||||
// Init initializes all Shard's components.
|
// Init initializes all Shard's components.
|
||||||
func (s *Shard) Init() error {
|
func (s *Shard) Init() error {
|
||||||
var fMetabase func() error
|
type initializer interface {
|
||||||
|
Init() error
|
||||||
if s.needRefillMetabase() {
|
|
||||||
fMetabase = s.refillMetabase
|
|
||||||
} else {
|
|
||||||
fMetabase = s.metaBase.Init
|
|
||||||
}
|
}
|
||||||
|
|
||||||
components := []func() error{
|
var components []initializer
|
||||||
s.blobStor.Init, fMetabase, s.pilorama.Init,
|
|
||||||
|
if s.GetMode() != ModeDegraded {
|
||||||
|
var initMetabase initializer
|
||||||
|
|
||||||
|
if s.needRefillMetabase() {
|
||||||
|
initMetabase = (*metabaseSynchronizer)(s)
|
||||||
|
} else {
|
||||||
|
initMetabase = s.metaBase
|
||||||
|
}
|
||||||
|
|
||||||
|
components = []initializer{
|
||||||
|
s.blobStor, initMetabase, s.pilorama,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
components = []initializer{s.blobStor, s.pilorama}
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.hasWriteCache() {
|
if s.hasWriteCache() {
|
||||||
components = append(components, s.writeCache.Init)
|
components = append(components, s.writeCache)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, component := range components {
|
for _, component := range components {
|
||||||
if err := component(); err != nil {
|
if err := component.Init(); err != nil {
|
||||||
|
if component == s.metaBase {
|
||||||
|
err = s.handleMetabaseFailure("init", err)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
return fmt.Errorf("could not initialize %T: %w", component, err)
|
return fmt.Errorf("could not initialize %T: %w", component, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -154,7 +204,11 @@ func (s *Shard) Close() error {
|
||||||
components = append(components, s.writeCache)
|
components = append(components, s.writeCache)
|
||||||
}
|
}
|
||||||
|
|
||||||
components = append(components, s.pilorama, s.blobStor, s.metaBase)
|
components = append(components, s.pilorama, s.blobStor)
|
||||||
|
|
||||||
|
if s.GetMode() != ModeDegraded {
|
||||||
|
components = append(components, s.metaBase)
|
||||||
|
}
|
||||||
|
|
||||||
for _, component := range components {
|
for _, component := range components {
|
||||||
if err := component.Close(); err != nil {
|
if err := component.Close(); err != nil {
|
||||||
|
|
Loading…
Reference in a new issue