vole
Clone
Read only, no credentials:
https://rodent.software/git/vole.git
Write over SSH with a registered key:
git clone ssh://git@0.0.0.0:2222/vole.git
A free and open-source forge that lives in your Git repo.
Stop repeating the index check and the history summaries
73ec800beafe53eea186fbc1cebec3306cc49da0 · Keenan Nemetz · 10d ago · parent 5d440e37
Stop repeating the index check and the history summaries The request memo covered the repository, the open counts and the change list, but two more reads were repeated: - The index refresh (issue rows, filters, `#42` numbers) ran on every surface that shows one, and each run started by resolving the metadata ref. A page calls it from the header, the number lookup and its own view, so it now happens once per request, and the resolved commit is shared with the change-request read instead of being resolved twice. - The overview walked the repository's whole history on every load: `shortlog` for contributors, `rev-list --count` for the code page's commit count, and the tree grouping for languages. Those are properties of a commit, and a commit id is content-addressed, so they cannot go stale: they are remembered by commit id in a bounded per-process cache that evicts oldest-first. On the fixture (30 change requests, 30 issues) the overview drops from 19 git calls to 9 on a repeated load, the code page from 12 to 11, and every page loses one `rev-parse` for the metadata ref.
server/web/issues.go +3−3
| @@ -22,7 +22,7 @@ func (w *Web) Issues(rw http.ResponseWriter, r *http.Request) { | |||
| 22 | 22 | if !ok { | |
| 23 | 23 | return | |
| 24 | 24 | } | |
| 25 | if err := w.Index.EnsureIssues(m); err != nil { | ||
| 25 | if err := w.ensureIndex(memoOf(r), m); err != nil { | ||
| 26 | 26 | w.serverError(rw, r, "issue index unavailable: "+err.Error()) | |
| 27 | 27 | return | |
| 28 | 28 | } | |
| @@ -165,7 +165,7 @@ type issuePageView struct { | |||
| 165 | 165 | func (w *Web) issueSidebar(r *http.Request, m *repo.Meta, iss *metadata.Issue, title, errMsg string) issueSidebarView { | |
| 166 | 166 | acl, _ := m.ACL() | |
| 167 | 167 | canManage := canTriage(acl, w.accountName(r), iss.Author) | |
| 168 | _ = w.Index.EnsureIssues(m) | ||
| 168 | _ = w.ensureIndex(memoOf(r), m) | ||
| 169 | 169 | labels, _ := w.Index.Labels(m.ID) | |
| 170 | 170 | assignable := mergeNames(w.assignableAccounts(m), iss.Assignees) | |
| 171 | 171 | number, _, _ := w.Index.Number(m.ID, iss.ID) | |
| @@ -256,7 +256,7 @@ func (w *Web) NewIssuePage(rw http.ResponseWriter, r *http.Request) { | |||
| 256 | 256 | http.Error(rw, "you do not have permission to file issues here", http.StatusForbidden) | |
| 257 | 257 | return | |
| 258 | 258 | } | |
| 259 | _ = w.Index.EnsureIssues(m) | ||
| 259 | _ = w.ensureIndex(memoOf(r), m) | ||
| 260 | 260 | labels, _ := w.Index.Labels(m.ID) | |
| 261 | 261 | w.render(rw, "issue_new", struct { | |
| 262 | 262 | Page | |