Skip to content
This repository was archived by the owner on Sep 30, 2024. It is now read-only.

Commit 73430cb

Browse files
authored
gitserver: Move postfetch into separate file (#61858)
Little code cleanup chore. Test plan: Just moved code around, trusting compiler.
1 parent 1836e70 commit 73430cb

File tree

4 files changed

+164
-144
lines changed

4 files changed

+164
-144
lines changed

cmd/gitserver/internal/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ go_library(
1111
"list_gitolite.go",
1212
"lock.go",
1313
"patch.go",
14+
"postfetch.go",
1415
"repo_info.go",
1516
"repositoryservice.go",
1617
"search.go",

cmd/gitserver/internal/cleanup.go

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1147,26 +1147,6 @@ func tooManyPackfiles(dir common.GitDir, limit int) (bool, error) {
11471147
return count > limit, nil
11481148
}
11491149

1150-
// gitSetAutoGC will set the value of gc.auto. If GC is managed by Sourcegraph
1151-
// the value will be 0 (disabled), otherwise if managed by git we will unset
1152-
// it to rely on default (on) or global config.
1153-
//
1154-
// The purpose is to avoid repository corruption which can happen if several
1155-
// git-gc operations are running at the same time.
1156-
func gitSetAutoGC(ctx context.Context, c git.GitConfigBackend) error {
1157-
switch gitGCMode {
1158-
case gitGCModeGitAutoGC, gitGCModeJanitorAutoGC:
1159-
return c.Unset(ctx, "gc.auto")
1160-
1161-
case gitGCModeMaintenance:
1162-
return c.Set(ctx, "gc.auto", "0")
1163-
1164-
default:
1165-
// should not happen
1166-
panic(fmt.Sprintf("non exhaustive switch for gitGCMode: %d", gitGCMode))
1167-
}
1168-
}
1169-
11701150
// jitterDuration returns a duration between [0, d) based on key. This is like
11711151
// a random duration, but instead of a random source it is computed via a hash
11721152
// on key.

cmd/gitserver/internal/postfetch.go

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
package internal
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"os"
7+
"time"
8+
9+
"github.com/sourcegraph/log"
10+
11+
"github.com/sourcegraph/sourcegraph/cmd/gitserver/internal/common"
12+
"github.com/sourcegraph/sourcegraph/cmd/gitserver/internal/git"
13+
"github.com/sourcegraph/sourcegraph/cmd/gitserver/internal/gitserverfs"
14+
"github.com/sourcegraph/sourcegraph/cmd/gitserver/internal/vcssyncer"
15+
"github.com/sourcegraph/sourcegraph/internal/api"
16+
"github.com/sourcegraph/sourcegraph/internal/database"
17+
"github.com/sourcegraph/sourcegraph/internal/fileutil"
18+
"github.com/sourcegraph/sourcegraph/lib/errors"
19+
)
20+
21+
func postRepoFetchActions(
22+
ctx context.Context,
23+
logger log.Logger,
24+
fs gitserverfs.FS,
25+
db database.DB,
26+
backend git.GitBackend,
27+
shardID string,
28+
repo api.RepoName,
29+
dir common.GitDir,
30+
syncer vcssyncer.VCSSyncer,
31+
) (errs error) {
32+
// Note: We use a multi error in this function to try to make as many of the
33+
// post repo fetch actions succeed.
34+
35+
if err := git.RemoveBadRefs(ctx, dir); err != nil {
36+
errs = errors.Append(errs, errors.Wrapf(err, "failed to remove bad refs for repo %q", repo))
37+
}
38+
39+
if err := git.SetRepositoryType(ctx, backend.Config(), syncer.Type()); err != nil {
40+
errs = errors.Append(errs, errors.Wrapf(err, "failed to set repository type for repo %q", repo))
41+
}
42+
43+
if err := git.SetGitAttributes(dir); err != nil {
44+
errs = errors.Append(errs, errors.Wrap(err, "setting git attributes"))
45+
}
46+
47+
if err := gitSetAutoGC(ctx, backend.Config()); err != nil {
48+
errs = errors.Append(errs, errors.Wrap(err, "setting git gc mode"))
49+
}
50+
51+
// Update the last-changed stamp on disk.
52+
if err := setLastChanged(logger, dir); err != nil {
53+
errs = errors.Append(errs, errors.Wrap(err, "failed to update last changed time"))
54+
}
55+
56+
// Successfully updated, best-effort updating of db fetch state based on
57+
// disk state.
58+
if err := setLastFetched(ctx, db, shardID, dir, repo); err != nil {
59+
errs = errors.Append(errs, errors.Wrap(err, "failed setting last fetch in DB"))
60+
}
61+
62+
// Successfully updated, best-effort calculation of the repo size.
63+
repoSizeBytes, err := fs.DirSize(dir.Path())
64+
if err != nil {
65+
errs = errors.Append(errs, errors.Wrap(err, "failed to calculate repo size"))
66+
} else if err := db.GitserverRepos().SetRepoSize(ctx, repo, repoSizeBytes, shardID); err != nil {
67+
errs = errors.Append(errs, errors.Wrap(err, "failed to set repo size"))
68+
}
69+
70+
return errs
71+
}
72+
73+
// gitSetAutoGC will set the value of gc.auto. If GC is managed by Sourcegraph
74+
// the value will be 0 (disabled), otherwise if managed by git we will unset
75+
// it to rely on default (on) or global config.
76+
//
77+
// The purpose is to avoid repository corruption which can happen if several
78+
// git-gc operations are running at the same time.
79+
func gitSetAutoGC(ctx context.Context, c git.GitConfigBackend) error {
80+
switch gitGCMode {
81+
case gitGCModeGitAutoGC, gitGCModeJanitorAutoGC:
82+
return c.Unset(ctx, "gc.auto")
83+
84+
case gitGCModeMaintenance:
85+
return c.Set(ctx, "gc.auto", "0")
86+
87+
default:
88+
// should not happen
89+
panic(fmt.Sprintf("non exhaustive switch for gitGCMode: %d", gitGCMode))
90+
}
91+
}
92+
93+
// setLastChanged discerns an approximate last-changed timestamp for a
94+
// repository. This can be approximate; it's used to determine how often we
95+
// should run `git fetch`, but is not relied on strongly. The basic plan
96+
// is as follows: If a repository has never had a timestamp before, we
97+
// guess that the right stamp is *probably* the timestamp of the most
98+
// chronologically-recent commit. If there are no commits, we just use the
99+
// current time because that's probably usually a temporary state.
100+
//
101+
// If a timestamp already exists, we want to update it if and only if
102+
// the set of references (as determined by `git show-ref`) has changed.
103+
//
104+
// To accomplish this, we assert that the file `sg_refhash` in the git
105+
// directory should, if it exists, contain a hash of the output of
106+
// `git show-ref`, and have a timestamp of "the last time this changed",
107+
// except that if we're creating that file for the first time, we set
108+
// it to the timestamp of the top commit. We then compute the hash of
109+
// the show-ref output, and store it in the file if and only if it's
110+
// different from the current contents.
111+
//
112+
// If show-ref fails, we use rev-list to determine whether that's just
113+
// an empty repository (not an error) or some kind of actual error
114+
// that is possibly causing our data to be incorrect, which should
115+
// be reported.
116+
func setLastChanged(logger log.Logger, dir common.GitDir) error {
117+
hashFile := dir.Path("sg_refhash")
118+
119+
hash, err := git.ComputeRefHash(dir)
120+
if err != nil {
121+
return errors.Wrapf(err, "computeRefHash failed for %s", dir)
122+
}
123+
124+
var stamp time.Time
125+
if _, err := os.Stat(hashFile); os.IsNotExist(err) {
126+
// This is the first time we are calculating the hash. Give a more
127+
// approriate timestamp for sg_refhash than the current time.
128+
stamp = git.LatestCommitTimestamp(logger, dir)
129+
}
130+
131+
_, err = fileutil.UpdateFileIfDifferent(hashFile, hash)
132+
if err != nil {
133+
return errors.Wrapf(err, "failed to update %s", hashFile)
134+
}
135+
136+
// If stamp is non-zero we have a more approriate mtime.
137+
if !stamp.IsZero() {
138+
err = os.Chtimes(hashFile, stamp, stamp)
139+
if err != nil {
140+
return errors.Wrapf(err, "failed to set mtime to the lastest commit timestamp for %s", dir)
141+
}
142+
}
143+
144+
return nil
145+
}
146+
147+
func setLastFetched(ctx context.Context, db database.DB, shardID string, dir common.GitDir, name api.RepoName) error {
148+
lastFetched, err := repoLastFetched(dir)
149+
if err != nil {
150+
return errors.Wrapf(err, "failed to get last fetched for %s", name)
151+
}
152+
153+
lastChanged, err := repoLastChanged(dir)
154+
if err != nil {
155+
return errors.Wrapf(err, "failed to get last changed for %s", name)
156+
}
157+
158+
return db.GitserverRepos().SetLastFetched(ctx, name, database.GitserverFetchData{
159+
LastFetched: lastFetched,
160+
LastChanged: lastChanged,
161+
ShardID: shardID,
162+
})
163+
}

cmd/gitserver/internal/server.go

Lines changed: 0 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -348,24 +348,6 @@ func (s *Server) repoUpdateOrClone(ctx context.Context, repoName api.RepoName) e
348348
return nil
349349
}
350350

