gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

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 }