mirror of
https://github.com/superseriousbusiness/gotosocial
synced 2025-06-05 21:59:39 +02:00
[performance] add user cache and database (#879)
* go fmt * add + use user cache and database * fix import * update tests * remove unused relation
This commit is contained in:
141
internal/cache/user.go
vendored
Normal file
141
internal/cache/user.go
vendored
Normal file
@ -0,0 +1,141 @@
|
||||
/*
|
||||
GoToSocial
|
||||
Copyright (C) 2021-2022 GoToSocial Authors admin@gotosocial.org
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package cache
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"codeberg.org/gruf/go-cache/v2"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
|
||||
)
|
||||
|
||||
// UserCache is a cache wrapper to provide lookups for gtsmodel.User
|
||||
type UserCache struct {
|
||||
cache cache.LookupCache[string, string, *gtsmodel.User]
|
||||
}
|
||||
|
||||
// NewUserCache returns a new instantiated UserCache object
|
||||
func NewUserCache() *UserCache {
|
||||
c := &UserCache{}
|
||||
c.cache = cache.NewLookup(cache.LookupCfg[string, string, *gtsmodel.User]{
|
||||
RegisterLookups: func(lm *cache.LookupMap[string, string]) {
|
||||
lm.RegisterLookup("accountid")
|
||||
lm.RegisterLookup("email")
|
||||
lm.RegisterLookup("unconfirmedemail")
|
||||
lm.RegisterLookup("confirmationtoken")
|
||||
},
|
||||
|
||||
AddLookups: func(lm *cache.LookupMap[string, string], user *gtsmodel.User) {
|
||||
lm.Set("accountid", user.AccountID, user.ID)
|
||||
if email := user.Email; email != "" {
|
||||
lm.Set("email", email, user.ID)
|
||||
}
|
||||
if unconfirmedEmail := user.UnconfirmedEmail; unconfirmedEmail != "" {
|
||||
lm.Set("unconfirmedemail", unconfirmedEmail, user.ID)
|
||||
}
|
||||
if confirmationToken := user.ConfirmationToken; confirmationToken != "" {
|
||||
lm.Set("confirmationtoken", confirmationToken, user.ID)
|
||||
}
|
||||
},
|
||||
|
||||
DeleteLookups: func(lm *cache.LookupMap[string, string], user *gtsmodel.User) {
|
||||
lm.Delete("accountid", user.AccountID)
|
||||
if email := user.Email; email != "" {
|
||||
lm.Delete("email", email)
|
||||
}
|
||||
if unconfirmedEmail := user.UnconfirmedEmail; unconfirmedEmail != "" {
|
||||
lm.Delete("unconfirmedemail", unconfirmedEmail)
|
||||
}
|
||||
if confirmationToken := user.ConfirmationToken; confirmationToken != "" {
|
||||
lm.Delete("confirmationtoken", confirmationToken)
|
||||
}
|
||||
},
|
||||
})
|
||||
c.cache.SetTTL(time.Minute*5, false)
|
||||
c.cache.Start(time.Second * 10)
|
||||
return c
|
||||
}
|
||||
|
||||
// GetByID attempts to fetch a user from the cache by its ID, you will receive a copy for thread-safety
|
||||
func (c *UserCache) GetByID(id string) (*gtsmodel.User, bool) {
|
||||
return c.cache.Get(id)
|
||||
}
|
||||
|
||||
// GetByAccountID attempts to fetch a user from the cache by its account ID, you will receive a copy for thread-safety
|
||||
func (c *UserCache) GetByAccountID(accountID string) (*gtsmodel.User, bool) {
|
||||
return c.cache.GetBy("accountid", accountID)
|
||||
}
|
||||
|
||||
// GetByEmail attempts to fetch a user from the cache by its email address, you will receive a copy for thread-safety
|
||||
func (c *UserCache) GetByEmail(email string) (*gtsmodel.User, bool) {
|
||||
return c.cache.GetBy("email", email)
|
||||
}
|
||||
|
||||
// GetByUnconfirmedEmail attempts to fetch a user from the cache by its confirmation token, you will receive a copy for thread-safety
|
||||
func (c *UserCache) GetByConfirmationToken(token string) (*gtsmodel.User, bool) {
|
||||
return c.cache.GetBy("confirmationtoken", token)
|
||||
}
|
||||
|
||||
// Put places a user in the cache, ensuring that the object place is a copy for thread-safety
|
||||
func (c *UserCache) Put(user *gtsmodel.User) {
|
||||
if user == nil || user.ID == "" {
|
||||
panic("invalid user")
|
||||
}
|
||||
c.cache.Set(user.ID, copyUser(user))
|
||||
}
|
||||
|
||||
// Invalidate invalidates one user from the cache using the ID of the user as key.
|
||||
func (c *UserCache) Invalidate(userID string) {
|
||||
c.cache.Invalidate(userID)
|
||||
}
|
||||
|
||||
func copyUser(user *gtsmodel.User) *gtsmodel.User {
|
||||
return >smodel.User{
|
||||
ID: user.ID,
|
||||
CreatedAt: user.CreatedAt,
|
||||
UpdatedAt: user.UpdatedAt,
|
||||
Email: user.Email,
|
||||
AccountID: user.AccountID,
|
||||
Account: nil,
|
||||
EncryptedPassword: user.EncryptedPassword,
|
||||
SignUpIP: user.SignUpIP,
|
||||
CurrentSignInAt: user.CurrentSignInAt,
|
||||
CurrentSignInIP: user.CurrentSignInIP,
|
||||
LastSignInAt: user.LastSignInAt,
|
||||
LastSignInIP: user.LastSignInIP,
|
||||
SignInCount: user.SignInCount,
|
||||
InviteID: user.InviteID,
|
||||
ChosenLanguages: user.ChosenLanguages,
|
||||
FilteredLanguages: user.FilteredLanguages,
|
||||
Locale: user.Locale,
|
||||
CreatedByApplicationID: user.CreatedByApplicationID,
|
||||
CreatedByApplication: nil,
|
||||
LastEmailedAt: user.LastEmailedAt,
|
||||
ConfirmationToken: user.ConfirmationToken,
|
||||
ConfirmationSentAt: user.ConfirmationSentAt,
|
||||
ConfirmedAt: user.ConfirmedAt,
|
||||
UnconfirmedEmail: user.UnconfirmedEmail,
|
||||
Moderator: copyBoolPtr(user.Moderator),
|
||||
Admin: copyBoolPtr(user.Admin),
|
||||
Disabled: copyBoolPtr(user.Disabled),
|
||||
Approved: copyBoolPtr(user.Approved),
|
||||
ResetPasswordToken: user.ResetPasswordToken,
|
||||
ResetPasswordSentAt: user.ResetPasswordSentAt,
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user