351-
func setLastFetched(ctx context.Context, db database.DB, shardID string, dir common.GitDir, name api.RepoName) error {
352-
lastFetched, err := repoLastFetched(dir)
353-
if err != nil {
354-
return errors.Wrapf(err, "failed to get last fetched for %s", name)
355-
}
356-
357-
lastChanged, err := repoLastChanged(dir)
358-
if err != nil {
359-
return errors.Wrapf(err, "failed to get last changed for %s", name)
360-
}
361-
362-
return db.GitserverRepos().SetLastFetched(ctx, name, database.GitserverFetchData{
363-
LastFetched: lastFetched,
364-
LastChanged: lastChanged,
365-
ShardID: shardID,
366-
})
367-
}
368-
369351
// setLastErrorNonFatal will set the last_error column for the repo in the gitserver table.
370352
func (s *Server) setLastErrorNonFatal(ctx context.Context, name api.RepoName, err error) {
371353
var errString string
@@ -670,58 +652,6 @@ func (w *linebasedBufferedWriter) Bytes() []byte {
670652
return w.buf
671653
}
672654

673-
func postRepoFetchActions(
674-
ctx context.Context,
675-
logger log.Logger,
676-
fs gitserverfs.FS,
677-
db database.DB,
678-
backend git.GitBackend,
679-
shardID string,
680-
repo api.RepoName,
681-
dir common.GitDir,
682-
syncer vcssyncer.VCSSyncer,
683-
) (errs error) {
684-
// Note: We use a multi error in this function to try to make as many of the
685-
// post repo fetch actions succeed.
686-
687-
if err := git.RemoveBadRefs(ctx, dir); err != nil {
688-
errs = errors.Append(errs, errors.Wrapf(err, "failed to remove bad refs for repo %q", repo))
689-
}
690-
691-
if err := git.SetRepositoryType(ctx, backend.Config(), syncer.Type()); err != nil {
692-
errs = errors.Append(errs, errors.Wrapf(err, "failed to set repository type for repo %q", repo))
693-
}
694-
695-
if err := git.SetGitAttributes(dir); err != nil {
696-
errs = errors.Append(errs, errors.Wrap(err, "setting git attributes"))
697-
}
698-
699-
if err := gitSetAutoGC(ctx, backend.Config()); err != nil {
700-
errs = errors.Append(errs, errors.Wrap(err, "setting git gc mode"))
701-
}
702-
703-
// Update the last-changed stamp on disk.
704-
if err := setLastChanged(logger, dir); err != nil {
705-
errs = errors.Append(errs, errors.Wrap(err, "failed to update last changed time"))
706-
}
707-
708-
// Successfully updated, best-effort updating of db fetch state based on
709-
// disk state.
710-
if err := setLastFetched(ctx, db, shardID, dir, repo); err != nil {
711-
errs = errors.Append(errs, errors.Wrap(err, "failed setting last fetch in DB"))
712-
}
713-
714-
// Successfully updated, best-effort calculation of the repo size.
715-
repoSizeBytes, err := fs.DirSize(dir.Path())
716-
if err != nil {
717-
errs = errors.Append(errs, errors.Wrap(err, "failed to calculate repo size"))
718-
} else if err := db.GitserverRepos().SetRepoSize(ctx, repo, repoSizeBytes, shardID); err != nil {
719-
errs = errors.Append(errs, errors.Wrap(err, "failed to set repo size"))
720-
}
721-
722-
return errs
723-
}
724-
725655
// readCloneProgress scans the reader and saves the most recent line of output
726656
// as the lock status, and optionally writes to a log file if siteConfig.cloneProgressLog
727657
// is enabled.
@@ -963,60 +893,6 @@ func (s *Server) doBackgroundRepoUpdate(repo api.RepoName, revspec string) error
963893
return err
964894
}
965895

