Skip to content
This repository has been archived by the owner on Jul 3, 2019. It is now read-only.

Added retry logic for all git operations. #136

Merged
merged 5 commits into from
Mar 8, 2018

Conversation

dryganets
Copy link
Contributor

Motivation

In the complex CI environments, intermittent issues happen. In order to prevent build failures, it is good to give a server an opportunity to recover from high load spikes.

Test Plan

Put in the ~/.gitconfig following section:
[http]
proxy = http://192.168.1.101:8888
As you don't have a proxy running on the port you will get a timeout error from git.
You could disable the proxy by editing the config file if you need.

Copy link

@nzec nzec left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Travis is failing. Please check.

@dryganets
Copy link
Contributor Author

not ok ENOENT: no such file or directory, open './no-npmignore/.npmignore'

I had a different ENOENT on npm install locally until I removed package-lock file.

I don't think this failure is related to my changes.

@dryganets
Copy link
Contributor Author

#137

created to test the error.
Repo without any changes triggers the same error.

Copy link
Owner

@zkat zkat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey! This is a great idea, and thank you for taking the time to put this together. I've made a few comments for changes I'd like to see, with apologies for a conflict that was introduced because of another PR that's now been merged.

I think this is a great idea, and I really appreciate this!

lib/util/git.js Outdated
'Operation timed out',
'Failed to connect to .* Timed out',
'Connection reset by peer',
'Couldn\'t resolve host'
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should not retry on resolve failure, because that tends to be a sign of an offline state, and unlikely to be fixed on a retry. See the errors make-fetch-happen retries on.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will remove, thank you.

Copy link
Contributor

@xqin xqin Mar 12, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why this code still in repository???

pacote/lib/util/git.js

Lines 33 to 35 in 425c58d

'Connection timed out',
'Operation timed out',
'Failed to connect to .* Timed out',

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because this retry logic, it make npm install process will never end, when user can not access github by http/https/ssh protocol(like in Intranet CI environments).

if i dit not put -ddd arguments in command line, and i will never see what happend with npm.

$ node ./bin/npm-cli.js install -ddd github:hello/world
npm info it worked if it ends with ok
npm verb cli [ '/Users/xqin/.nvm/versions/node/v8.9.4/bin/node',
npm verb cli   '/Users/xqin/Desktop/Work/npm/bin/npm-cli.js',
npm verb cli   'install',
npm verb cli   '-ddd',
npm verb cli   'github:hello/world' ]
npm info using npm@6.8.0
npm info using node@v8.9.4
npm verb npm-session 146e905747a05a8f
npm sill install loadCurrentTree
npm sill install readLocalPackageData
npm sill pacote Retrying git command: ls-remote -h -t ssh://git@github.com/hello/world.git attempt # 2
npm sill pacote Retrying git command: ls-remote -h -t ssh://git@github.com/hello/world.git attempt # 3
npm sill pacote Retrying git command: ls-remote -h -t ssh://git@github.com/hello/world.git attempt # 4
npm sill pacote Retrying git command: ls-remote -h -t ssh://git@github.com/hello/world.git attempt # 5
npm sill pacote Retrying git command: ls-remote -h -t ssh://git@github.com/hello/world.git attempt # 6
npm sill pacote Retrying git command: ls-remote -h -t ssh://git@github.com/hello/world.git attempt # 7
npm sill pacote Retrying git command: ls-remote -h -t ssh://git@github.com/hello/world.git attempt # 8
npm sill pacote Retrying git command: ls-remote -h -t ssh://git@github.com/hello/world.git attempt # 9
npm sill pacote Retrying git command: ls-remote -h -t ssh://git@github.com/hello/world.git attempt # 10
⸨░░░░░░░░░░░░░░░░░░⸩ ⠦ rollbackFailedOptional: sill pacote Retrying git command: ls-remote -h -t ssh://git@github.com/hello/world.git attempt # 10

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lib/util/git.js Outdated
@@ -25,6 +26,23 @@ const GOOD_ENV_VARS = new Set([
'GIT_SSL_NO_VERIFY'
])

const GIT_TRANSIENT_ERRORS = [
'remote error: Internal Server Error',
'fatal: Couldn\'t find remote ref ',
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a failure to find a remote ref is very unlikely to be fixed by an immediate retry -- even if there's a timing issue, it's unlikely to be fixed in such a small window, and this particular failure, I would expect, is almost always an error the user themself has to fix.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agree

lib/util/git.js Outdated
}
})
if (type === 'tag') {
const match = ref.match(/v?(\d+\.\d+\.\d+)$/)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line is conflicting with the version in latest -- could you pull in that patch here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

lib/util/git.js Outdated
return execFileAsync(gitPath, gitArgs, mkOpts(gitOpts, opts))
return promiseRetry((retry, number) => {
if (number != 1) {
opts.log.info('pacote', 'Retrying git command: ' + gitArgs.join(' ') + ' attempt # ' + number);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if you're gonna log this, I'd rather this be logged in verbose instead.

lib/util/git.js Outdated
return cp.spawn(gitPath, gitArgs, mkOpts(gitOpts, opts))
return promiseRetry((retry, number) => {
if (number != 1) {
opts.log.info('pacote', 'Retrying git command: ' + gitArgs.join(' ') + ' attempt # ' + number);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto, on verbose

lib/util/git.js Outdated
const GIT_TRANSIENT_ERROR_RE = new RegExp(GIT_TRANSIENT_ERRORS)

function shouldRetry(error) {
return GIT_TRANSIENT_ERROR_RE.test(error);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This ; made me realize the standard check was misconfigured -- it's now been fixed, and you'll need to fix that standard linter violations in this patch, too. Mostly, it's just removing the semicolons, I think. You'll get the errors now when you rebase onto latest.

In the complex CI environments, intermittent issues happen. In order to prevent build failures, it is good to give a server an opportunity to recover from high load spikes.

Put in the ~/.gitconfig following section:
[http]
        proxy = http://192.168.1.101:8888

As you don't have a proxy running on the port you will get a timeout error from git.
@dryganets
Copy link
Contributor Author

dryganets commented Feb 6, 2018

As for another CI failure
you need to re-generate the package-lock.json to make it gone.

see:
npm/npm#17444

@dryganets
Copy link
Contributor Author

@zkat I believe I have fixes for all comments you made.

@dryganets
Copy link
Contributor Author

It might be worth to reconsider the log level from silly to warn.
As log won't be visible unless retry happens.
And if retry happens it is very important to know about it as it might bring some light on the configuration problems of the build server.

Normally on the user machine, there are no extra logs anyway.

Copy link
Owner

@zkat zkat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! :)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants