diff options
Diffstat (limited to 'internal/cache/gts.go')
-rw-r--r-- | internal/cache/gts.go | 313 |
1 files changed, 313 insertions, 0 deletions
diff --git a/internal/cache/gts.go b/internal/cache/gts.go new file mode 100644 index 000000000..9d77f5386 --- /dev/null +++ b/internal/cache/gts.go @@ -0,0 +1,313 @@ +/* + 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/v3/result" + "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" +) + +type GTSCaches interface { + // Init will initialize all the gtsmodel caches in this collection. + // NOTE: the cache MUST NOT be in use anywhere, this is not thread-safe. + Init() + + // Start will attempt to start all of the gtsmodel caches, or panic. + Start() + + // Stop will attempt to stop all of the gtsmodel caches, or panic. + Stop() + + // Account provides access to the gtsmodel Account database cache. + Account() *result.Cache[*gtsmodel.Account] + + // Block provides access to the gtsmodel Block (account) database cache. + Block() *result.Cache[*gtsmodel.Block] + + // DomainBlock provides access to the gtsmodel DomainBlock database cache. + DomainBlock() *result.Cache[*gtsmodel.DomainBlock] + + // Emoji provides access to the gtsmodel Emoji database cache. + Emoji() *result.Cache[*gtsmodel.Emoji] + + // EmojiCategory provides access to the gtsmodel EmojiCategory database cache. + EmojiCategory() *result.Cache[*gtsmodel.EmojiCategory] + + // Mention provides access to the gtsmodel Mention database cache. + Mention() *result.Cache[*gtsmodel.Mention] + + // Notification provides access to the gtsmodel Notification database cache. + Notification() *result.Cache[*gtsmodel.Notification] + + // Status provides access to the gtsmodel Status database cache. + Status() *result.Cache[*gtsmodel.Status] + + // Tombstone provides access to the gtsmodel Tombstone database cache. + Tombstone() *result.Cache[*gtsmodel.Tombstone] + + // User provides access to the gtsmodel User database cache. + User() *result.Cache[*gtsmodel.User] +} + +// NewGTS returns a new default implementation of GTSCaches. +func NewGTS() GTSCaches { + return >sCaches{} +} + +type gtsCaches struct { + account *result.Cache[*gtsmodel.Account] + block *result.Cache[*gtsmodel.Block] + domainBlock *result.Cache[*gtsmodel.DomainBlock] + emoji *result.Cache[*gtsmodel.Emoji] + emojiCategory *result.Cache[*gtsmodel.EmojiCategory] + mention *result.Cache[*gtsmodel.Mention] + notification *result.Cache[*gtsmodel.Notification] + status *result.Cache[*gtsmodel.Status] + tombstone *result.Cache[*gtsmodel.Tombstone] + user *result.Cache[*gtsmodel.User] +} + +func (c *gtsCaches) Init() { + c.initAccount() + c.initBlock() + c.initDomainBlock() + c.initEmoji() + c.initEmojiCategory() + c.initMention() + c.initNotification() + c.initStatus() + c.initTombstone() + c.initUser() +} + +func (c *gtsCaches) Start() { + tryUntil("starting gtsmodel.Account cache", 5, func() bool { + return c.account.Start(time.Second * 10) + }) + tryUntil("starting gtsmodel.Block cache", 5, func() bool { + return c.block.Start(time.Second * 10) + }) + tryUntil("starting gtsmodel.DomainBlock cache", 5, func() bool { + return c.domainBlock.Start(time.Second * 10) + }) + tryUntil("starting gtsmodel.Emoji cache", 5, func() bool { + return c.emoji.Start(time.Second * 10) + }) + tryUntil("starting gtsmodel.EmojiCategory cache", 5, func() bool { + return c.emojiCategory.Start(time.Second * 10) + }) + tryUntil("starting gtsmodel.Mention cache", 5, func() bool { + return c.mention.Start(time.Second * 10) + }) + tryUntil("starting gtsmodel.Notification cache", 5, func() bool { + return c.notification.Start(time.Second * 10) + }) + tryUntil("starting gtsmodel.Status cache", 5, func() bool { + return c.status.Start(time.Second * 10) + }) + tryUntil("starting gtsmodel.Tombstone cache", 5, func() bool { + return c.tombstone.Start(time.Second * 10) + }) + tryUntil("starting gtsmodel.User cache", 5, func() bool { + return c.user.Start(time.Second * 10) + }) +} + +func (c *gtsCaches) Stop() { + tryUntil("stopping gtsmodel.Account cache", 5, c.account.Stop) + tryUntil("stopping gtsmodel.Block cache", 5, c.block.Stop) + tryUntil("stopping gtsmodel.DomainBlock cache", 5, c.domainBlock.Stop) + tryUntil("stopping gtsmodel.Emoji cache", 5, c.emoji.Stop) + tryUntil("stopping gtsmodel.EmojiCategory cache", 5, c.emojiCategory.Stop) + tryUntil("stopping gtsmodel.Mention cache", 5, c.mention.Stop) + tryUntil("stopping gtsmodel.Notification cache", 5, c.notification.Stop) + tryUntil("stopping gtsmodel.Status cache", 5, c.status.Stop) + tryUntil("stopping gtsmodel.Tombstone cache", 5, c.tombstone.Stop) + tryUntil("stopping gtsmodel.User cache", 5, c.user.Stop) +} + +func (c *gtsCaches) Account() *result.Cache[*gtsmodel.Account] { + return c.account +} + +func (c *gtsCaches) Block() *result.Cache[*gtsmodel.Block] { + return c.block +} + +func (c *gtsCaches) DomainBlock() *result.Cache[*gtsmodel.DomainBlock] { + return c.domainBlock +} + +func (c *gtsCaches) Emoji() *result.Cache[*gtsmodel.Emoji] { + return c.emoji +} + +func (c *gtsCaches) EmojiCategory() *result.Cache[*gtsmodel.EmojiCategory] { + return c.emojiCategory +} + +func (c *gtsCaches) Mention() *result.Cache[*gtsmodel.Mention] { + return c.mention +} + +func (c *gtsCaches) Notification() *result.Cache[*gtsmodel.Notification] { + return c.notification +} + +func (c *gtsCaches) Status() *result.Cache[*gtsmodel.Status] { + return c.status +} + +func (c *gtsCaches) Tombstone() *result.Cache[*gtsmodel.Tombstone] { + return c.tombstone +} + +func (c *gtsCaches) User() *result.Cache[*gtsmodel.User] { + return c.user +} + +func (c *gtsCaches) initAccount() { + c.account = result.NewSized([]result.Lookup{ + {Name: "ID"}, + {Name: "URI"}, + {Name: "URL"}, + {Name: "Username.Domain"}, + {Name: "PublicKeyURI"}, + }, func(a1 *gtsmodel.Account) *gtsmodel.Account { + a2 := new(gtsmodel.Account) + *a2 = *a1 + return a2 + }, 1000) + c.account.SetTTL(time.Minute*5, false) +} + +func (c *gtsCaches) initBlock() { + c.block = result.NewSized([]result.Lookup{ + {Name: "ID"}, + {Name: "AccountID.TargetAccountID"}, + {Name: "URI"}, + }, func(b1 *gtsmodel.Block) *gtsmodel.Block { + b2 := new(gtsmodel.Block) + *b2 = *b1 + return b2 + }, 1000) + c.block.SetTTL(time.Minute*5, false) +} + +func (c *gtsCaches) initDomainBlock() { + c.domainBlock = result.NewSized([]result.Lookup{ + {Name: "Domain"}, + }, func(d1 *gtsmodel.DomainBlock) *gtsmodel.DomainBlock { + d2 := new(gtsmodel.DomainBlock) + *d2 = *d1 + return d2 + }, 1000) + c.domainBlock.SetTTL(time.Minute*5, false) +} + +func (c *gtsCaches) initEmoji() { + c.emoji = result.NewSized([]result.Lookup{ + {Name: "ID"}, + {Name: "URI"}, + {Name: "Shortcode.Domain"}, + {Name: "ImageStaticURL"}, + }, func(e1 *gtsmodel.Emoji) *gtsmodel.Emoji { + e2 := new(gtsmodel.Emoji) + *e2 = *e1 + return e2 + }, 1000) + c.emoji.SetTTL(time.Minute*5, false) +} + +func (c *gtsCaches) initEmojiCategory() { + c.emojiCategory = result.NewSized([]result.Lookup{ + {Name: "ID"}, + {Name: "Name"}, + }, func(c1 *gtsmodel.EmojiCategory) *gtsmodel.EmojiCategory { + c2 := new(gtsmodel.EmojiCategory) + *c2 = *c1 + return c2 + }, 1000) + c.emojiCategory.SetTTL(time.Minute*5, false) +} + +func (c *gtsCaches) initMention() { + c.mention = result.NewSized([]result.Lookup{ + {Name: "ID"}, + }, func(m1 *gtsmodel.Mention) *gtsmodel.Mention { + m2 := new(gtsmodel.Mention) + *m2 = *m1 + return m2 + }, 1000) + c.mention.SetTTL(time.Minute*5, false) +} + +func (c *gtsCaches) initNotification() { + c.notification = result.NewSized([]result.Lookup{ + {Name: "ID"}, + }, func(n1 *gtsmodel.Notification) *gtsmodel.Notification { + n2 := new(gtsmodel.Notification) + *n2 = *n1 + return n2 + }, 1000) + c.notification.SetTTL(time.Minute*5, false) +} + +func (c *gtsCaches) initStatus() { + c.status = result.NewSized([]result.Lookup{ + {Name: "ID"}, + {Name: "URI"}, + {Name: "URL"}, + }, func(s1 *gtsmodel.Status) *gtsmodel.Status { + s2 := new(gtsmodel.Status) + *s2 = *s1 + return s2 + }, 1000) + c.status.SetTTL(time.Minute*5, false) +} + +// initTombstone will initialize the gtsmodel.Tombstone cache. +func (c *gtsCaches) initTombstone() { + c.tombstone = result.NewSized([]result.Lookup{ + {Name: "ID"}, + {Name: "URI"}, + }, func(t1 *gtsmodel.Tombstone) *gtsmodel.Tombstone { + t2 := new(gtsmodel.Tombstone) + *t2 = *t1 + return t2 + }, 100) + c.tombstone.SetTTL(time.Minute*5, false) +} + +func (c *gtsCaches) initUser() { + c.user = result.NewSized([]result.Lookup{ + {Name: "ID"}, + {Name: "AccountID"}, + {Name: "Email"}, + {Name: "ConfirmationToken"}, + {Name: "ExternalID"}, + }, func(u1 *gtsmodel.User) *gtsmodel.User { + u2 := new(gtsmodel.User) + *u2 = *u1 + return u2 + }, 1000) + c.user.SetTTL(time.Minute*5, false) +} |