Fix FrostfsID cache #1464

Merged
fyrchik merged 1 commit from dstepanov-yadro/frostfs-node:fix/frostfsid_cache into master 2024-11-02 14:21:42 +00:00

View file

@ -1,6 +1,7 @@
package main package main
import ( import (
"strings"
"time" "time"
"git.frostfs.info/TrueCloudLab/frostfs-contract/frostfsid/client" "git.frostfs.info/TrueCloudLab/frostfs-contract/frostfsid/client"
@ -9,10 +10,22 @@ import (
"github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/util"
) )
type subjectWithError struct {
subject *client.Subject
err error
}
type subjectExtWithError struct {
subject *client.SubjectExtended
err error
}
type morphFrostfsIDCache struct { type morphFrostfsIDCache struct {
subjProvider frostfsidcore.SubjectProvider subjProvider frostfsidcore.SubjectProvider
subjCache *expirable.LRU[util.Uint160, *client.Subject] subjCache *expirable.LRU[util.Uint160, subjectWithError]
subjExtCache *expirable.LRU[util.Uint160, subjectExtWithError]
metrics cacheMetrics metrics cacheMetrics
} }
@ -21,7 +34,9 @@ func newMorphFrostfsIDCache(subjProvider frostfsidcore.SubjectProvider, size int
return &morphFrostfsIDCache{ return &morphFrostfsIDCache{
subjProvider: subjProvider, subjProvider: subjProvider,
subjCache: expirable.NewLRU(size, func(util.Uint160, *client.Subject) {}, ttl), subjCache: expirable.NewLRU(size, func(util.Uint160, subjectWithError) {}, ttl),
subjExtCache: expirable.NewLRU(size, func(util.Uint160, subjectExtWithError) {}, ttl),
metrics: metrics, metrics: metrics,
} }
@ -37,16 +52,21 @@ func (m *morphFrostfsIDCache) GetSubject(addr util.Uint160) (*client.Subject, er
result, found := m.subjCache.Get(addr) result, found := m.subjCache.Get(addr)
if found { if found {
hit = true hit = true
return result, nil return result.subject, result.err
} }
result, err := m.subjProvider.GetSubject(addr) subj, err := m.subjProvider.GetSubject(addr)
if err != nil { if err != nil {
if m.isCacheableError(err) {
m.subjCache.Add(addr, subjectWithError{
err: err,
})
}
return nil, err return nil, err
} }
m.subjCache.Add(addr, result) m.subjCache.Add(addr, subjectWithError{subject: subj})
return result, nil return subj, nil
} }
func (m *morphFrostfsIDCache) GetSubjectExtended(addr util.Uint160) (*client.SubjectExtended, error) { func (m *morphFrostfsIDCache) GetSubjectExtended(addr util.Uint160) (*client.SubjectExtended, error) {
@ -59,21 +79,32 @@ func (m *morphFrostfsIDCache) GetSubjectExtended(addr util.Uint160) (*client.Sub
result, found := m.subjExtCache.Get(addr) result, found := m.subjExtCache.Get(addr)
if found { if found {
hit = true hit = true
return result, nil return result.subject, result.err
} }
var err error subjExt, err := m.subjProvider.GetSubjectExtended(addr)
subjExt, err = m.subjProvider.GetSubjectExtended(addr)
if err != nil { if err != nil {
if m.isCacheableError(err) {
m.subjExtCache.Add(addr, subjectExtWithError{
err: err,
})
m.subjCache.Add(addr, subjectWithError{
err: err,
})
}
return nil, err return nil, err
} }
m.subjExtCache.Add(addr, subjExt) m.subjExtCache.Add(addr, subjectExtWithError{subject: subjExt})
m.subjCache.Add(addr, subjectFromSubjectExtended(subjExt)) m.subjCache.Add(addr, subjectWithError{subject: subjectFromSubjectExtended(subjExt)})
return subjExt, nil return subjExt, nil
} }
func (m *morphFrostfsIDCache) isCacheableError(err error) bool {
return strings.Contains(err.Error(), frostfsidcore.SubjectNotFoundErrorMessage)
}
func subjectFromSubjectExtended(subjExt *client.SubjectExtended) *client.Subject { func subjectFromSubjectExtended(subjExt *client.SubjectExtended) *client.Subject {
return &client.Subject{ return &client.Subject{
PrimaryKey: subjExt.PrimaryKey, PrimaryKey: subjExt.PrimaryKey,