cache.go (4544B)
1 // GoToSocial 2 // Copyright (C) GoToSocial Authors admin@gotosocial.org 3 // SPDX-License-Identifier: AGPL-3.0-or-later 4 // 5 // This program is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Affero General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // This program is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Affero General Public License for more details. 14 // 15 // You should have received a copy of the GNU Affero General Public License 16 // along with this program. If not, see <http://www.gnu.org/licenses/>. 17 18 package cache 19 20 import ( 21 "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" 22 "github.com/superseriousbusiness/gotosocial/internal/log" 23 ) 24 25 type Caches struct { 26 // GTS provides access to the collection of gtsmodel object caches. 27 // (used by the database). 28 GTS GTSCaches 29 30 // AP provides access to the collection of ActivityPub object caches. 31 // (planned to be used by the typeconverter). 32 AP APCaches 33 34 // Visibility provides access to the item visibility cache. 35 // (used by the visibility filter). 36 Visibility VisibilityCache 37 38 // prevent pass-by-value. 39 _ nocopy 40 } 41 42 // Init will (re)initialize both the GTS and AP cache collections. 43 // NOTE: the cache MUST NOT be in use anywhere, this is not thread-safe. 44 func (c *Caches) Init() { 45 log.Infof(nil, "init: %p", c) 46 47 c.GTS.Init() 48 c.AP.Init() 49 c.Visibility.Init() 50 51 // Setup cache invalidate hooks. 52 // !! READ THE METHOD COMMENT 53 c.setuphooks() 54 } 55 56 // Start will start both the GTS and AP cache collections. 57 func (c *Caches) Start() { 58 log.Infof(nil, "start: %p", c) 59 60 c.GTS.Start() 61 c.AP.Start() 62 c.Visibility.Start() 63 } 64 65 // Stop will stop both the GTS and AP cache collections. 66 func (c *Caches) Stop() { 67 log.Infof(nil, "stop: %p", c) 68 69 c.GTS.Stop() 70 c.AP.Stop() 71 c.Visibility.Stop() 72 } 73 74 // setuphooks sets necessary cache invalidation hooks between caches, 75 // as an invalidation indicates a database INSERT / UPDATE / DELETE. 76 // NOTE THEY ARE ONLY CALLED WHEN THE ITEM IS IN THE CACHE, SO FOR 77 // HOOKS TO BE CALLED ON DELETE YOU MUST FIRST POPULATE IT IN THE CACHE. 78 func (c *Caches) setuphooks() { 79 c.GTS.Account().SetInvalidateCallback(func(account *gtsmodel.Account) { 80 // Invalidate account ID cached visibility. 81 c.Visibility.Invalidate("ItemID", account.ID) 82 c.Visibility.Invalidate("RequesterID", account.ID) 83 }) 84 85 c.GTS.Block().SetInvalidateCallback(func(block *gtsmodel.Block) { 86 // Invalidate block origin account ID cached visibility. 87 c.Visibility.Invalidate("ItemID", block.AccountID) 88 c.Visibility.Invalidate("RequesterID", block.AccountID) 89 90 // Invalidate block target account ID cached visibility. 91 c.Visibility.Invalidate("ItemID", block.TargetAccountID) 92 c.Visibility.Invalidate("RequesterID", block.TargetAccountID) 93 }) 94 95 c.GTS.Follow().SetInvalidateCallback(func(follow *gtsmodel.Follow) { 96 // Invalidate follow origin account ID cached visibility. 97 c.Visibility.Invalidate("ItemID", follow.AccountID) 98 c.Visibility.Invalidate("RequesterID", follow.AccountID) 99 100 // Invalidate follow target account ID cached visibility. 101 c.Visibility.Invalidate("ItemID", follow.TargetAccountID) 102 c.Visibility.Invalidate("RequesterID", follow.TargetAccountID) 103 }) 104 105 c.GTS.FollowRequest().SetInvalidateCallback(func(followReq *gtsmodel.FollowRequest) { 106 // Invalidate follow request origin account ID cached visibility. 107 c.Visibility.Invalidate("ItemID", followReq.AccountID) 108 c.Visibility.Invalidate("RequesterID", followReq.AccountID) 109 110 // Invalidate follow request target account ID cached visibility. 111 c.Visibility.Invalidate("ItemID", followReq.TargetAccountID) 112 c.Visibility.Invalidate("RequesterID", followReq.TargetAccountID) 113 114 // Invalidate any cached follow with same ID. 115 c.GTS.Follow().Invalidate("ID", followReq.ID) 116 }) 117 118 c.GTS.Status().SetInvalidateCallback(func(status *gtsmodel.Status) { 119 // Invalidate status ID cached visibility. 120 c.Visibility.Invalidate("ItemID", status.ID) 121 122 for _, id := range status.AttachmentIDs { 123 // Invalidate cache for attached media IDs, 124 c.GTS.Media().Invalidate("ID", id) 125 } 126 }) 127 128 c.GTS.User().SetInvalidateCallback(func(user *gtsmodel.User) { 129 // Invalidate local account ID cached visibility. 130 c.Visibility.Invalidate("ItemID", user.AccountID) 131 c.Visibility.Invalidate("RequesterID", user.AccountID) 132 }) 133 }