Skip to content
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

Atomic rename #47

Merged
merged 9 commits into from
Apr 21, 2017
Merged

Atomic rename #47

merged 9 commits into from
Apr 21, 2017

Conversation

develar
Copy link
Contributor

@develar develar commented Feb 24, 2017

#36 (comment)

Already used in the electron-builder. During test period no issues were discovered.

Close #36

@develar
Copy link
Contributor Author

develar commented Mar 18, 2017

@malept Could you please review?

Copy link
Member

@MarshallOfSound MarshallOfSound left a comment

Choose a reason for hiding this comment

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

RIP, not getting notifications from this repo 😆

LGTM, only issue would be breach of scope (the package.json changes, but they all look fair enough so I'm 👍 )

@MarshallOfSound
Copy link
Member

Probably want a second set of eyes before merge into a key module

/cc @electron-userland

package.json Outdated
"mkdirp": "^0.5.1",
"tape": "^4.6.0",
Copy link
Member

Choose a reason for hiding this comment

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

The changes in this file are unnecessary.

lib/index.js Outdated
})
debug('moving', filename, 'from', this.cache, 'to', target)
fs.rename(path.join(this.cache, filename), target, (err) => {
if (err) return cb(err)
Copy link
Member

Choose a reason for hiding this comment

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

So if rename fails, we're just going to leave the file in the cache dir?

This should clean up after itself.

lib/index.js Outdated
downloadFile (url, filename, cacheFilename, cb, onSuccess) {
debug('downloading', url, 'to', this.tmpdir)
downloadFile (url, cacheFilename, cb, onSuccess) {
const tempFileName = `tmp-${process.pid}-${(tmpFileCounter++).toString(16)}-${path.basename(cacheFilename)}`
Copy link
Member

Choose a reason for hiding this comment

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

I'd rather have this use something like tempnam instead of introducing global variables and hand-rolling it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

tempnam is not suitable because using fs. I think it is ok to not use external module for two lines of code (also, to reduce number of external deps and increase security).

Copy link
Member

Choose a reason for hiding this comment

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

tempnam is not suitable because using fs.

Could you please explain this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't want to use something like mkdtemp here because only our tool creates temp file here — process.pid allows us to be sure that will be no conflicts with other processes. To not complicate and keep it simple.

lib/index.js Outdated
@@ -10,6 +10,8 @@ const pathExists = require('path-exists')
const semver = require('semver')
const sumchecker = require('sumchecker')

let tmpFileCounter = 0
Copy link
Member

Choose a reason for hiding this comment

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

If you're going to keep this, at least make it a class variable or something.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It must be file level variable because class can be created several times.

Copy link
Member

Choose a reason for hiding this comment

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

Yes, a class variable, not an instance variable.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

a class variable, not an instance variable.

Hmm... ES6 doesn't support

static tmpFileCounter = 0

SyntaxError: Unexpected token =

We cannot use this syntax because node doesn't support it.

What do you mean? And for what we should use class variable here? It should be module level variable. e.g. I write in Kotlin and prefer to use file level vars instead of static.

Copy link
Member

Choose a reason for hiding this comment

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

@develar That syntax isn't supported but the syntax ClassName.tmpFileCounter = 0 does work and has the same affect 👍

lib/index.js Outdated
downloadFile (url, filename, cacheFilename, cb, onSuccess) {
debug('downloading', url, 'to', this.tmpdir)
downloadFile (url, cacheFilename, cb, onSuccess) {
const tempFileName = `tmp-${process.pid}-${(tmpFileCounter++).toString(16)}-${path.basename(cacheFilename)}`
Copy link
Member

Choose a reason for hiding this comment

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

tempnam is not suitable because using fs.

Could you please explain this?

lib/index.js Outdated
fs.rename(path.join(cache, filename), target, (err) => {
if (err) {
try {
fs.unlinkSync(cache)
Copy link
Member

Choose a reason for hiding this comment

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

Why not use the async version and get rid of the try...catch?

lib/index.js Outdated
try {
fs.unlinkSync(cache)
} catch (error) {
console.error(`Error deleting cache file: ${error.message}`)
Copy link
Member

Choose a reason for hiding this comment

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

This needs to show the filename that couldn't be removed so the user can deal with it themselves.

Copy link
Member

Choose a reason for hiding this comment

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

I don't think this was addressed.

@develar
Copy link
Contributor Author

develar commented Mar 27, 2017

I have answered to all questions, what's left?

@kevinsawicki
Copy link
Contributor

I have answered to all questions, what's left?

This looks good to me, what do you think @malept?

}
} finally {
cb(err)
}
Copy link
Member

Choose a reason for hiding this comment

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

Not sure what the point of the try...finally is. Is an exception being thrown?

Copy link

Choose a reason for hiding this comment

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

☝️ Yeah it seems unnecessary...

Copy link
Contributor Author

@develar develar Mar 29, 2017

Choose a reason for hiding this comment

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

User application can override console.error. e.g. Jest does it. As we must call user cb in any case, it is more safe to use try-finally here. Otherwise we can get unresolved promise and so on.

Copy link

Choose a reason for hiding this comment

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

Jest does it

Yikes. Ok.

@malept
Copy link
Member

malept commented Mar 29, 2017

@zeke given #36, do you want to take a look?

Copy link

@zeke zeke left a comment

Choose a reason for hiding this comment

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

I agree with @malept's recent feedback all around. Otherwise, looks good to me!

@develar
Copy link
Contributor Author

develar commented Apr 8, 2017

I don't like ElectronDownloader.tmpFileCounter (local module variable is better and more safe), but if you want — ok.

@develar
Copy link
Contributor Author

develar commented Apr 9, 2017

Right now electron-download should be not released after #24 — I get strange errors like Error: ENOENT: no such file or directory, open '/Users/develar/Library/Caches/electron/electron-v1.6.3-darwin-x64.zip And since electron-download (and used libs) doesn't use promises with long stack traces, it is not easy to find cause of error. Not yet clear — is it due to my changes or upstream affected as well.

@Siilwyn maybe you will have some ideas (workaround — remove ~/.electron dir).

@Siilwyn
Copy link
Contributor

Siilwyn commented Apr 9, 2017

@develar I'm assuming you already found the culprit pointed out in #24

@Siilwyn Siilwyn mentioned this pull request Apr 14, 2017
@develar
Copy link
Contributor Author

develar commented Apr 15, 2017

Friendly ping :)

@kevinsawicki kevinsawicki merged commit 9e43a90 into electron:master Apr 21, 2017
@kevinsawicki
Copy link
Contributor

Thanks @develar 👍 🚢

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

Successfully merging this pull request may close these issues.

6 participants