Skip to content

Commit 71b0dd1

Browse files
authored
Merge branch 'main' into any-assignee
2 parents a1a6b8e + a4df01b commit 71b0dd1

File tree

7 files changed

+218
-94
lines changed

7 files changed

+218
-94
lines changed

models/activities/action.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,10 @@ func (a *Action) TableIndices() []*schemas.Index {
172172
cuIndex := schemas.NewIndex("c_u", schemas.IndexType)
173173
cuIndex.AddColumn("user_id", "is_deleted")
174174

175-
indices := []*schemas.Index{actUserIndex, repoIndex, cudIndex, cuIndex}
175+
actUserUserIndex := schemas.NewIndex("au_c_u", schemas.IndexType)
176+
actUserUserIndex.AddColumn("act_user_id", "created_unix", "user_id")
177+
178+
indices := []*schemas.Index{actUserIndex, repoIndex, cudIndex, cuIndex, actUserUserIndex}
176179

177180
return indices
178181
}
@@ -442,6 +445,7 @@ type GetFeedsOptions struct {
442445
OnlyPerformedBy bool // only actions performed by requested user
443446
IncludeDeleted bool // include deleted actions
444447
Date string // the day we want activity for: YYYY-MM-DD
448+
DontCount bool // do counting in GetFeeds
445449
}
446450

447451
// ActivityReadable return whether doer can read activities of user

models/activities/action_list.go

