diff options
author | 2021-09-01 10:08:21 +0100 | |
---|---|---|
committer | 2021-09-01 11:08:21 +0200 | |
commit | 7d193de25fbccc00923d6d791d6d4e0d2d5d498e (patch) | |
tree | da993d91aeaccc07c2fff461067325fbe89bba73 /internal/cache/status.go | |
parent | Add SQLite support, fix un-thread-safe DB caches, small performance f… (#172) (diff) | |
download | gotosocial-7d193de25fbccc00923d6d791d6d4e0d2d5d498e.tar.xz |
Improve GetRemoteStatus and db.GetStatus() logic (#174)
* only fetch status parents / children if explicity requested when dereferencing
Signed-off-by: kim (grufwub) <grufwub@gmail.com>
* Remove recursive DB GetStatus logic, don't fetch parent unless requested
Signed-off-by: kim (grufwub) <grufwub@gmail.com>
* StatusCache copies status so there are no thread-safety issues with modified status objects
Signed-off-by: kim (grufwub) <grufwub@gmail.com>
* remove sqlite test files
Signed-off-by: kim (grufwub) <grufwub@gmail.com>
* fix bugs introduced by previous commit
Signed-off-by: kim (grufwub) <grufwub@gmail.com>
* fix not continue on error in loop
Signed-off-by: kim (grufwub) <grufwub@gmail.com>
* use our own RunInTx implementation (possible fix for nested tx error)
Signed-off-by: kim (grufwub) <grufwub@gmail.com>
* fix cast statement to work with SQLite
Signed-off-by: kim (grufwub) <grufwub@gmail.com>
* be less strict about valid status in cache
Signed-off-by: kim (grufwub) <grufwub@gmail.com>
* add cache=shared ALWAYS for SQLite db instances
Signed-off-by: kim (grufwub) <grufwub@gmail.com>
* Fix EnrichRemoteAccount when updating account fails
Signed-off-by: kim (grufwub) <grufwub@gmail.com>
* add nolint tag
Signed-off-by: kim (grufwub) <grufwub@gmail.com>
* ensure file: prefixes the filename in sqlite addr
Signed-off-by: kim (grufwub) <grufwub@gmail.com>
* add an account cache, add status author account from db
Signed-off-by: kim (grufwub) <grufwub@gmail.com>
* Fix incompatible SQLite query
Signed-off-by: kim (grufwub) <grufwub@gmail.com>
* *actually* use the new getAccount() function in accountsDB
Signed-off-by: kim (grufwub) <grufwub@gmail.com>
* update cache tests to use test suite
Signed-off-by: kim (grufwub) <grufwub@gmail.com>
* add RelationshipTestSuite, add tests for methods with changed SQL
Signed-off-by: kim (grufwub) <grufwub@gmail.com>
Diffstat (limited to 'internal/cache/status.go')
-rw-r--r-- | internal/cache/status.go | 70 |
1 files changed, 58 insertions, 12 deletions
diff --git a/internal/cache/status.go b/internal/cache/status.go index 895a5692c..028abc8f7 100644 --- a/internal/cache/status.go +++ b/internal/cache/status.go @@ -37,7 +37,7 @@ func NewStatusCache() *StatusCache { return &c } -// GetByID attempts to fetch a status from the cache by its ID +// GetByID attempts to fetch a status from the cache by its ID, you will receive a copy for thread-safety func (c *StatusCache) GetByID(id string) (*gtsmodel.Status, bool) { c.mutex.Lock() status, ok := c.getByID(id) @@ -45,7 +45,7 @@ func (c *StatusCache) GetByID(id string) (*gtsmodel.Status, bool) { return status, ok } -// GetByURL attempts to fetch a status from the cache by its URL +// GetByURL attempts to fetch a status from the cache by its URL, you will receive a copy for thread-safety func (c *StatusCache) GetByURL(url string) (*gtsmodel.Status, bool) { // Perform safe ID lookup c.mutex.Lock() @@ -63,7 +63,7 @@ func (c *StatusCache) GetByURL(url string) (*gtsmodel.Status, bool) { return status, ok } -// GetByURI attempts to fetch a status from the cache by its URI +// GetByURI attempts to fetch a status from the cache by its URI, you will receive a copy for thread-safety func (c *StatusCache) GetByURI(uri string) (*gtsmodel.Status, bool) { // Perform safe ID lookup c.mutex.Lock() @@ -81,26 +81,72 @@ func (c *StatusCache) GetByURI(uri string) (*gtsmodel.Status, bool) { return status, ok } -// getByID performs an unsafe (no mutex locks) lookup of status by ID +// getByID performs an unsafe (no mutex locks) lookup of status by ID, returning a copy of status in cache func (c *StatusCache) getByID(id string) (*gtsmodel.Status, bool) { v, ok := c.cache.Get(id) if !ok { return nil, false } - return v.(*gtsmodel.Status), true + return copyStatus(v.(*gtsmodel.Status)), true } -// Put places a status in the cache +// Put places a status in the cache, ensuring that the object place is a copy for thread-safety func (c *StatusCache) Put(status *gtsmodel.Status) { - if status == nil || status.ID == "" || - status.URL == "" || - status.URI == "" { + if status == nil || status.ID == "" { panic("invalid status") } c.mutex.Lock() - c.cache.Set(status.ID, status) - c.urls[status.URL] = status.ID - c.uris[status.URI] = status.ID + c.cache.Set(status.ID, copyStatus(status)) + if status.URL != "" { + c.urls[status.URL] = status.ID + } + if status.URI != "" { + c.uris[status.URI] = status.ID + } c.mutex.Unlock() } + +// copyStatus performs a surface-level copy of status, only keeping attached IDs intact, not the objects. +// due to all the data being copied being 99% primitive types or strings (which are immutable and passed by ptr) +// this should be a relatively cheap process +func copyStatus(status *gtsmodel.Status) *gtsmodel.Status { + return >smodel.Status{ + ID: status.ID, + URI: status.URI, + URL: status.URL, + Content: status.Content, + AttachmentIDs: status.AttachmentIDs, + Attachments: nil, + TagIDs: status.TagIDs, + Tags: nil, + MentionIDs: status.MentionIDs, + Mentions: nil, + EmojiIDs: status.EmojiIDs, + Emojis: nil, + CreatedAt: status.CreatedAt, + UpdatedAt: status.UpdatedAt, + Local: status.Local, + AccountID: status.AccountID, + Account: nil, + AccountURI: status.AccountURI, + InReplyToID: status.InReplyToID, + InReplyTo: nil, + InReplyToURI: status.InReplyToURI, + InReplyToAccountID: status.InReplyToAccountID, + InReplyToAccount: nil, + BoostOfID: status.BoostOfID, + BoostOf: nil, + BoostOfAccountID: status.BoostOfAccountID, + BoostOfAccount: nil, + ContentWarning: status.ContentWarning, + Visibility: status.Visibility, + Sensitive: status.Sensitive, + Language: status.Language, + CreatedWithApplicationID: status.CreatedWithApplicationID, + VisibilityAdvanced: status.VisibilityAdvanced, + ActivityStreamsType: status.ActivityStreamsType, + Text: status.Text, + Pinned: status.Pinned, + } +} |