-
Notifications
You must be signed in to change notification settings - Fork 29.8k
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
fs: add AbortSignal support to watch #37190
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -1579,6 +1579,17 @@ function watch(filename, options, listener) { | |||||
if (listener) { | ||||||
watcher.addListener('change', listener); | ||||||
} | ||||||
if (options.signal) { | ||||||
if (options.signal.aborted) { | ||||||
process.nextTick(() => watcher.close()); | ||||||
} else { | ||||||
const listener = () => watcher.close(); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: you could move the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I actually find this way more readable though I don't have very strong feelings about it. |
||||||
options.signal.addEventListener('abort', listener); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure if that matters / is more efficient, but at least it makes it clearer that this is just a one timer:
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a common issue that gets brought up from time to time. The reason I like doing That assumption has lead to memory leaks in our code before - this way the cleanup is explicit (when the watcher is closed) and I think it makes bugs slightly less likely. |
||||||
watcher.once('close', () => { | ||||||
options.signal.removeEventListener('abort', listener); | ||||||
}); | ||||||
} | ||||||
} | ||||||
|
||||||
return watcher; | ||||||
} | ||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
// Flags: --expose-internals | ||
'use strict'; | ||
|
||
// Verify that AbortSignal integration works for fs.watch | ||
|
||
const common = require('../common'); | ||
|
||
if (common.isIBMi) | ||
common.skip('IBMi does not support `fs.watch()`'); | ||
|
||
const fs = require('fs'); | ||
const fixtures = require('../common/fixtures'); | ||
|
||
|
||
{ | ||
// Signal aborted after creating the watcher | ||
const file = fixtures.path('empty.js'); | ||
const ac = new AbortController(); | ||
const { signal } = ac; | ||
const watcher = fs.watch(file, { signal }); | ||
watcher.once('close', common.mustCall()); | ||
setImmediate(() => ac.abort()); | ||
} | ||
{ | ||
// Signal aborted before creating the watcher | ||
const file = fixtures.path('empty.js'); | ||
const ac = new AbortController(); | ||
const { signal } = ac; | ||
ac.abort(); | ||
const watcher = fs.watch(file, { signal }); | ||
watcher.once('close', common.mustCall()); | ||
} |
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.
Why on next tick?
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.
So that users have a chance to subscribe to the
"close"
event.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.
(Just because
watch
returns an EventEmitter watcher and not a promise or a callback)