+18-6
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,11 @@ func GetFeeds(ctx context.Context, opts GetFeedsOptions) (ActionList, int64, err
243243
sess := db.GetEngine(ctx).Where(cond)
244244
sess = db.SetSessionPagination(sess, &opts)
245245

246-
count, err = sess.Desc("`action`.created_unix").FindAndCount(&actions)
246+
if opts.DontCount {
247+
err = sess.Desc("`action`.created_unix").Find(&actions)
248+
} else {
249+
count, err = sess.Desc("`action`.created_unix").FindAndCount(&actions)
250+
}
247251
if err != nil {
248252
return nil, 0, fmt.Errorf("FindAndCount: %w", err)
249253
}
@@ -257,11 +261,13 @@ func GetFeeds(ctx context.Context, opts GetFeedsOptions) (ActionList, int64, err
257261
return nil, 0, fmt.Errorf("Find(actionsIDs): %w", err)
258262
}
259263

260-
count, err = db.GetEngine(ctx).Where(cond).
261-
Table("action").
262-
Cols("`action`.id").Count()
263-
if err != nil {
264-
return nil, 0, fmt.Errorf("Count: %w", err)
264+
if !opts.DontCount {
265+
count, err = db.GetEngine(ctx).Where(cond).
266+
Table("action").
267+
Cols("`action`.id").Count()
268+
if err != nil {
269+
return nil, 0, fmt.Errorf("Count: %w", err)
270+
}
265271
}
266272

267273
if err := db.GetEngine(ctx).In("`action`.id", actionIDs).Desc("`action`.created_unix").Find(&actions); err != nil {
@@ -275,3 +281,9 @@ func GetFeeds(ctx context.Context, opts GetFeedsOptions) (ActionList, int64, err
275281

276282
return actions, count, nil
277283
}
284+
285+
func CountUserFeeds(ctx context.Context, userID int64) (int64, error) {
286+
return db.GetEngine(ctx).Where("user_id = ?", userID).
287+
And("is_deleted = ?", false).
288+
Count(&Action{})
289+
}

models/migrations/migrations.go

+1
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,7 @@ func prepareMigrationTasks() []*migration {
377377
newMigration(314, "Update OwnerID as zero for repository level action tables", v1_24.UpdateOwnerIDOfRepoLevelActionsTables),
378378
newMigration(315, "Add Ephemeral to ActionRunner", v1_24.AddEphemeralToActionRunner),
379379
newMigration(316, "Add description for secrets and variables", v1_24.AddDescriptionForSecretsAndVariables),
380+
newMigration(317, "Add new index for action for heatmap", v1_24.AddNewIndexForUserDashboard),
380381
}
381382
return preparedMigrations
382383
}

models/migrations/v1_24/v317.go

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// Copyright 2025 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package v1_24 //nolint
5+
6+
import (
7+
"code.gitea.io/gitea/modules/timeutil"
8+
9+
"xorm.io/xorm"
10+
"xorm.io/xorm/schemas"
11+
)
12+
13+
type improveActionTableIndicesAction struct {
14+
ID int64 `xorm:"pk autoincr"`
15+
UserID int64 `xorm:"INDEX"` // Receiver user id.
16+
OpType int
17+
ActUserID int64 // Action user id.
18+
RepoID int64
19+
CommentID int64 `xorm:"INDEX"`
20+
IsDeleted bool `xorm:"NOT NULL DEFAULT false"`
21+
RefName string
22+
IsPrivate bool `xorm:"NOT NULL DEFAULT false"`
23+
Content string `xorm:"TEXT"`
24+
CreatedUnix timeutil.TimeStamp `xorm:"created"`
25+
}
26+
27+
// TableName sets the name of this table
28+
func (*improveActionTableIndicesAction) TableName() string {
29+
return "action"
30+
}
31+
32+
// TableIndices implements xorm's TableIndices interface
33+
func (a *improveActionTableIndicesAction) TableIndices() []*schemas.Index {
34+
repoIndex := schemas.NewIndex("r_u_d", schemas.IndexType)
35+
repoIndex.AddColumn("repo_id", "user_id", "is_deleted")
36+
37+
actUserIndex := schemas.NewIndex("au_r_c_u_d", schemas.IndexType)
38+
actUserIndex.AddColumn("act_user_id", "repo_id", "created_unix", "user_id", "is_deleted")
39+
40+
cudIndex := schemas.NewIndex("c_u_d", schemas.IndexType)
41+
cudIndex.AddColumn("created_unix", "user_id", "is_deleted")
42+
43+
cuIndex := schemas.NewIndex("c_u", schemas.IndexType)
44+
cuIndex.AddColumn("user_id", "is_deleted")
45+
46+
actUserUserIndex := schemas.NewIndex("au_c_u", schemas.IndexType)
47+
actUserUserIndex.AddColumn("act_user_id", "created_unix", "user_id")
48+
49+
indices := []*schemas.Index{actUserIndex, repoIndex, cudIndex, cuIndex, actUserUserIndex}
50+
51+
return indices
52+
}
53+
54+
func AddNewIndexForUserDashboard(x *xorm.Engine) error {
55+
return x.Sync(new(improveActionTableIndicesAction))
56+
}

routers/web/user/home.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ func Dashboard(ctx *context.Context) {
119119
ctx.Data["HeatmapTotalContributions"] = activities_model.GetTotalContributionsInHeatmap(data)
120120
}
121121

122-
feeds, count, err := feed_service.GetFeeds(ctx, activities_model.GetFeedsOptions{
122+
feeds, count, err := feed_service.GetFeedsForDashboard(ctx, activities_model.GetFeedsOptions{
123123
RequestedUser: ctxUser,
124124
RequestedTeam: ctx.Org.Team,
125125
Actor: ctx.Doer,

services/feed/feed.go

+26
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,28 @@ import (
1313
repo_model "code.gitea.io/gitea/models/repo"
1414
"code.gitea.io/gitea/models/unit"
1515
user_model "code.gitea.io/gitea/models/user"
16+
"code.gitea.io/gitea/modules/cache"
1617
"code.gitea.io/gitea/modules/setting"
1718
)
1819

20+
func userFeedCacheKey(userID int64) string {
21+
return fmt.Sprintf("user_feed_%d", userID)
22+
}
23+
24+
func GetFeedsForDashboard(ctx context.Context, opts activities_model.GetFeedsOptions) (activities_model.ActionList, int64, error) {
25+
opts.DontCount = opts.RequestedTeam == nil && opts.Date == ""
26+
results, cnt, err := activities_model.GetFeeds(ctx, opts)
27+
if err != nil {
28+
return nil, 0, err
29+
}
30+
if opts.DontCount {
31+
cnt, err = cache.GetInt64(userFeedCacheKey(opts.Actor.ID), func() (int64, error) {
32+
return activities_model.CountUserFeeds(ctx, opts.Actor.ID)
33+
})
34+
}
35+
return results, cnt, err
36+
}
37+
1938
// GetFeeds returns actions according to the provided options
2039
func GetFeeds(ctx context.Context, opts activities_model.GetFeedsOptions) (activities_model.ActionList, int64, error) {
2140
return activities_model.GetFeeds(ctx, opts)
@@ -68,6 +87,13 @@ func notifyWatchers(ctx context.Context, act *activities_model.Action, watchers
6887
if err := db.Insert(ctx, act); err != nil {
6988
return fmt.Errorf("insert new action: %w", err)
7089
}
90+
91+
total, err := activities_model.CountUserFeeds(ctx, act.UserID)
92+
if err != nil {
93+
return fmt.Errorf("count user feeds: %w", err)
94+
}
95+
96+
_ = cache.GetCache().Put(userFeedCacheKey(act.UserID), fmt.Sprintf("%d", total), setting.CacheService.TTLSeconds())
7197
}
7298

7399
return nil

0 commit comments

Comments
 (0)