From 480521bcdccd496cbf24d8614abc880984843b46 Mon Sep 17 00:00:00 2001 From: Anirudh Oppiliappan Date: Sun, 9 Mar 2025 12:24:25 +0200 Subject: [PATCH] knotserver/git: cache just the commit hash and time This should help alleviate the memory leakyness that was exhibited when we stored the entire object.Commit in memory. --- appview/pages/templates/repo/index.html | 4 +-- appview/pages/templates/repo/tree.html | 4 +-- knotserver/git/git.go | 37 +++++++++++++++++-------- types/tree.go | 12 ++++++-- 4 files changed, 40 insertions(+), 17 deletions(-) diff --git a/appview/pages/templates/repo/index.html b/appview/pages/templates/repo/index.html index a7755a2..7dad806 100644 --- a/appview/pages/templates/repo/index.html +++ b/appview/pages/templates/repo/index.html @@ -79,7 +79,7 @@ {{ timeFmt .LastCommit.When }} @@ -104,7 +104,7 @@ {{ timeFmt .LastCommit.When }} diff --git a/appview/pages/templates/repo/tree.html b/appview/pages/templates/repo/tree.html index 0434a80..b1c48cc 100644 --- a/appview/pages/templates/repo/tree.html +++ b/appview/pages/templates/repo/tree.html @@ -44,7 +44,7 @@ {{ .Name }} - + {{ end }} @@ -59,7 +59,7 @@ {{ .Name }} - + {{ end }} diff --git a/knotserver/git/git.go b/knotserver/git/git.go index f165a0b..30e59d8 100644 --- a/knotserver/git/git.go +++ b/knotserver/git/git.go @@ -9,6 +9,7 @@ import ( "os/exec" "path" "sort" + "strconv" "strings" "sync" "time" @@ -17,6 +18,7 @@ import ( "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/plumbing/object" + "github.com/sotangled/tangled/types" ) var ( @@ -297,16 +299,16 @@ func (g *GitRepo) WriteTar(w io.Writer, prefix string) error { return nil } -func (g *GitRepo) LastCommitForPath(path string) (*object.Commit, error) { +func (g *GitRepo) LastCommitForPath(path string) (*types.LastCommitInfo, error) { cacheKey := fmt.Sprintf("%s:%s", g.h.String(), path) cacheMu.RLock() - if commit, found := commitCache.Get(cacheKey); found { + if commitInfo, found := commitCache.Get(cacheKey); found { cacheMu.RUnlock() - return commit.(*object.Commit), nil + return commitInfo.(*types.LastCommitInfo), nil } cacheMu.RUnlock() - cmd := exec.Command("git", "-C", g.path, "log", "-1", "--format=%H", "--", path) + cmd := exec.Command("git", "-C", g.path, "log", "-1", "--format=%H %ct", "--", path) var out bytes.Buffer cmd.Stdout = &out @@ -316,23 +318,36 @@ func (g *GitRepo) LastCommitForPath(path string) (*object.Commit, error) { return nil, fmt.Errorf("failed to get commit hash: %w", err) } - commitHash := strings.TrimSpace(out.String()) - if commitHash == "" { + output := strings.TrimSpace(out.String()) + if output == "" { return nil, fmt.Errorf("no commits found for path: %s", path) } - hash := plumbing.NewHash(commitHash) + parts := strings.SplitN(output, " ", 2) + if len(parts) < 2 { + return nil, fmt.Errorf("unexpected commit log format") + } - commit, err := g.r.CommitObject(hash) + commitHash := parts[0] + commitTimeUnix, err := strconv.ParseInt(parts[1], 10, 64) if err != nil { - return nil, err + return nil, fmt.Errorf("parsing commit time: %w", err) + } + commitTime := time.Unix(commitTimeUnix, 0) + + hash := plumbing.NewHash(commitHash) + + commitInfo := &types.LastCommitInfo{ + Hash: hash, + Message: "", + When: commitTime, } cacheMu.Lock() - commitCache.Set(cacheKey, commit, 1) + commitCache.Set(cacheKey, commitInfo, 1) cacheMu.Unlock() - return commit, nil + return commitInfo, nil } func newInfoWrapper( diff --git a/types/tree.go b/types/tree.go index 9248a0e..aedcb68 100644 --- a/types/tree.go +++ b/types/tree.go @@ -1,7 +1,9 @@ package types import ( - "github.com/go-git/go-git/v5/plumbing/object" + "time" + + "github.com/go-git/go-git/v5/plumbing" ) // A nicer git tree representation. @@ -12,5 +14,11 @@ type NiceTree struct { IsFile bool `json:"is_file"` IsSubtree bool `json:"is_subtree"` - LastCommit *object.Commit `json:"last_commit,omitempty"` + LastCommit *LastCommitInfo `json:"last_commit,omitempty"` +} + +type LastCommitInfo struct { + Hash plumbing.Hash + Message string + When time.Time } -- 2.54.0