Skip to content

Commit 673fee4

Browse files
lunnywxiaoguang
andauthored
Refactor push mirror find and add check for updating push mirror (#32539) (#32549)
backport #32539 --------- Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
1 parent 578c02d commit 673fee4

File tree

8 files changed

+147
-108
lines changed

8 files changed

+147
-108
lines changed

models/db/collation.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,8 @@ func CheckCollations(x *xorm.Engine) (*CheckCollationsResult, error) {
6868

6969
var candidateCollations []string
7070
if x.Dialect().URI().DBType == schemas.MYSQL {
71-
if _, err = x.SQL("SELECT @@collation_database").Get(&res.DatabaseCollation); err != nil {
71+
_, err = x.SQL("SELECT DEFAULT_COLLATION_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = ?", setting.Database.Name).Get(&res.DatabaseCollation)
72+
if err != nil {
7273
return nil, err
7374
}
7475
res.IsCollationCaseSensitive = func(s string) bool {

models/repo/pushmirror.go

+34-16
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,13 @@ import (
99

1010
"code.gitea.io/gitea/models/db"
1111
"code.gitea.io/gitea/modules/log"
12+
"code.gitea.io/gitea/modules/optional"
1213
"code.gitea.io/gitea/modules/timeutil"
1314
"code.gitea.io/gitea/modules/util"
1415

1516
"xorm.io/builder"
1617
)
1718

18-
// ErrPushMirrorNotExist mirror does not exist error
19-
var ErrPushMirrorNotExist = util.NewNotExistErrorf("PushMirror does not exist")
20-
2119
// PushMirror represents mirror information of a repository.
2220
type PushMirror struct {
2321
ID int64 `xorm:"pk autoincr"`
@@ -96,26 +94,46 @@ func DeletePushMirrors(ctx context.Context, opts PushMirrorOptions) error {
9694
return util.NewInvalidArgumentErrorf("repoID required and must be set")
9795
}
9896

97+
type findPushMirrorOptions struct {
98+
db.ListOptions
99+
RepoID int64
100+
SyncOnCommit optional.Option[bool]
101+
}
102+
103+
func (opts findPushMirrorOptions) ToConds() builder.Cond {
104+
cond := builder.NewCond()
105+
if opts.RepoID > 0 {
106+
cond = cond.And(builder.Eq{"repo_id": opts.RepoID})
107+
}
108+
if opts.SyncOnCommit.Has() {
109+
cond = cond.And(builder.Eq{"sync_on_commit": opts.SyncOnCommit.Value()})
110+
}
111+
return cond
112+
}
113+
99114
// GetPushMirrorsByRepoID returns push-mirror information of a repository.
100115
func GetPushMirrorsByRepoID(ctx context.Context, repoID int64, listOptions db.ListOptions) ([]*PushMirror, int64, error) {
101-
sess := db.GetEngine(ctx).Where("repo_id = ?", repoID)
102-
if listOptions.Page != 0 {
103-
sess = db.SetSessionPagination(sess, &listOptions)
104-
mirrors := make([]*PushMirror, 0, listOptions.PageSize)
105-
count, err := sess.FindAndCount(&mirrors)
106-
return mirrors, count, err
116+
return db.FindAndCount[PushMirror](ctx, findPushMirrorOptions{
117+
ListOptions: listOptions,
118+
RepoID: repoID,
119+
})
120+
}
121+
122+
func GetPushMirrorByIDAndRepoID(ctx context.Context, id, repoID int64) (*PushMirror, bool, error) {
123+
var pushMirror PushMirror
124+
has, err := db.GetEngine(ctx).Where("id = ?", id).And("repo_id = ?", repoID).Get(&pushMirror)
125+
if !has || err != nil {
126+
return nil, has, err
107127
}
108-
mirrors := make([]*PushMirror, 0, 10)
109-
count, err := sess.FindAndCount(&mirrors)
110-
return mirrors, count, err
128+
return &pushMirror, true, nil
111129
}
112130

113131
// GetPushMirrorsSyncedOnCommit returns push-mirrors for this repo that should be updated by new commits
114132
func GetPushMirrorsSyncedOnCommit(ctx context.Context, repoID int64) ([]*PushMirror, error) {
115-
mirrors := make([]*PushMirror, 0, 10)
116-
return mirrors, db.GetEngine(ctx).
117-
Where("repo_id = ? AND sync_on_commit = ?", repoID, true).
118-
Find(&mirrors)
133+
return db.Find[PushMirror](ctx, findPushMirrorOptions{
134+
RepoID: repoID,
135+
SyncOnCommit: optional.Some(true),
136+
})
119137
}
120138

121139
// PushMirrorsIterate iterates all push-mirror repositories.

routers/web/repo/setting/setting.go

+15-36
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import (
88
"errors"
99
"fmt"
1010
"net/http"
11-
"strconv"
1211
"strings"
1312
"time"
1413

@@ -298,8 +297,8 @@ func SettingsPost(ctx *context.Context) {
298297
return
299298
}
300299

301-
m, err := selectPushMirrorByForm(ctx, form, repo)
302-
if err != nil {
300+
m, _, _ := repo_model.GetPushMirrorByIDAndRepoID(ctx, form.PushMirrorID, repo.ID)
301+
if m == nil {
303302
ctx.NotFound("", nil)
304303
return
305304
}
@@ -325,15 +324,13 @@ func SettingsPost(ctx *context.Context) {
325324
return
326325
}
327326

328-
id, err := strconv.ParseInt(form.PushMirrorID, 10, 64)
329-
if err != nil {
330-
ctx.ServerError("UpdatePushMirrorIntervalPushMirrorID", err)
327+
m, _, _ := repo_model.GetPushMirrorByIDAndRepoID(ctx, form.PushMirrorID, repo.ID)
328+
if m == nil {
329+
ctx.NotFound("", nil)
331330
return
332331
}
333-
m := &repo_model.PushMirror{
334-
ID: id,
335-
Interval: interval,
336-
}
332+
333+
m.Interval = interval
337334
if err := repo_model.UpdatePushMirrorInterval(ctx, m); err != nil {
338335
ctx.ServerError("UpdatePushMirrorInterval", err)
339336
return
@@ -342,7 +339,10 @@ func SettingsPost(ctx *context.Context) {
342339
// If we observed its implementation in the context of `push-mirror-sync` where it
343340
// is evident that pushing to the queue is necessary for updates.
344341
// So, there are updates within the given interval, it is necessary to update the queue accordingly.
345-
mirror_service.AddPushMirrorToQueue(m.ID)
342+
if !ctx.FormBool("push_mirror_defer_sync") {
343+
// push_mirror_defer_sync is mainly for testing purpose, we do not really want to sync the push mirror immediately
344+
mirror_service.AddPushMirrorToQueue(m.ID)
345+
}
346346
ctx.Flash.Success(ctx.Tr("repo.settings.update_settings_success"))
347347
ctx.Redirect(repo.Link() + "/settings")
348348

@@ -356,18 +356,18 @@ func SettingsPost(ctx *context.Context) {
356356
// as an error on the UI for this action
357357
ctx.Data["Err_RepoName"] = nil
358358

359-
m, err := selectPushMirrorByForm(ctx, form, repo)
360-
if err != nil {
359+
m, _, _ := repo_model.GetPushMirrorByIDAndRepoID(ctx, form.PushMirrorID, repo.ID)
360+
if m == nil {
361361
ctx.NotFound("", nil)
362362
return
363363
}
364364

365-
if err = mirror_service.RemovePushMirrorRemote(ctx, m); err != nil {
365+
if err := mirror_service.RemovePushMirrorRemote(ctx, m); err != nil {
366366
ctx.ServerError("RemovePushMirrorRemote", err)
367367
return
368368
}
369369

370-
if err = repo_model.DeletePushMirrors(ctx, repo_model.PushMirrorOptions{ID: m.ID, RepoID: m.RepoID}); err != nil {
370+
if err := repo_model.DeletePushMirrors(ctx, repo_model.PushMirrorOptions{ID: m.ID, RepoID: m.RepoID}); err != nil {
371371
ctx.ServerError("DeletePushMirrorByID", err)
372372
return
373373
}
@@ -970,24 +970,3 @@ func handleSettingRemoteAddrError(ctx *context.Context, err error, form *forms.R
970970
}
971971
ctx.RenderWithErr(ctx.Tr("repo.mirror_address_url_invalid"), tplSettingsOptions, form)
972972
}
973-
974-
func selectPushMirrorByForm(ctx *context.Context, form *forms.RepoSettingForm, repo *repo_model.Repository) (*repo_model.PushMirror, error) {
975-
id, err := strconv.ParseInt(form.PushMirrorID, 10, 64)
976-
if err != nil {
977-
return nil, err
978-
}
979-
980-
pushMirrors, _, err := repo_model.GetPushMirrorsByRepoID(ctx, repo.ID, db.ListOptions{})
981-
if err != nil {
982-
return nil, err
983-
}
984-
985-
for _, m := range pushMirrors {
986-
if m.ID == id {
987-
m.Repo = repo
988-
return m, nil
989-
}
990-
}
991-
992-
return nil, fmt.Errorf("PushMirror[%v] not associated to repository %v", id, repo)
993-
}

services/forms/repo_form.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ type RepoSettingForm struct {
119119
MirrorPassword string
120120
LFS bool `form:"mirror_lfs"`
121121
LFSEndpoint string `form:"mirror_lfs_endpoint"`
122-
PushMirrorID string
122+
PushMirrorID int64
123123
PushMirrorAddress string
124124
PushMirrorUsername string
125125
PushMirrorPassword string

services/mirror/mirror.go

+1-9
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import (
88
"fmt"
99

1010
repo_model "code.gitea.io/gitea/models/repo"
11-
"code.gitea.io/gitea/modules/graceful"
1211
"code.gitea.io/gitea/modules/log"
1312
"code.gitea.io/gitea/modules/queue"
1413
"code.gitea.io/gitea/modules/setting"
@@ -119,14 +118,7 @@ func Update(ctx context.Context, pullLimit, pushLimit int) error {
119118
return nil
120119
}
121120

122-
func queueHandler(items ...*SyncRequest) []*SyncRequest {
123-
for _, req := range items {
124-
doMirrorSync(graceful.GetManager().ShutdownContext(), req)
125-
}
126-
return nil
127-
}
128-
129121
// InitSyncMirrors initializes a go routine to sync the mirrors
130122
func InitSyncMirrors() {
131-
StartSyncMirrors(queueHandler)
123+
StartSyncMirrors()
132124
}

services/mirror/queue.go

+9-2
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,19 @@ type SyncRequest struct {
2828
ReferenceID int64 // RepoID for pull mirror, MirrorID for push mirror
2929
}
3030

31+
func queueHandler(items ...*SyncRequest) []*SyncRequest {
32+
for _, req := range items {
33+
doMirrorSync(graceful.GetManager().ShutdownContext(), req)
34+
}
35+
return nil
36+
}
37+
3138
// StartSyncMirrors starts a go routine to sync the mirrors
32-
func StartSyncMirrors(queueHandle func(data ...*SyncRequest) []*SyncRequest) {
39+
func StartSyncMirrors() {
3340
if !setting.Mirror.Enabled {
3441
return
3542
}
36-
mirrorQueue = queue.CreateUniqueQueue(graceful.GetManager().ShutdownContext(), "mirror", queueHandle)
43+
mirrorQueue = queue.CreateUniqueQueue(graceful.GetManager().ShutdownContext(), "mirror", queueHandler)
3744
if mirrorQueue == nil {
3845
log.Fatal("Unable to create mirror queue")
3946
}

tests/integration/db_collation_test.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,12 @@ func TestDatabaseCollation(t *testing.T) {
7373

7474
t.Run("Convert tables to utf8mb4_bin", func(t *testing.T) {
7575
defer test.MockVariableValue(&setting.Database.CharsetCollation, "utf8mb4_bin")()
76-
assert.NoError(t, db.ConvertDatabaseTable())
7776
r, err := db.CheckCollations(x)
7877
assert.NoError(t, err)
78+
assert.EqualValues(t, "utf8mb4_bin", r.ExpectedCollation)
79+
assert.NoError(t, db.ConvertDatabaseTable())
80+
r, err = db.CheckCollations(x)
81+
assert.NoError(t, err)
7982
assert.Equal(t, "utf8mb4_bin", r.DatabaseCollation)
8083
assert.True(t, r.CollationEquals(r.ExpectedCollation, r.DatabaseCollation))
8184
assert.Empty(t, r.InconsistentCollationColumns)

0 commit comments

Comments
 (0)