From ab1af217969d1563b3526383244df5220b6ba931 Mon Sep 17 00:00:00 2001 From: Andrew Thornton Date: Sun, 30 May 2021 15:53:40 +0100 Subject: [PATCH 1/6] Make modules/context.Context a context.Context Signed-off-by: Andrew Thornton --- modules/context/context.go | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/modules/context/context.go b/modules/context/context.go index d812d7b58cddc..790a1fd987b01 100644 --- a/modules/context/context.go +++ b/modules/context/context.go @@ -528,6 +528,26 @@ func (ctx *Context) Status(status int) { ctx.Resp.WriteHeader(status) } +// Deadline is part of the interface for context.Context and we pass this to the request context +func (ctx *Context) Deadline() (deadline time.Time, ok bool) { + return ctx.Req.Context().Deadline() +} + +// Done is part of the interface for context.Context and we pass this to the request context +func (ctx *Context) Done() <-chan struct{} { + return ctx.Req.Context().Done() +} + +// Err is part of the interface for context.Context and we pass this to the request context +func (ctx *Context) Err() error { + return ctx.Req.Context().Err() +} + +// Value is part of the interface for context.Context and we pass this to the request context +func (ctx *Context) Value(key interface{}) interface{} { + return ctx.Req.Context().Value(key) +} + // Handler represents a custom handler type Handler func(*Context) From 700b38abb56f46412d82be8dd0d94f3ebbcb6a99 Mon Sep 17 00:00:00 2001 From: Andrew Thornton Date: Sun, 30 May 2021 15:56:22 +0100 Subject: [PATCH 2/6] Simplify context calls Signed-off-by: Andrew Thornton --- modules/context/context.go | 2 +- routers/admin/users.go | 4 ++-- routers/api/v1/admin/user.go | 4 ++-- routers/events/events.go | 2 +- routers/install.go | 4 ++-- routers/private/manager.go | 2 +- routers/private/restore_repo.go | 2 +- routers/repo/blame.go | 2 +- routers/repo/lfs.go | 2 +- routers/user/auth.go | 12 ++++++------ routers/user/auth_openid.go | 4 ++-- routers/user/setting/account.go | 2 +- services/archiver/archiver.go | 4 ++-- 13 files changed, 23 insertions(+), 23 deletions(-) diff --git a/modules/context/context.go b/modules/context/context.go index 790a1fd987b01..d45e9ff87cd89 100644 --- a/modules/context/context.go +++ b/modules/context/context.go @@ -509,7 +509,7 @@ func (ctx *Context) ParamsInt64(p string) int64 { // SetParams set params into routes func (ctx *Context) SetParams(k, v string) { - chiCtx := chi.RouteContext(ctx.Req.Context()) + chiCtx := chi.RouteContext(ctx) chiCtx.URLParams.Add(strings.TrimPrefix(k, ":"), url.PathEscape(v)) } diff --git a/routers/admin/users.go b/routers/admin/users.go index 3b29eeefc1afd..a71a11dd8a225 100644 --- a/routers/admin/users.go +++ b/routers/admin/users.go @@ -113,7 +113,7 @@ func NewUserPost(ctx *context.Context) { ctx.RenderWithErr(password.BuildComplexityError(ctx), tplUserNew, &form) return } - pwned, err := password.IsPwned(ctx.Req.Context(), form.Password) + pwned, err := password.IsPwned(ctx, form.Password) if pwned { ctx.Data["Err_Password"] = true errMsg := ctx.Tr("auth.password_pwned") @@ -256,7 +256,7 @@ func EditUserPost(ctx *context.Context) { ctx.RenderWithErr(password.BuildComplexityError(ctx), tplUserEdit, &form) return } - pwned, err := password.IsPwned(ctx.Req.Context(), form.Password) + pwned, err := password.IsPwned(ctx, form.Password) if pwned { ctx.Data["Err_Password"] = true errMsg := ctx.Tr("auth.password_pwned") diff --git a/routers/api/v1/admin/user.go b/routers/api/v1/admin/user.go index 2d4a3815f4ca4..4bbe7f77ba2ea 100644 --- a/routers/api/v1/admin/user.go +++ b/routers/api/v1/admin/user.go @@ -88,7 +88,7 @@ func CreateUser(ctx *context.APIContext) { ctx.Error(http.StatusBadRequest, "PasswordComplexity", err) return } - pwned, err := password.IsPwned(ctx.Req.Context(), form.Password) + pwned, err := password.IsPwned(ctx, form.Password) if pwned { if err != nil { log.Error(err.Error()) @@ -162,7 +162,7 @@ func EditUser(ctx *context.APIContext) { ctx.Error(http.StatusBadRequest, "PasswordComplexity", err) return } - pwned, err := password.IsPwned(ctx.Req.Context(), form.Password) + pwned, err := password.IsPwned(ctx, form.Password) if pwned { if err != nil { log.Error(err.Error()) diff --git a/routers/events/events.go b/routers/events/events.go index 2c1034038fbb2..b140bf660cace 100644 --- a/routers/events/events.go +++ b/routers/events/events.go @@ -42,7 +42,7 @@ func Events(ctx *context.Context) { } // Listen to connection close and un-register messageChan - notify := ctx.Req.Context().Done() + notify := ctx.Done() ctx.Resp.Flush() shutdownCtx := graceful.GetManager().ShutdownContext() diff --git a/routers/install.go b/routers/install.go index ef53422c4e128..30340e99cd636 100644 --- a/routers/install.go +++ b/routers/install.go @@ -400,7 +400,7 @@ func InstallPost(ctx *context.Context) { } // Re-read settings - PostInstallInit(ctx.Req.Context()) + PostInstallInit(ctx) // Create admin account if len(form.AdminName) > 0 { @@ -454,7 +454,7 @@ func InstallPost(ctx *context.Context) { // Now get the http.Server from this request and shut it down // NB: This is not our hammerable graceful shutdown this is http.Server.Shutdown - srv := ctx.Req.Context().Value(http.ServerContextKey).(*http.Server) + srv := ctx.Value(http.ServerContextKey).(*http.Server) go func() { if err := srv.Shutdown(graceful.GetManager().HammerContext()); err != nil { log.Error("Unable to shutdown the install server! Error: %v", err) diff --git a/routers/private/manager.go b/routers/private/manager.go index 192c4947e76a1..1ccb1843630ce 100644 --- a/routers/private/manager.go +++ b/routers/private/manager.go @@ -35,7 +35,7 @@ func FlushQueues(ctx *context.PrivateContext) { }) return } - err := queue.GetManager().FlushAll(ctx.Req.Context(), opts.Timeout) + err := queue.GetManager().FlushAll(ctx, opts.Timeout) if err != nil { ctx.JSON(http.StatusRequestTimeout, map[string]interface{}{ "err": fmt.Sprintf("%v", err), diff --git a/routers/private/restore_repo.go b/routers/private/restore_repo.go index c002de874a96e..df787e1b33089 100644 --- a/routers/private/restore_repo.go +++ b/routers/private/restore_repo.go @@ -36,7 +36,7 @@ func RestoreRepo(ctx *myCtx.PrivateContext) { } if err := migrations.RestoreRepository( - ctx.Req.Context(), + ctx, params.RepoDir, params.OwnerName, params.RepoName, diff --git a/routers/repo/blame.go b/routers/repo/blame.go index f5b228bdfe136..1a3e1dcb9c570 100644 --- a/routers/repo/blame.go +++ b/routers/repo/blame.go @@ -124,7 +124,7 @@ func RefBlame(ctx *context.Context) { return } - blameReader, err := git.CreateBlameReader(ctx.Req.Context(), models.RepoPath(userName, repoName), commitID, fileName) + blameReader, err := git.CreateBlameReader(ctx, models.RepoPath(userName, repoName), commitID, fileName) if err != nil { ctx.NotFound("CreateBlameReader", err) return diff --git a/routers/repo/lfs.go b/routers/repo/lfs.go index 3a7ce2e23bd51..c17bd2f87a2d8 100644 --- a/routers/repo/lfs.go +++ b/routers/repo/lfs.go @@ -414,7 +414,7 @@ func LFSPointerFiles(ctx *context.Context) { err = func() error { pointerChan := make(chan lfs.PointerBlob) errChan := make(chan error, 1) - go lfs.SearchPointerBlobs(ctx.Req.Context(), ctx.Repo.GitRepo, pointerChan, errChan) + go lfs.SearchPointerBlobs(ctx, ctx.Repo.GitRepo, pointerChan, errChan) numPointers := 0 var numAssociated, numNoExist, numAssociatable int diff --git a/routers/user/auth.go b/routers/user/auth.go index 5f8b1a6b99a7b..827b7cdef0651 100644 --- a/routers/user/auth.go +++ b/routers/user/auth.go @@ -1011,9 +1011,9 @@ func LinkAccountPostRegister(ctx *context.Context) { case setting.ImageCaptcha: valid = context.GetImageCaptcha().VerifyReq(ctx.Req) case setting.ReCaptcha: - valid, err = recaptcha.Verify(ctx.Req.Context(), form.GRecaptchaResponse) + valid, err = recaptcha.Verify(ctx, form.GRecaptchaResponse) case setting.HCaptcha: - valid, err = hcaptcha.Verify(ctx.Req.Context(), form.HcaptchaResponse) + valid, err = hcaptcha.Verify(ctx, form.HcaptchaResponse) default: ctx.ServerError("Unknown Captcha Type", fmt.Errorf("Unknown Captcha Type: %s", setting.Service.CaptchaType)) return @@ -1153,9 +1153,9 @@ func SignUpPost(ctx *context.Context) { case setting.ImageCaptcha: valid = context.GetImageCaptcha().VerifyReq(ctx.Req) case setting.ReCaptcha: - valid, err = recaptcha.Verify(ctx.Req.Context(), form.GRecaptchaResponse) + valid, err = recaptcha.Verify(ctx, form.GRecaptchaResponse) case setting.HCaptcha: - valid, err = hcaptcha.Verify(ctx.Req.Context(), form.HcaptchaResponse) + valid, err = hcaptcha.Verify(ctx, form.HcaptchaResponse) default: ctx.ServerError("Unknown Captcha Type", fmt.Errorf("Unknown Captcha Type: %s", setting.Service.CaptchaType)) return @@ -1191,7 +1191,7 @@ func SignUpPost(ctx *context.Context) { ctx.RenderWithErr(password.BuildComplexityError(ctx), tplSignUp, &form) return } - pwned, err := password.IsPwned(ctx.Req.Context(), form.Password) + pwned, err := password.IsPwned(ctx, form.Password) if pwned { errMsg := ctx.Tr("auth.password_pwned") if err != nil { @@ -1620,7 +1620,7 @@ func ResetPasswdPost(ctx *context.Context) { ctx.Data["Err_Password"] = true ctx.RenderWithErr(password.BuildComplexityError(ctx), tplResetPassword, nil) return - } else if pwned, err := password.IsPwned(ctx.Req.Context(), passwd); pwned || err != nil { + } else if pwned, err := password.IsPwned(ctx, passwd); pwned || err != nil { errMsg := ctx.Tr("auth.password_pwned") if err != nil { log.Error(err.Error()) diff --git a/routers/user/auth_openid.go b/routers/user/auth_openid.go index b1dfc6ada05db..1a73a08c4862d 100644 --- a/routers/user/auth_openid.go +++ b/routers/user/auth_openid.go @@ -385,13 +385,13 @@ func RegisterOpenIDPost(ctx *context.Context) { ctx.ServerError("", err) return } - valid, err = recaptcha.Verify(ctx.Req.Context(), form.GRecaptchaResponse) + valid, err = recaptcha.Verify(ctx, form.GRecaptchaResponse) case setting.HCaptcha: if err := ctx.Req.ParseForm(); err != nil { ctx.ServerError("", err) return } - valid, err = hcaptcha.Verify(ctx.Req.Context(), form.HcaptchaResponse) + valid, err = hcaptcha.Verify(ctx, form.HcaptchaResponse) default: ctx.ServerError("Unknown Captcha Type", fmt.Errorf("Unknown Captcha Type: %s", setting.Service.CaptchaType)) return diff --git a/routers/user/setting/account.go b/routers/user/setting/account.go index e12d63ee029ee..48ab37d9369e6 100644 --- a/routers/user/setting/account.go +++ b/routers/user/setting/account.go @@ -58,7 +58,7 @@ func AccountPost(ctx *context.Context) { ctx.Flash.Error(ctx.Tr("form.password_not_match")) } else if !password.IsComplexEnough(form.Password) { ctx.Flash.Error(password.BuildComplexityError(ctx)) - } else if pwned, err := password.IsPwned(ctx.Req.Context(), form.Password); pwned || err != nil { + } else if pwned, err := password.IsPwned(ctx, form.Password); pwned || err != nil { errMsg := ctx.Tr("auth.password_pwned") if err != nil { log.Error(err.Error()) diff --git a/services/archiver/archiver.go b/services/archiver/archiver.go index 359fc8b627d91..dfa6334d9536c 100644 --- a/services/archiver/archiver.go +++ b/services/archiver/archiver.go @@ -76,7 +76,7 @@ func (aReq *ArchiveRequest) IsComplete() bool { func (aReq *ArchiveRequest) WaitForCompletion(ctx *context.Context) bool { select { case <-aReq.cchan: - case <-ctx.Req.Context().Done(): + case <-ctx.Done(): } return aReq.IsComplete() @@ -92,7 +92,7 @@ func (aReq *ArchiveRequest) TimedWaitForCompletion(ctx *context.Context, dur tim case <-time.After(dur): timeout = true case <-aReq.cchan: - case <-ctx.Req.Context().Done(): + case <-ctx.Done(): } return aReq.IsComplete(), timeout From 84614acdb3a70d449a556f55f136d3dfa12cb557 Mon Sep 17 00:00:00 2001 From: Andrew Thornton Date: Sun, 30 May 2021 16:11:02 +0100 Subject: [PATCH 3/6] Set the base context for requests to the HammerContext Signed-off-by: Andrew Thornton --- modules/graceful/server_http.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modules/graceful/server_http.go b/modules/graceful/server_http.go index b101a10d9197d..4471e379ef445 100644 --- a/modules/graceful/server_http.go +++ b/modules/graceful/server_http.go @@ -5,7 +5,9 @@ package graceful import ( + "context" "crypto/tls" + "net" "net/http" ) @@ -16,6 +18,7 @@ func newHTTPServer(network, address, name string, handler http.Handler) (*Server WriteTimeout: DefaultWriteTimeOut, MaxHeaderBytes: DefaultMaxHeaderBytes, Handler: handler, + BaseContext: func(net.Listener) context.Context { return GetManager().HammerContext() }, } server.OnShutdown = func() { httpServer.SetKeepAlivesEnabled(false) From a4839a0f7b3090bcaee0158dc8e87867f8b4056a Mon Sep 17 00:00:00 2001 From: Andrew Thornton Date: Sun, 30 May 2021 17:59:54 +0100 Subject: [PATCH 4/6] pass context into get-last-commit Signed-off-by: Andrew Thornton --- modules/git/commit_info_gogit.go | 9 +++++---- modules/git/commit_info_nogogit.go | 13 +++++++------ modules/git/commit_info_test.go | 5 +++-- modules/git/last_commit_cache_gogit.go | 11 ++++++----- modules/git/last_commit_cache_nogogit.go | 11 ++++++----- modules/git/notes_gogit.go | 5 +++-- modules/git/notes_nogogit.go | 5 +++-- modules/git/notes_test.go | 7 ++++--- modules/repository/cache.go | 5 +++-- routers/repo/commit.go | 2 +- routers/repo/view.go | 2 +- services/repository/push.go | 2 +- 12 files changed, 43 insertions(+), 34 deletions(-) diff --git a/modules/git/commit_info_gogit.go b/modules/git/commit_info_gogit.go index 6d95e22d0c7c8..2ca711da6fd89 100644 --- a/modules/git/commit_info_gogit.go +++ b/modules/git/commit_info_gogit.go @@ -7,6 +7,7 @@ package git import ( + "context" "path" "github.com/emirpasic/gods/trees/binaryheap" @@ -16,7 +17,7 @@ import ( ) // GetCommitsInfo gets information of all commits that are corresponding to these entries -func (tes Entries) GetCommitsInfo(commit *Commit, treePath string, cache *LastCommitCache) ([]CommitInfo, *Commit, error) { +func (tes Entries) GetCommitsInfo(ctx context.Context, commit *Commit, treePath string, cache *LastCommitCache) ([]CommitInfo, *Commit, error) { entryPaths := make([]string, len(tes)+1) // Get the commit for the treePath itself entryPaths[0] = "" @@ -42,7 +43,7 @@ func (tes Entries) GetCommitsInfo(commit *Commit, treePath string, cache *LastCo return nil, nil, err } if len(unHitPaths) > 0 { - revs2, err := GetLastCommitForPaths(c, treePath, unHitPaths) + revs2, err := GetLastCommitForPaths(ctx, c, treePath, unHitPaths) if err != nil { return nil, nil, err } @@ -55,7 +56,7 @@ func (tes Entries) GetCommitsInfo(commit *Commit, treePath string, cache *LastCo } } } else { - revs, err = GetLastCommitForPaths(c, treePath, entryPaths) + revs, err = GetLastCommitForPaths(ctx, c, treePath, entryPaths) } if err != nil { return nil, nil, err @@ -173,7 +174,7 @@ func getLastCommitForPathsByCache(commitID, treePath string, paths []string, cac } // GetLastCommitForPaths returns last commit information -func GetLastCommitForPaths(c cgobject.CommitNode, treePath string, paths []string) (map[string]*object.Commit, error) { +func GetLastCommitForPaths(ctx context.Context, c cgobject.CommitNode, treePath string, paths []string) (map[string]*object.Commit, error) { // We do a tree traversal with nodes sorted by commit time heap := binaryheap.NewWith(func(a, b interface{}) int { if a.(*commitAndPaths).commit.CommitTime().Before(b.(*commitAndPaths).commit.CommitTime()) { diff --git a/modules/git/commit_info_nogogit.go b/modules/git/commit_info_nogogit.go index 485271f145152..34b28c344ecb4 100644 --- a/modules/git/commit_info_nogogit.go +++ b/modules/git/commit_info_nogogit.go @@ -9,6 +9,7 @@ package git import ( "bufio" "bytes" + "context" "fmt" "io" "math" @@ -18,7 +19,7 @@ import ( ) // GetCommitsInfo gets information of all commits that are corresponding to these entries -func (tes Entries) GetCommitsInfo(commit *Commit, treePath string, cache *LastCommitCache) ([]CommitInfo, *Commit, error) { +func (tes Entries) GetCommitsInfo(ctx context.Context, commit *Commit, treePath string, cache *LastCommitCache) ([]CommitInfo, *Commit, error) { entryPaths := make([]string, len(tes)+1) // Get the commit for the treePath itself entryPaths[0] = "" @@ -31,13 +32,13 @@ func (tes Entries) GetCommitsInfo(commit *Commit, treePath string, cache *LastCo var revs map[string]*Commit if cache != nil { var unHitPaths []string - revs, unHitPaths, err = getLastCommitForPathsByCache(commit.ID.String(), treePath, entryPaths, cache) + revs, unHitPaths, err = getLastCommitForPathsByCache(ctx, commit.ID.String(), treePath, entryPaths, cache) if err != nil { return nil, nil, err } if len(unHitPaths) > 0 { sort.Strings(unHitPaths) - commits, err := GetLastCommitForPaths(commit, treePath, unHitPaths) + commits, err := GetLastCommitForPaths(ctx, commit, treePath, unHitPaths) if err != nil { return nil, nil, err } @@ -53,7 +54,7 @@ func (tes Entries) GetCommitsInfo(commit *Commit, treePath string, cache *LastCo sort.Strings(entryPaths) revs = map[string]*Commit{} var foundCommits []*Commit - foundCommits, err = GetLastCommitForPaths(commit, treePath, entryPaths) + foundCommits, err = GetLastCommitForPaths(ctx, commit, treePath, entryPaths) for i, found := range foundCommits { revs[entryPaths[i]] = found } @@ -101,7 +102,7 @@ func (tes Entries) GetCommitsInfo(commit *Commit, treePath string, cache *LastCo return commitsInfo, treeCommit, nil } -func getLastCommitForPathsByCache(commitID, treePath string, paths []string, cache *LastCommitCache) (map[string]*Commit, []string, error) { +func getLastCommitForPathsByCache(ctx context.Context, commitID, treePath string, paths []string, cache *LastCommitCache) (map[string]*Commit, []string, error) { wr, rd, cancel := cache.repo.CatFileBatch() defer cancel() @@ -124,7 +125,7 @@ func getLastCommitForPathsByCache(commitID, treePath string, paths []string, cac } // GetLastCommitForPaths returns last commit information -func GetLastCommitForPaths(commit *Commit, treePath string, paths []string) ([]*Commit, error) { +func GetLastCommitForPaths(ctx context.Context, commit *Commit, treePath string, paths []string) ([]*Commit, error) { // We read backwards from the commit to obtain all of the commits // We'll do this by using rev-list to provide us with parent commits in order diff --git a/modules/git/commit_info_test.go b/modules/git/commit_info_test.go index 3966419bc146f..0608801f9df45 100644 --- a/modules/git/commit_info_test.go +++ b/modules/git/commit_info_test.go @@ -5,6 +5,7 @@ package git import ( + "context" "os" "path/filepath" "testing" @@ -69,7 +70,7 @@ func testGetCommitsInfo(t *testing.T, repo1 *Repository) { assert.NoError(t, err) entries, err := tree.ListEntries() assert.NoError(t, err) - commitsInfo, treeCommit, err := entries.GetCommitsInfo(commit, testCase.Path, nil) + commitsInfo, treeCommit, err := entries.GetCommitsInfo(context.Background(), commit, testCase.Path, nil) assert.NoError(t, err) if err != nil { t.FailNow() @@ -136,7 +137,7 @@ func BenchmarkEntries_GetCommitsInfo(b *testing.B) { b.ResetTimer() b.Run(benchmark.name, func(b *testing.B) { for i := 0; i < b.N; i++ { - _, _, err := entries.GetCommitsInfo(commit, "", nil) + _, _, err := entries.GetCommitsInfo(context.Background(), commit, "", nil) if err != nil { b.Fatal(err) } diff --git a/modules/git/last_commit_cache_gogit.go b/modules/git/last_commit_cache_gogit.go index 65d6299bef387..16fb1c988cca8 100644 --- a/modules/git/last_commit_cache_gogit.go +++ b/modules/git/last_commit_cache_gogit.go @@ -7,6 +7,7 @@ package git import ( + "context" "path" "github.com/go-git/go-git/v5/plumbing/object" @@ -60,7 +61,7 @@ func (c *LastCommitCache) Get(ref, entryPath string) (interface{}, error) { } // CacheCommit will cache the commit from the gitRepository -func (c *LastCommitCache) CacheCommit(commit *Commit) error { +func (c *LastCommitCache) CacheCommit(ctx context.Context, commit *Commit) error { commitNodeIndex, _ := commit.repo.CommitNodeIndex() @@ -69,10 +70,10 @@ func (c *LastCommitCache) CacheCommit(commit *Commit) error { return err } - return c.recursiveCache(index, &commit.Tree, "", 1) + return c.recursiveCache(ctx, index, &commit.Tree, "", 1) } -func (c *LastCommitCache) recursiveCache(index cgobject.CommitNode, tree *Tree, treePath string, level int) error { +func (c *LastCommitCache) recursiveCache(ctx context.Context, index cgobject.CommitNode, tree *Tree, treePath string, level int) error { if level == 0 { return nil } @@ -89,7 +90,7 @@ func (c *LastCommitCache) recursiveCache(index cgobject.CommitNode, tree *Tree, entryMap[entry.Name()] = entry } - commits, err := GetLastCommitForPaths(index, treePath, entryPaths) + commits, err := GetLastCommitForPaths(ctx, index, treePath, entryPaths) if err != nil { return err } @@ -103,7 +104,7 @@ func (c *LastCommitCache) recursiveCache(index cgobject.CommitNode, tree *Tree, if err != nil { return err } - if err := c.recursiveCache(index, subTree, entry, level-1); err != nil { + if err := c.recursiveCache(ctx, index, subTree, entry, level-1); err != nil { return err } } diff --git a/modules/git/last_commit_cache_nogogit.go b/modules/git/last_commit_cache_nogogit.go index 9808216a8f870..3cbb0cca32e05 100644 --- a/modules/git/last_commit_cache_nogogit.go +++ b/modules/git/last_commit_cache_nogogit.go @@ -8,6 +8,7 @@ package git import ( "bufio" + "context" "path" ) @@ -61,11 +62,11 @@ func (c *LastCommitCache) Get(ref, entryPath string, wr WriteCloserError, rd *bu } // CacheCommit will cache the commit from the gitRepository -func (c *LastCommitCache) CacheCommit(commit *Commit) error { - return c.recursiveCache(commit, &commit.Tree, "", 1) +func (c *LastCommitCache) CacheCommit(ctx context.Context, commit *Commit) error { + return c.recursiveCache(ctx, commit, &commit.Tree, "", 1) } -func (c *LastCommitCache) recursiveCache(commit *Commit, tree *Tree, treePath string, level int) error { +func (c *LastCommitCache) recursiveCache(ctx context.Context, commit *Commit, tree *Tree, treePath string, level int) error { if level == 0 { return nil } @@ -82,7 +83,7 @@ func (c *LastCommitCache) recursiveCache(commit *Commit, tree *Tree, treePath st entryMap[entry.Name()] = entry } - commits, err := GetLastCommitForPaths(commit, treePath, entryPaths) + commits, err := GetLastCommitForPaths(ctx, commit, treePath, entryPaths) if err != nil { return err } @@ -97,7 +98,7 @@ func (c *LastCommitCache) recursiveCache(commit *Commit, tree *Tree, treePath st if err != nil { return err } - if err := c.recursiveCache(commit, subTree, entry, level-1); err != nil { + if err := c.recursiveCache(ctx, commit, subTree, entry, level-1); err != nil { return err } } diff --git a/modules/git/notes_gogit.go b/modules/git/notes_gogit.go index 173d29cee6b44..534a5d517153a 100644 --- a/modules/git/notes_gogit.go +++ b/modules/git/notes_gogit.go @@ -7,13 +7,14 @@ package git import ( + "context" "io/ioutil" "github.com/go-git/go-git/v5/plumbing/object" ) // GetNote retrieves the git-notes data for a given commit. -func GetNote(repo *Repository, commitID string, note *Note) error { +func GetNote(ctx context.Context, repo *Repository, commitID string, note *Note) error { notes, err := repo.GetCommit(NotesRef) if err != nil { return err @@ -62,7 +63,7 @@ func GetNote(repo *Repository, commitID string, note *Note) error { return err } - lastCommits, err := GetLastCommitForPaths(commitNode, "", []string{path}) + lastCommits, err := GetLastCommitForPaths(ctx, commitNode, "", []string{path}) if err != nil { return err } diff --git a/modules/git/notes_nogogit.go b/modules/git/notes_nogogit.go index d5d194b23f1b0..2b927249954a7 100644 --- a/modules/git/notes_nogogit.go +++ b/modules/git/notes_nogogit.go @@ -7,12 +7,13 @@ package git import ( + "context" "io/ioutil" "strings" ) // GetNote retrieves the git-notes data for a given commit. -func GetNote(repo *Repository, commitID string, note *Note) error { +func GetNote(ctx context.Context, repo *Repository, commitID string, note *Note) error { notes, err := repo.GetCommit(NotesRef) if err != nil { return err @@ -63,7 +64,7 @@ func GetNote(repo *Repository, commitID string, note *Note) error { path = path[idx+1:] } - lastCommits, err := GetLastCommitForPaths(notes, treePath, []string{path}) + lastCommits, err := GetLastCommitForPaths(ctx, notes, treePath, []string{path}) if err != nil { return err } diff --git a/modules/git/notes_test.go b/modules/git/notes_test.go index b7939e691355a..f66a191e6ae27 100644 --- a/modules/git/notes_test.go +++ b/modules/git/notes_test.go @@ -5,6 +5,7 @@ package git import ( + "context" "path/filepath" "testing" @@ -18,7 +19,7 @@ func TestGetNotes(t *testing.T) { defer bareRepo1.Close() note := Note{} - err = GetNote(bareRepo1, "95bb4d39648ee7e325106df01a621c530863a653", ¬e) + err = GetNote(context.Background(), bareRepo1, "95bb4d39648ee7e325106df01a621c530863a653", ¬e) assert.NoError(t, err) assert.Equal(t, []byte("Note contents\n"), note.Message) assert.Equal(t, "Vladimir Panteleev", note.Commit.Author.Name) @@ -31,10 +32,10 @@ func TestGetNestedNotes(t *testing.T) { defer repo.Close() note := Note{} - err = GetNote(repo, "3e668dbfac39cbc80a9ff9c61eb565d944453ba4", ¬e) + err = GetNote(context.Background(), repo, "3e668dbfac39cbc80a9ff9c61eb565d944453ba4", ¬e) assert.NoError(t, err) assert.Equal(t, []byte("Note 2"), note.Message) - err = GetNote(repo, "ba0a96fa63532d6c5087ecef070b0250ed72fa47", ¬e) + err = GetNote(context.Background(), repo, "ba0a96fa63532d6c5087ecef070b0250ed72fa47", ¬e) assert.NoError(t, err) assert.Equal(t, []byte("Note 1"), note.Message) } diff --git a/modules/repository/cache.go b/modules/repository/cache.go index 5d6dea8fcb60b..e574f1adb7f7c 100644 --- a/modules/repository/cache.go +++ b/modules/repository/cache.go @@ -5,6 +5,7 @@ package repository import ( + "context" "strings" "code.gitea.io/gitea/models" @@ -23,7 +24,7 @@ func getRefName(fullRefName string) string { } // CacheRef cachhe last commit information of the branch or the tag -func CacheRef(repo *models.Repository, gitRepo *git.Repository, fullRefName string) error { +func CacheRef(ctx context.Context, repo *models.Repository, gitRepo *git.Repository, fullRefName string) error { if !setting.CacheService.LastCommit.Enabled { return nil } @@ -43,5 +44,5 @@ func CacheRef(repo *models.Repository, gitRepo *git.Repository, fullRefName stri commitCache := git.NewLastCommitCache(repo.FullName(), gitRepo, setting.LastCommitCacheTTLSeconds, cache.GetCache()) - return commitCache.CacheCommit(commit) + return commitCache.CacheCommit(ctx, commit) } diff --git a/routers/repo/commit.go b/routers/repo/commit.go index c4719526376f7..e9d7da044ec2d 100644 --- a/routers/repo/commit.go +++ b/routers/repo/commit.go @@ -355,7 +355,7 @@ func Diff(ctx *context.Context) { } note := &git.Note{} - err = git.GetNote(ctx.Repo.GitRepo, commitID, note) + err = git.GetNote(ctx.Req.Context(), ctx.Repo.GitRepo, commitID, note) if err == nil { ctx.Data["Note"] = string(charset.ToUTF8WithFallback(note.Message)) ctx.Data["NoteCommit"] = note.Commit diff --git a/routers/repo/view.go b/routers/repo/view.go index 285cacc2dfa96..7d583e32dde20 100644 --- a/routers/repo/view.go +++ b/routers/repo/view.go @@ -145,7 +145,7 @@ func renderDirectory(ctx *context.Context, treeLink string) { } var latestCommit *git.Commit - ctx.Data["Files"], latestCommit, err = entries.GetCommitsInfo(ctx.Repo.Commit, ctx.Repo.TreePath, c) + ctx.Data["Files"], latestCommit, err = entries.GetCommitsInfo(ctx.Req.Context(), ctx.Repo.Commit, ctx.Repo.TreePath, c) if err != nil { ctx.ServerError("GetCommitsInfo", err) return diff --git a/services/repository/push.go b/services/repository/push.go index bed5c575fe81d..f031073b2e0e0 100644 --- a/services/repository/push.go +++ b/services/repository/push.go @@ -208,7 +208,7 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error { } // Cache for big repository - if err := repo_module.CacheRef(repo, gitRepo, opts.RefFullName); err != nil { + if err := repo_module.CacheRef(graceful.GetManager().HammerContext(), repo, gitRepo, opts.RefFullName); err != nil { log.Error("repo_module.CacheRef %s/%s failed: %v", repo.ID, branch, err) } } else { From 47c6c412b18098397595849dfbe56e1afcb1950c Mon Sep 17 00:00:00 2001 From: Andrew Thornton Date: Sun, 30 May 2021 20:35:13 +0100 Subject: [PATCH 5/6] Make commit_info cancellable Signed-off-by: Andrew Thornton --- modules/git/commit_info_gogit.go | 5 +++++ modules/git/commit_info_nogogit.go | 10 +++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/modules/git/commit_info_gogit.go b/modules/git/commit_info_gogit.go index 2ca711da6fd89..a8006dcef2e64 100644 --- a/modules/git/commit_info_gogit.go +++ b/modules/git/commit_info_gogit.go @@ -193,6 +193,11 @@ func GetLastCommitForPaths(ctx context.Context, c cgobject.CommitNode, treePath heap.Push(&commitAndPaths{c, paths, initialHashes}) for { + select { + case <-ctx.Done(): + return nil, ctx.Err() + default: + } cIn, ok := heap.Pop() if !ok { break diff --git a/modules/git/commit_info_nogogit.go b/modules/git/commit_info_nogogit.go index 34b28c344ecb4..f34bef9f018c8 100644 --- a/modules/git/commit_info_nogogit.go +++ b/modules/git/commit_info_nogogit.go @@ -137,7 +137,7 @@ func GetLastCommitForPaths(ctx context.Context, commit *Commit, treePath string, go func() { stderr := strings.Builder{} - err := NewCommand("rev-list", "--format=%T", commit.ID.String()).RunInDirPipeline(commit.repo.Path, revListWriter, &stderr) + err := NewCommand("rev-list", "--format=%T", commit.ID.String()).SetParentContext(ctx).RunInDirPipeline(commit.repo.Path, revListWriter, &stderr) if err != nil { _ = revListWriter.CloseWithError(ConcatenateError(err, (&stderr).String())) } else { @@ -203,6 +203,11 @@ revListLoop: treeReadingLoop: for { + select { + case <-ctx.Done(): + return nil, ctx.Err() + default: + } _, _, size, err := ReadBatchLine(batchReader) if err != nil { return nil, err @@ -322,6 +327,9 @@ revListLoop: } } } + if scan.Err() != nil { + return nil, scan.Err() + } commitsMap := make(map[string]*Commit, len(commits)) commitsMap[commit.ID.String()] = commit From 6b702858a1538ba2cd2486846e0ab28abf2a5ebf Mon Sep 17 00:00:00 2001 From: Andrew Thornton Date: Sun, 30 May 2021 22:43:46 +0100 Subject: [PATCH 6/6] use context as context Signed-off-by: Andrew Thornton --- routers/repo/commit.go | 2 +- routers/repo/view.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/routers/repo/commit.go b/routers/repo/commit.go index e9d7da044ec2d..3e6148bcbbc76 100644 --- a/routers/repo/commit.go +++ b/routers/repo/commit.go @@ -355,7 +355,7 @@ func Diff(ctx *context.Context) { } note := &git.Note{} - err = git.GetNote(ctx.Req.Context(), ctx.Repo.GitRepo, commitID, note) + err = git.GetNote(ctx, ctx.Repo.GitRepo, commitID, note) if err == nil { ctx.Data["Note"] = string(charset.ToUTF8WithFallback(note.Message)) ctx.Data["NoteCommit"] = note.Commit diff --git a/routers/repo/view.go b/routers/repo/view.go index 7d583e32dde20..fb7b2c0501241 100644 --- a/routers/repo/view.go +++ b/routers/repo/view.go @@ -145,7 +145,7 @@ func renderDirectory(ctx *context.Context, treeLink string) { } var latestCommit *git.Commit - ctx.Data["Files"], latestCommit, err = entries.GetCommitsInfo(ctx.Req.Context(), ctx.Repo.Commit, ctx.Repo.TreePath, c) + ctx.Data["Files"], latestCommit, err = entries.GetCommitsInfo(ctx, ctx.Repo.Commit, ctx.Repo.TreePath, c) if err != nil { ctx.ServerError("GetCommitsInfo", err) return