diff options
author | 2021-08-29 15:41:41 +0100 | |
---|---|---|
committer | 2021-08-29 16:41:41 +0200 | |
commit | ed462245730bd7832019bd43e0bc1c9d1c055e8e (patch) | |
tree | 1caad78ea6aabf5ea93c93a8ade97176b4889500 /internal/db/bundb/notification.go | |
parent | Mention fixup (#167) (diff) | |
download | gotosocial-ed462245730bd7832019bd43e0bc1c9d1c055e8e.tar.xz |
Add SQLite support, fix un-thread-safe DB caches, small performance f… (#172)
* Add SQLite support, fix un-thread-safe DB caches, small performance fixes
Signed-off-by: kim (grufwub) <grufwub@gmail.com>
* add SQLite licenses to README
Signed-off-by: kim (grufwub) <grufwub@gmail.com>
* appease the linter, and fix my dumbass-ery
Signed-off-by: kim (grufwub) <grufwub@gmail.com>
* make requested changes
Signed-off-by: kim (grufwub) <grufwub@gmail.com>
* add back comment
Signed-off-by: kim (grufwub) <grufwub@gmail.com>
Diffstat (limited to 'internal/db/bundb/notification.go')
-rw-r--r-- | internal/db/bundb/notification.go | 115 |
1 files changed, 57 insertions, 58 deletions
diff --git a/internal/db/bundb/notification.go b/internal/db/bundb/notification.go index 1c30837ec..d3be16168 100644 --- a/internal/db/bundb/notification.go +++ b/internal/db/bundb/notification.go @@ -21,8 +21,7 @@ package bundb import ( "context" - "github.com/sirupsen/logrus" - "github.com/superseriousbusiness/gotosocial/internal/cache" + "github.com/ReneKroon/ttlcache" "github.com/superseriousbusiness/gotosocial/internal/config" "github.com/superseriousbusiness/gotosocial/internal/db" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" @@ -31,38 +30,8 @@ import ( type notificationDB struct { config *config.Config - conn *bun.DB - log *logrus.Logger - cache cache.Cache -} - -func (n *notificationDB) cacheNotification(id string, notification *gtsmodel.Notification) { - if n.cache == nil { - n.cache = cache.New() - } - - if err := n.cache.Store(id, notification); err != nil { - n.log.Panicf("notificationDB: error storing in cache: %s", err) - } -} - -func (n *notificationDB) notificationCached(id string) (*gtsmodel.Notification, bool) { - if n.cache == nil { - n.cache = cache.New() - return nil, false - } - - nI, err := n.cache.Fetch(id) - if err != nil || nI == nil { - return nil, false - } - - notification, ok := nI.(*gtsmodel.Notification) - if !ok { - n.log.Panicf("notificationDB: cached interface with key %s was not a notification", id) - } - - return notification, true + conn *DBConn + cache *ttlcache.Cache } func (n *notificationDB) newNotificationQ(i interface{}) *bun.SelectQuery { @@ -75,30 +44,30 @@ func (n *notificationDB) newNotificationQ(i interface{}) *bun.SelectQuery { } func (n *notificationDB) GetNotification(ctx context.Context, id string) (*gtsmodel.Notification, db.Error) { - if notification, cached := n.notificationCached(id); cached { + if notification, cached := n.getNotificationCache(id); cached { return notification, nil } - notification := >smodel.Notification{} - - q := n.newNotificationQ(notification). - Where("notification.id = ?", id) - - err := processErrorResponse(q.Scan(ctx)) - - if err == nil && notification != nil { - n.cacheNotification(id, notification) + notif := >smodel.Notification{} + err := n.getNotificationDB(ctx, id, notif) + if err != nil { + return nil, err } - - return notification, err + return notif, nil } func (n *notificationDB) GetNotifications(ctx context.Context, accountID string, limit int, maxID string, sinceID string) ([]*gtsmodel.Notification, db.Error) { - // begin by selecting just the IDs - notifIDs := []*gtsmodel.Notification{} + // Ensure reasonable + if limit < 0 { + limit = 0 + } + + // Make a guess for slice size + notifications := make([]*gtsmodel.Notification, 0, limit) + q := n.conn. NewSelect(). - Model(¬ifIDs). + Model(¬ifications). Column("id"). Where("target_account_id = ?", accountID). Order("id DESC") @@ -115,22 +84,52 @@ func (n *notificationDB) GetNotifications(ctx context.Context, accountID string, q = q.Limit(limit) } - err := processErrorResponse(q.Scan(ctx)) + err := q.Scan(ctx) if err != nil { - return nil, err + return nil, n.conn.ProcessError(err) } // now we have the IDs, select the notifs one by one // reason for this is that for each notif, we can instead get it from our cache if it's cached - notifications := []*gtsmodel.Notification{} - for _, notifID := range notifIDs { - notif, err := n.GetNotification(ctx, notifID.ID) - errP := processErrorResponse(err) - if errP != nil { - return nil, errP + for i, notif := range notifications { + // Check cache for notification + nn, cached := n.getNotificationCache(notif.ID) + if cached { + notifications[i] = nn + continue + } + + // Check DB for notification + err := n.getNotificationDB(ctx, notif.ID, notif) + if err != nil { + return nil, err } - notifications = append(notifications, notif) } return notifications, nil } + +func (n *notificationDB) getNotificationCache(id string) (*gtsmodel.Notification, bool) { + v, ok := n.cache.Get(id) + if !ok { + return nil, false + } + return v.(*gtsmodel.Notification), true +} + +func (n *notificationDB) putNotificationCache(notif *gtsmodel.Notification) { + n.cache.Set(notif.ID, notif) +} + +func (n *notificationDB) getNotificationDB(ctx context.Context, id string, dst *gtsmodel.Notification) error { + q := n.newNotificationQ(dst). + Where("notification.id = ?", id) + + err := q.Scan(ctx) + if err != nil { + return n.conn.ProcessError(err) + } + + n.putNotificationCache(dst) + return nil +} |