[#1464] frostfsid: Cache subject not found error
All checks were successful
Tests and linters / Run gofumpt (pull_request) Successful in 1m30s
DCO action / DCO (pull_request) Successful in 1m43s
Vulncheck / Vulncheck (pull_request) Successful in 1m35s
Pre-commit hooks / Pre-commit (pull_request) Successful in 2m30s
Build / Build Components (pull_request) Successful in 2m35s
Tests and linters / gopls check (pull_request) Successful in 2m52s
Tests and linters / Staticcheck (pull_request) Successful in 2m57s
Tests and linters / Lint (pull_request) Successful in 3m50s
Tests and linters / Tests (pull_request) Successful in 4m27s
Tests and linters / Tests with -race (pull_request) Successful in 6m6s

Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>
This commit is contained in:
Dmitrii Stepanov 2024-10-30 17:44:31 +03:00
parent e74d05c03f
commit 2285cfc36f
Signed by: dstepanov-yadro
GPG key ID: 237AF1A763293BC0

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,