mirror of
https://github.com/superseriousbusiness/gotosocial
synced 2025-06-05 21:59:39 +02:00
[performance] cached oauth database types (#2838)
* update token + client code to use struct caches * add code comments * slight tweak to default mem ratios * fix envparsing * add appropriate invalidate hooks * update the tokenstore sweeping function to rely on caches * update to use PutClient() * add ClientID to list of token struct indices
This commit is contained in:
4
internal/cache/cache.go
vendored
4
internal/cache/cache.go
vendored
@@ -59,6 +59,7 @@ func (c *Caches) Init() {
|
||||
c.initBlock()
|
||||
c.initBlockIDs()
|
||||
c.initBoostOfIDs()
|
||||
c.initClient()
|
||||
c.initDomainAllow()
|
||||
c.initDomainBlock()
|
||||
c.initEmoji()
|
||||
@@ -85,9 +86,10 @@ func (c *Caches) Init() {
|
||||
c.initReport()
|
||||
c.initStatus()
|
||||
c.initStatusFave()
|
||||
c.initStatusFaveIDs()
|
||||
c.initTag()
|
||||
c.initThreadMute()
|
||||
c.initStatusFaveIDs()
|
||||
c.initToken()
|
||||
c.initTombstone()
|
||||
c.initUser()
|
||||
c.initWebfinger()
|
||||
|
70
internal/cache/db.go
vendored
70
internal/cache/db.go
vendored
@@ -58,6 +58,9 @@ type GTSCaches struct {
|
||||
// BoostOfIDs provides access to the boost of IDs list database cache.
|
||||
BoostOfIDs SliceCache[string]
|
||||
|
||||
// Client provides access to the gtsmodel Client database cache.
|
||||
Client StructCache[*gtsmodel.Client]
|
||||
|
||||
// DomainAllow provides access to the domain allow database cache.
|
||||
DomainAllow *domain.Cache
|
||||
|
||||
@@ -150,6 +153,9 @@ type GTSCaches struct {
|
||||
// Tag provides access to the gtsmodel Tag database cache.
|
||||
Tag StructCache[*gtsmodel.Tag]
|
||||
|
||||
// Token provides access to the gtsmodel Token database cache.
|
||||
Token StructCache[*gtsmodel.Token]
|
||||
|
||||
// Tombstone provides access to the gtsmodel Tombstone database cache.
|
||||
Tombstone StructCache[*gtsmodel.Tombstone]
|
||||
|
||||
@@ -309,9 +315,10 @@ func (c *Caches) initApplication() {
|
||||
{Fields: "ID"},
|
||||
{Fields: "ClientID"},
|
||||
},
|
||||
MaxSize: cap,
|
||||
IgnoreErr: ignoreErrors,
|
||||
Copy: copyF,
|
||||
MaxSize: cap,
|
||||
IgnoreErr: ignoreErrors,
|
||||
Copy: copyF,
|
||||
Invalidate: c.OnInvalidateApplication,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -374,6 +381,32 @@ func (c *Caches) initBoostOfIDs() {
|
||||
c.GTS.BoostOfIDs.Init(0, cap)
|
||||
}
|
||||
|
||||
func (c *Caches) initClient() {
|
||||
// Calculate maximum cache size.
|
||||
cap := calculateResultCacheMax(
|
||||
sizeofClient(), // model in-mem size.
|
||||
config.GetCacheClientMemRatio(),
|
||||
)
|
||||
|
||||
log.Infof(nil, "cache size = %d", cap)
|
||||
|
||||
copyF := func(c1 *gtsmodel.Client) *gtsmodel.Client {
|
||||
c2 := new(gtsmodel.Client)
|
||||
*c2 = *c1
|
||||
return c2
|
||||
}
|
||||
|
||||
c.GTS.Client.Init(structr.CacheConfig[*gtsmodel.Client]{
|
||||
Indices: []structr.IndexConfig{
|
||||
{Fields: "ID"},
|
||||
},
|
||||
MaxSize: cap,
|
||||
IgnoreErr: ignoreErrors,
|
||||
Copy: copyF,
|
||||
Invalidate: c.OnInvalidateClient,
|
||||
})
|
||||
}
|
||||
|
||||
func (c *Caches) initDomainAllow() {
|
||||
c.GTS.DomainAllow = new(domain.Cache)
|
||||
}
|
||||
@@ -1135,7 +1168,7 @@ func (c *Caches) initTag() {
|
||||
|
||||
func (c *Caches) initThreadMute() {
|
||||
cap := calculateResultCacheMax(
|
||||
sizeOfThreadMute(), // model in-mem size.
|
||||
sizeofThreadMute(), // model in-mem size.
|
||||
config.GetCacheThreadMuteMemRatio(),
|
||||
)
|
||||
|
||||
@@ -1160,6 +1193,35 @@ func (c *Caches) initThreadMute() {
|
||||
})
|
||||
}
|
||||
|
||||
func (c *Caches) initToken() {
|
||||
// Calculate maximum cache size.
|
||||
cap := calculateResultCacheMax(
|
||||
sizeofToken(), // model in-mem size.
|
||||
config.GetCacheTokenMemRatio(),
|
||||
)
|
||||
|
||||
log.Infof(nil, "cache size = %d", cap)
|
||||
|
||||
copyF := func(t1 *gtsmodel.Token) *gtsmodel.Token {
|
||||
t2 := new(gtsmodel.Token)
|
||||
*t2 = *t1
|
||||
return t2
|
||||
}
|
||||
|
||||
c.GTS.Token.Init(structr.CacheConfig[*gtsmodel.Token]{
|
||||
Indices: []structr.IndexConfig{
|
||||
{Fields: "ID"},
|
||||
{Fields: "Code"},
|
||||
{Fields: "Access"},
|
||||
{Fields: "Refresh"},
|
||||
{Fields: "ClientID", Multiple: true},
|
||||
},
|
||||
MaxSize: cap,
|
||||
IgnoreErr: ignoreErrors,
|
||||
Copy: copyF,
|
||||
})
|
||||
}
|
||||
|
||||
func (c *Caches) initTombstone() {
|
||||
// Calculate maximum cache size.
|
||||
cap := calculateResultCacheMax(
|
||||
|
10
internal/cache/invalidate.go
vendored
10
internal/cache/invalidate.go
vendored
@@ -60,6 +60,11 @@ func (c *Caches) OnInvalidateAccount(account *gtsmodel.Account) {
|
||||
c.GTS.Move.Invalidate("TargetURI", account.URI)
|
||||
}
|
||||
|
||||
func (c *Caches) OnInvalidateApplication(app *gtsmodel.Application) {
|
||||
// Invalidate cached client of this application.
|
||||
c.GTS.Client.Invalidate("ID", app.ClientID)
|
||||
}
|
||||
|
||||
func (c *Caches) OnInvalidateBlock(block *gtsmodel.Block) {
|
||||
// Invalidate block origin account ID cached visibility.
|
||||
c.Visibility.Invalidate("ItemID", block.AccountID)
|
||||
@@ -73,6 +78,11 @@ func (c *Caches) OnInvalidateBlock(block *gtsmodel.Block) {
|
||||
c.GTS.BlockIDs.Invalidate(block.AccountID)
|
||||
}
|
||||
|
||||
func (c *Caches) OnInvalidateClient(client *gtsmodel.Client) {
|
||||
// Invalidate any tokens under this client.
|
||||
c.GTS.Token.Invalidate("ClientID", client.ID)
|
||||
}
|
||||
|
||||
func (c *Caches) OnInvalidateEmojiCategory(category *gtsmodel.EmojiCategory) {
|
||||
// Invalidate any emoji in this category.
|
||||
c.GTS.Emoji.Invalidate("CategoryID", category.ID)
|
||||
|
38
internal/cache/size.go
vendored
38
internal/cache/size.go
vendored
@@ -176,6 +176,7 @@ func totalOfRatios() float64 {
|
||||
config.GetCacheBlockMemRatio() +
|
||||
config.GetCacheBlockIDsMemRatio() +
|
||||
config.GetCacheBoostOfIDsMemRatio() +
|
||||
config.GetCacheClientMemRatio() +
|
||||
config.GetCacheEmojiMemRatio() +
|
||||
config.GetCacheEmojiCategoryMemRatio() +
|
||||
config.GetCacheFollowMemRatio() +
|
||||
@@ -198,6 +199,7 @@ func totalOfRatios() float64 {
|
||||
config.GetCacheStatusFaveIDsMemRatio() +
|
||||
config.GetCacheTagMemRatio() +
|
||||
config.GetCacheThreadMuteMemRatio() +
|
||||
config.GetCacheTokenMemRatio() +
|
||||
config.GetCacheTombstoneMemRatio() +
|
||||
config.GetCacheUserMemRatio() +
|
||||
config.GetCacheWebfingerMemRatio() +
|
||||
@@ -287,6 +289,17 @@ func sizeofBlock() uintptr {
|
||||
}))
|
||||
}
|
||||
|
||||
func sizeofClient() uintptr {
|
||||
return uintptr(size.Of(>smodel.Client{
|
||||
ID: exampleID,
|
||||
CreatedAt: exampleTime,
|
||||
UpdatedAt: exampleTime,
|
||||
Secret: exampleID,
|
||||
Domain: exampleURI,
|
||||
UserID: exampleID,
|
||||
}))
|
||||
}
|
||||
|
||||
func sizeofEmoji() uintptr {
|
||||
return uintptr(size.Of(>smodel.Emoji{
|
||||
ID: exampleID,
|
||||
@@ -591,7 +604,7 @@ func sizeofTag() uintptr {
|
||||
}))
|
||||
}
|
||||
|
||||
func sizeOfThreadMute() uintptr {
|
||||
func sizeofThreadMute() uintptr {
|
||||
return uintptr(size.Of(>smodel.ThreadMute{
|
||||
ID: exampleID,
|
||||
CreatedAt: exampleTime,
|
||||
@@ -601,6 +614,29 @@ func sizeOfThreadMute() uintptr {
|
||||
}))
|
||||
}
|
||||
|
||||
func sizeofToken() uintptr {
|
||||
return uintptr(size.Of(>smodel.Token{
|
||||
ID: exampleID,
|
||||
CreatedAt: exampleTime,
|
||||
UpdatedAt: exampleTime,
|
||||
ClientID: exampleID,
|
||||
UserID: exampleID,
|
||||
RedirectURI: exampleURI,
|
||||
Scope: "r:w",
|
||||
Code: "", // TODO
|
||||
CodeChallenge: "", // TODO
|
||||
CodeChallengeMethod: "", // TODO
|
||||
CodeCreateAt: exampleTime,
|
||||
CodeExpiresAt: exampleTime,
|
||||
Access: exampleID + exampleID,
|
||||
AccessCreateAt: exampleTime,
|
||||
AccessExpiresAt: exampleTime,
|
||||
Refresh: "", // TODO: clients don't really support this very well yet
|
||||
RefreshCreateAt: exampleTime,
|
||||
RefreshExpiresAt: exampleTime,
|
||||
}))
|
||||
}
|
||||
|
||||
func sizeofTombstone() uintptr {
|
||||
return uintptr(size.Of(>smodel.Tombstone{
|
||||
ID: exampleID,
|
||||
|
Reference in New Issue
Block a user