Merge pull request 'feat: improve performance of notifications page for MySQL' (#6146) from gusted/forgejo-notification-perf into forgejo

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6146
Reviewed-by: Michael Kriese <michael.kriese@gmx.de>
This commit is contained in:
Otto 2024-12-05 17:58:36 +00:00
commit 59e0f7fde6
2 changed files with 50 additions and 12 deletions

View file

@ -111,20 +111,26 @@ func getNotifications(ctx *context.Context) {
return return
} }
statuses := []activities_model.NotificationStatus{status, activities_model.NotificationStatusPinned} sess := db.GetEngine(ctx).Table("notification")
nls, err := db.Find[activities_model.Notification](ctx, activities_model.FindNotificationOptions{ if setting.Database.Type.IsMySQL() {
ListOptions: db.ListOptions{ sess = sess.IndexHint("USE", "JOIN", "IDX_notification_user_id")
PageSize: perPage, }
Page: page, sess.Where("user_id = ?", ctx.Doer.ID).
}, And("status = ? OR status = ?", status, activities_model.NotificationStatusPinned).
UserID: ctx.Doer.ID, OrderBy("notification.updated_unix DESC")
Status: statuses,
}) if perPage > 0 {
if err != nil { if page == 0 {
ctx.ServerError("db.Find[activities_model.Notification]", err) page = 1
return }
sess.Limit(perPage, (page-1)*perPage)
} }
nls := make([]*activities_model.Notification, 0, perPage)
if err := sess.Find(&nls); err != nil {
ctx.ServerError("FindNotifications", err)
return
}
notifications := activities_model.NotificationList(nls) notifications := activities_model.NotificationList(nls)
failCount := 0 failCount := 0

View file

@ -0,0 +1,32 @@
// Copyright 2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: GPL-3.0-or-later
package integration
import (
"net/http"
"testing"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/tests"
)
func TestNotification(t *testing.T) {
defer tests.PrepareTestEnv(t)()
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
session := loginUser(t, user2.Name)
req := NewRequest(t, "GET", "/notifications")
resp := session.MakeRequest(t, req, http.StatusOK)
htmlDoc := NewHTMLParser(t, resp.Body)
// Unread and pinned notification.
htmlDoc.AssertElement(t, ".notifications-link[href='/user2/repo1/pulls/3']", true)
htmlDoc.AssertElement(t, ".notifications-link[href='/user2/repo1/issues/4']", true)
htmlDoc.AssertElement(t, ".notifications-link[href='/user2/repo2/issues/1']", true)
// Read notification.
htmlDoc.AssertElement(t, ".notifications-link[href='/user2/repo2/pulls/2']", false)
}