966-
// setLastChanged discerns an approximate last-changed timestamp for a
967-
// repository. This can be approximate; it's used to determine how often we
968-
// should run `git fetch`, but is not relied on strongly. The basic plan
969-
// is as follows: If a repository has never had a timestamp before, we
970-
// guess that the right stamp is *probably* the timestamp of the most
971-
// chronologically-recent commit. If there are no commits, we just use the
972-
// current time because that's probably usually a temporary state.
973-
//
974-
// If a timestamp already exists, we want to update it if and only if
975-
// the set of references (as determined by `git show-ref`) has changed.
976-
//
977-
// To accomplish this, we assert that the file `sg_refhash` in the git
978-
// directory should, if it exists, contain a hash of the output of
979-
// `git show-ref`, and have a timestamp of "the last time this changed",
980-
// except that if we're creating that file for the first time, we set
981-
// it to the timestamp of the top commit. We then compute the hash of
982-
// the show-ref output, and store it in the file if and only if it's
983-
// different from the current contents.
984-
//
985-
// If show-ref fails, we use rev-list to determine whether that's just
986-
// an empty repository (not an error) or some kind of actual error
987-
// that is possibly causing our data to be incorrect, which should
988-
// be reported.
989-
func setLastChanged(logger log.Logger, dir common.GitDir) error {
990-
hashFile := dir.Path("sg_refhash")
991-
992-
hash, err := git.ComputeRefHash(dir)
993-
if err != nil {
994-
return errors.Wrapf(err, "computeRefHash failed for %s", dir)
995-
}
996-
997-
var stamp time.Time
998-
if _, err := os.Stat(hashFile); os.IsNotExist(err) {
999-
// This is the first time we are calculating the hash. Give a more
1000-
// approriate timestamp for sg_refhash than the current time.
1001-
stamp = git.LatestCommitTimestamp(logger, dir)
1002-
}
1003-
1004-
_, err = fileutil.UpdateFileIfDifferent(hashFile, hash)
1005-
if err != nil {
1006-
return errors.Wrapf(err, "failed to update %s", hashFile)
1007-
}
1008-
1009-
// If stamp is non-zero we have a more approriate mtime.
1010-
if !stamp.IsZero() {
1011-
err = os.Chtimes(hashFile, stamp, stamp)
1012-
if err != nil {
1013-
return errors.Wrapf(err, "failed to set mtime to the lastest commit timestamp for %s", dir)
1014-
}
1015-
}
1016-
1017-
return nil
1018-
}
1019-
1020896
func (s *Server) SearchWithObservability(ctx context.Context, tr trace.Trace, args *protocol.SearchRequest, onMatch func(*protocol.CommitMatch) error) (limitHit bool, err error) {
1021897
return searchWithObservability(ctx, s.logger, s.fs.RepoDir(args.Repo), tr, args, onMatch)
1022898
}

0 commit comments

Comments
 (0)