Fix FrostfsID cache #1464
1 changed files with 42 additions and 11 deletions
|
@ -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,
|
||||||
|
|
Loading…
Reference in a new issue
As now only
subject not found
error is cacheable, it is safe to update both caches