-
Notifications
You must be signed in to change notification settings - Fork 486
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(module/git): allow module.git use cached content when failed to fetch #5712
feat(module/git): allow module.git use cached content when failed to fetch #5712
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! I have a comment about the approach but I think you only need a few small tweaks to get this ready for merging.
fetchRepoErr := repo.FetchContext(ctx, &git.FetchOptions{ | ||
RemoteName: "origin", | ||
Force: true, | ||
Auth: opts.Auth.Convert(), | ||
}) | ||
if err != nil && !errors.Is(err, git.NoErrAlreadyUpToDate) { | ||
return nil, UpdateFailedError{ | ||
if fetchRepoErr != nil && !errors.Is(fetchRepoErr, git.NoErrAlreadyUpToDate) { | ||
err = UpdateFailedError{ | ||
Repository: opts.Repository, | ||
Inner: err, | ||
Inner: fetchRepoErr, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, I'd rather the error handler here return instead of falling back to Reset, that way we don't touch the repo at all in case a pull fails; something like
if err != nil && !errors.Is(err, git.NoErrAlreadyUpToDate) {
workTree, workTreeErr := repo.Worktree()
if workTreeErr != nil {
return nil, workTreeErr
}
return &GitRepo{
opts: opts,
repo: repo,
workTree: workTree,
}, UpdateFailedError{
Repository: opts.Repository,
Inner: err,
}
}
(This can probably be refactored a bit so the GitRepo object is constructed before doing a pull to reduce duplication with the successful path)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point here. I've amended in latest commit.
err = UpdateFailedError{ | ||
Repository: repo.opts.Repository, | ||
Inner: err, | ||
Inner: fetchRepoErr, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto here: I'm not sure we should be falling back to resetting the git repo when the update fails, and I think we should just return directly here.
(Also, this instance of err
is always overwritten by the assignment on line 125 below)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point here. I've amended in latest commit.
component/module/git/git.go
Outdated
// Failure to update repository makes the module loader temporarily use cached contents on disk | ||
var updateVcsErr vcs.UpdateFailedError | ||
if c.repo == nil || !reflect.DeepEqual(repoOpts, c.repoOpts) { | ||
r, err := vcs.NewGitRepo(context.Background(), repoPath, repoOpts) | ||
if err != nil { | ||
return err | ||
if errors.As(err, &updateVcsErr) { | ||
level.Error(c.log).Log("msg", "failed to update repository", "err", err) | ||
c.updateHealth(err) | ||
} else { | ||
return err | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, I'm still not sure if the error check needs to happen here in the Update or in the call to pollFile.
It seems like it would be sufficient if New made the check instead, since we're really only interested about fixing component construction to use a cache:
// New creates a new module.git component.
func New(o component.Options, args Arguments) (*Component, error) {
m, err := module.NewModuleComponent(o)
if err != nil {
return nil, err
}
c := &Component{
opts: o,
log: o.Logger,
mod: m,
argsChanged: make(chan struct{}, 1),
}
// Only acknowledge the error from Update if it's not a
// vcs.UpdateFailedError; vcs.UpdateFailedError means that the Git repo
// exists but we were just unable to update it.
if err := c.Update(args); err != nil && !errors.Is(err, &vcs.UpdateFailedError{}) {
return nil, err
}
return c, nil
}
I think adding that check in New will allow you to leave Update and pollFile unchanged. WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My bad, pollFile
also returns vcs.UpdateFailedError
so the New
method also has to have the changes as well. I've finalized in the latest commit
3c49ca7
to
6cd7029
Compare
GH checks is failing due to degraded performance on DockerHub's side. Please help rerunning when it's better, Robert. Thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for the delay between reviews, there was a holiday yesterday. This is getting much closer!
component/module/git/git.go
Outdated
return nil, err | ||
if errors.As(err, &vcs.UpdateFailedError{}) { | ||
level.Error(c.log).Log("msg", "failed to update repository", "err", err) | ||
c.updateHealth(err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This shouldn't be necessary since the call to Update
will already update the health for you if it returns an error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I wasn't aware of this internal detail :D
Removed updateHealth
in latest commit
if errors.As(err, &vcs.UpdateFailedError{}) { | ||
level.Error(c.log).Log("msg", "failed to update repository", "err", err) | ||
c.updateHealth(err) | ||
} else { | ||
return err | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I'm following whether this is necessary still; with the latest change, it's currently the callers responsibility for whether UpdateFailedError needs separate handling or not.
Am I missing something that this check is changing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The err check for UpdateFailedError
in New
method is to check for returned error from pollFile
method.
This check right here is to inform Flow controller component's unhealthiness from failing to update Git repo and to continue assigning the Repo object and options to internal attributes. Returning early will leave the attributes, namely r.repo
empty and can cause null pointer exception, I'd wager.
I can't run the CI because of merge conflicts, can you resolve those? |
…fetch Signed-off-by: hainenber <[email protected]>
Signed-off-by: hainenber <[email protected]>
Signed-off-by: hainenber <[email protected]>
Signed-off-by: hainenber <[email protected]>
Signed-off-by: hainenber <[email protected]>
Signed-off-by: hainenber <[email protected]>
6cd7029
to
d5e93a0
Compare
Thanks for the heads-up, done resolving on my side! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
…fetch (grafana#5712) Signed-off-by: hainenber <[email protected]> (cherry picked from commit 39b78a8)
* packaging: fix grafana-agent-flow.river (#5802) (#5809) * packaging: fix grafana-agent-flow.river (#5802) Add needed label in default `grafana-agent-flow.river` default configuration used in downstream packages. * Update CHANGELOG.md (cherry picked from commit eac661f) * misc: fix changelog entry (#5812) PR #5802 accidentally added the changelog entry to a published release. (cherry picked from commit bc3babc) * feat(module/git): allow module.git use cached content when failed to fetch (#5712) Signed-off-by: hainenber <[email protected]> (cherry picked from commit 39b78a8) * Fix converter output for prometheus.exporter.windows to not unnecessarily add empty blocks (#5817) (cherry picked from commit 165914b) * delete obsolete broken windows test (#5818) (cherry picked from commit bcbc7ab) * prepare for release v0.38.0-rc.1 (#5821) (cherry picked from commit 7d775c1) --------- Co-authored-by: Brice Waegeneire <[email protected]> Co-authored-by: Đỗ Trọng Hải <[email protected]> Co-authored-by: Erik Baranowski <[email protected]>
PR Description
Allow
module.git
loader to use cached contents when failed to fetch during startup/update. This should be transient as the next poll interval, if fetch failure got resolved, the Git content will be up-to-date.Which issue(s) this PR fixes
Fixes #5708
Notes to the Reviewer
Do let me know if something more format is needed, like a unit test or so.
PR Checklist