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/request_view.go +5−5
| @@ -381,22 +381,22 @@ func (w *Web) requestSidebar(r *http.Request, m *repo.Meta, req *metadata.Reques | |||
| 381 | 381 | v.BaseOptions = branchOptions(branches, req.Base) | |
| 382 | 382 | v.HeadOptions = branchOptions(headBranches(branches, acl, who), req.HeadRef) | |
| 383 | 383 | } | |
| 384 | nums := w.entityNumbers(m) | ||
| 384 | nums := w.entityNumbers(memoOf(r), m) | ||
| 385 | 385 | v.Number = nums[req.ID] | |
| 386 | v.LinkedIssues = w.requestLinkedIssues(m, req, nums) | ||
| 386 | v.LinkedIssues = w.requestLinkedIssues(memoOf(r), m, req, nums) | ||
| 387 | 387 | return v | |
| 388 | 388 | } | |
| 389 | 389 | ||
| 390 | 390 | // requestLinkedIssues reads the issues a request promises to close. The index | |
| 391 | 391 | // supplies the rows the overview uses, and a row the index cannot name is read | |
| 392 | 392 | // from the issue itself rather than dropped: the request still holds the link. | |
| 393 | func (w *Web) requestLinkedIssues(m *repo.Meta, req *metadata.Request, nums map[string]int) []requestIssue { | ||
| 393 | func (w *Web) requestLinkedIssues(memo *requestMemo, m *repo.Meta, req *metadata.Request, nums map[string]int) []requestIssue { | ||
| 394 | 394 | if len(req.Closes) == 0 { | |
| 395 | 395 | return nil | |
| 396 | 396 | } | |
| 397 | 397 | rows := make(map[string]index.IssueRow, len(req.Closes)) | |
| 398 | 398 | if w.Index != nil { | |
| 399 | if err := w.Index.Ensure(m); err == nil { | ||
| 399 | if err := w.ensureIndex(memo, m); err == nil { | ||
| 400 | 400 | if list, err := w.Index.Issues(m.ID, index.Filter{State: "all"}); err == nil { | |
| 401 | 401 | for _, row := range list { | |
| 402 | 402 | rows[row.ID] = row | |
| @@ -474,7 +474,7 @@ func (w *Web) SearchRequestIssues(rw http.ResponseWriter, r *http.Request) { | |||
| 474 | 474 | w.render(rw, "request_issue_search", view, 0) | |
| 475 | 475 | return | |
| 476 | 476 | } | |
| 477 | if err := w.Index.Ensure(m); err != nil { | ||
| 477 | if err := w.ensureIndex(memoOf(r), m); err != nil { | ||
| 478 | 478 | if w.Logger != nil { | |
| 479 | 479 | w.Logger("web: issue search index for %s: %v", m.Name, err) | |
| 480 | 480 | } | |