summaryrefslogtreecommitdiff
path: root/internal/db/bundb/notification.go
diff options
context:
space:
mode:
authorLibravatar kim <89579420+NyaaaWhatsUpDoc@users.noreply.github.com>2021-08-29 15:41:41 +0100
committerLibravatar GitHub <noreply@github.com>2021-08-29 16:41:41 +0200
commited462245730bd7832019bd43e0bc1c9d1c055e8e (patch)
tree1caad78ea6aabf5ea93c93a8ade97176b4889500 /internal/db/bundb/notification.go
parentMention fixup (#167) (diff)
downloadgotosocial-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.go115
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 := &gtsmodel.Notification{}
-
- q := n.newNotificationQ(notification).
- Where("notification.id = ?", id)
-
- err := processErrorResponse(q.Scan(ctx))
-
- if err == nil && notification != nil {
- n.cacheNotification(id, notification)
+ notif := &gtsmodel.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(&notifIDs).
+ Model(&notifications).
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
+}