From b259be7c5484bbb976be6a7dc9ba3e431705b528 Mon Sep 17 00:00:00 2001 From: James M Snell Date: Tue, 23 Jun 2015 20:42:49 -0700 Subject: [PATCH 01/17] doc: improve http.abort description Per #4409, the documentation on http.abort is a bit lacking. This provides a slight improvement. Reviewed-By: James M Snell PR-URL: https://github.com/joyent/node/pull/25591 --- doc/api/http.markdown | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/api/http.markdown b/doc/api/http.markdown index 5cf3b07a9cd778..833d2dfed53b25 100644 --- a/doc/api/http.markdown +++ b/doc/api/http.markdown @@ -911,7 +911,8 @@ is finished. ### request.abort() -Aborts a request. (New since v0.3.8.) +Marks the request as aborting. Calling this will cause remaining data +in the response to be dropped and the socket to be destroyed. ### request.setTimeout(timeout[, callback]) From 60b4239aadc02fa601184f6b3fda05279c4f0a37 Mon Sep 17 00:00:00 2001 From: James M Snell Date: Tue, 23 Jun 2015 20:59:56 -0700 Subject: [PATCH 02/17] doc: mention that mode is ignored if file exists per: https://github.com/joyent/node/issues/6847 Reviewed-By: James M Snell PR-URL: https://github.com/joyent/node/pull/25591 --- doc/api/fs.markdown | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/api/fs.markdown b/doc/api/fs.markdown index 5f96b10763fe45..c15a9222cdfddd 100644 --- a/doc/api/fs.markdown +++ b/doc/api/fs.markdown @@ -823,6 +823,9 @@ there's no file descriptor leak. If `autoClose` is set to true (default behavior), on `error` or `end` the file descriptor will be closed automatically. +`mode` sets the file mode (permission and sticky bits), but only if the +file was created. + An example to read the last 10 bytes of a file which is 100 bytes long: fs.createReadStream('sample.txt', {start: 90, end: 99}); From f32f82249d5822b719f43415037820772cc2863d Mon Sep 17 00:00:00 2001 From: James M Snell Date: Tue, 4 Aug 2015 14:20:21 -0700 Subject: [PATCH 03/17] docs: Fix default options for fs.createWriteStream() Per: https://github.com/joyent/node/commit/b7229debbe6007772a4cbe82f158176b6f45de80 The documentation for createWriteStream() references an 'encoding' property that has a default value of null. However, this property is never referenced by createWriteStream() or WritableState(). Instead a 'defaultEncoding' property is referenced in WritableState() with a default of 'utf8' if no value is supplied. This fix updates the documentation to rename the 'encoding' property to 'defaultEncoding' and indicate its default value of 'utf8'. Originally Contributed By: @chrisneave (The original patch did not apply clean) --- doc/api/fs.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/api/fs.markdown b/doc/api/fs.markdown index c15a9222cdfddd..0a6b178e038232 100644 --- a/doc/api/fs.markdown +++ b/doc/api/fs.markdown @@ -850,14 +850,14 @@ Returns a new WriteStream object (See `Writable Stream`). `options` is an object or string with the following defaults: { flags: 'w', - encoding: null, + defaultEncoding: 'utf8', fd: null, mode: 0o666 } `options` may also include a `start` option to allow writing data at some position past the beginning of the file. Modifying a file rather than replacing it may require a `flags` mode of `r+` rather than the -default mode `w`. The `encoding` can be `'utf8'`, `'ascii'`, `binary`, +default mode `w`. The `defaultEncoding` can be `'utf8'`, `'ascii'`, `binary`, or `'base64'`. Like `ReadStream` above, if `fd` is specified, `WriteStream` will ignore the From e603452c7f7cf56b252a4dce345fbba785ef22b1 Mon Sep 17 00:00:00 2001 From: James M Snell Date: Tue, 4 Aug 2015 14:23:28 -0700 Subject: [PATCH 04/17] Documentation update about Buffer initialization per: https://github.com/joyent/node/commit/53b6a615a5a0eab42b7ffd0baf3f2b5117f0229a fixes https://github.com/joyent/node/issues/7230 Original commit patch did not apply cleanly Originally contributed by @sarathms --- doc/api/buffer.markdown | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/api/buffer.markdown b/doc/api/buffer.markdown index 92b7f2ba93b288..1f5cef341fccb4 100644 --- a/doc/api/buffer.markdown +++ b/doc/api/buffer.markdown @@ -67,6 +67,10 @@ Allocates a new buffer of `size` bytes. `size` must be less than 2,147,483,648 bytes (2 GB) on 64 bits architectures, otherwise a `RangeError` is thrown. +Unlike `ArrayBuffers`, the underlying memory for buffers is not initialized. So +the contents of a newly created `Buffer` is unknown. Use `buf.fill(0)`to +initialize a buffer to zeroes. + ### new Buffer(array) * `array` Array From 66047a50592d7ad62f78b7a737da446b1a2c77e4 Mon Sep 17 00:00:00 2001 From: James M Snell Date: Fri, 26 Jun 2015 07:51:14 -0700 Subject: [PATCH 05/17] doc: add a note about readable in flowing mode Original: https://github.com/joyent/node/pull/8682 Slightly modified version of the original PR (#8682) to add appropriate line wrapping and fix a couple of grammar nits. Reviewed-By: James M Snell PR-URL: https://github.com/joyent/node/pull/25591 --- doc/api/stream.markdown | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/api/stream.markdown b/doc/api/stream.markdown index a7a78f229edb57..ba4de626cc7573 100644 --- a/doc/api/stream.markdown +++ b/doc/api/stream.markdown @@ -164,6 +164,9 @@ readable.on('readable', function() { Once the internal buffer is drained, a `readable` event will fire again when more data is available. +The `readable` event is not emitted in the "flowing" mode with the +sole exception of the last one, on end-of-stream. + #### Event: 'data' * `chunk` {Buffer | String} The chunk of data. @@ -181,6 +184,9 @@ readable.on('data', function(chunk) { console.log('got %d bytes of data', chunk.length); }); ``` +Note that the `readable` event should not be used together with `data` +because the assigning the latter switches the stream into "flowing" mode, +so the `readable` event will not be emitted. #### Event: 'end' From 93c489e598a0c856304346ee4cfe621a85d37598 Mon Sep 17 00:00:00 2001 From: James M Snell Date: Tue, 4 Aug 2015 14:28:16 -0700 Subject: [PATCH 06/17] doc: Document http.request protocol option Per: https://github.com/joyent/node/commit/16f547600a81552b7c9515cda8f2b1f38f98dad5 Originally contributed by: @scop Original commit patch did not apply cleanly --- doc/api/http.markdown | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/api/http.markdown b/doc/api/http.markdown index 833d2dfed53b25..966b304b56d282 100644 --- a/doc/api/http.markdown +++ b/doc/api/http.markdown @@ -462,6 +462,7 @@ automatically parsed with [url.parse()][]. Options: +- `protocol`: Protocol to use. Defaults to `'http'`. - `host`: A domain name or IP address of the server to issue the request to. Defaults to `'localhost'`. - `hostname`: Alias for `host`. To support `url.parse()` `hostname` is From 46396ccf44881b62c76f513973b4ae69fde7c7c0 Mon Sep 17 00:00:00 2001 From: James M Snell Date: Tue, 4 Aug 2015 14:35:13 -0700 Subject: [PATCH 07/17] doc, comments: Grammar and spelling fixes Per: https://github.com/joyent/node/commit/5ccb429ee8556ac0cbc81dddc2d5a2a4f5d75b58 Originally contributed by @scop Original commit patch did not apply cleanly --- doc/api/buffer.markdown | 2 +- doc/api/cluster.markdown | 4 ++-- doc/api/dns.markdown | 4 ++-- lib/_http_client.js | 4 ++-- lib/url.js | 4 ++-- src/node.cc | 2 +- src/node_object_wrap.h | 2 +- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/doc/api/buffer.markdown b/doc/api/buffer.markdown index 1f5cef341fccb4..94f3e3d8e164f5 100644 --- a/doc/api/buffer.markdown +++ b/doc/api/buffer.markdown @@ -43,7 +43,7 @@ Creating a typed array from a `Buffer` works with the following caveats: 2. The buffer's memory is interpreted as an array, not a byte array. That is, `new Uint32Array(new Buffer([1,2,3,4]))` creates a 4-element `Uint32Array` - with elements `[1,2,3,4]`, not an `Uint32Array` with a single element + with elements `[1,2,3,4]`, not a `Uint32Array` with a single element `[0x1020304]` or `[0x4030201]`. NOTE: Node.js v0.8 simply retained a reference to the buffer in `array.buffer` diff --git a/doc/api/cluster.markdown b/doc/api/cluster.markdown index b7e76fcb8ffa0e..abf05bf9f40c82 100644 --- a/doc/api/cluster.markdown +++ b/doc/api/cluster.markdown @@ -121,7 +121,7 @@ values are `"rr"` and `"none"`. ## cluster.settings * {Object} - * `execArgv` {Array} list of string arguments passed to the io.js executable. + * `execArgv` {Array} list of string arguments passed to the io.js executable. (Default=`process.execArgv`) * `exec` {String} file path to worker file. (Default=`process.argv[1]`) * `args` {Array} string arguments passed to worker. @@ -613,7 +613,7 @@ It is not emitted in the worker. ### Event: 'disconnect' -Similar to the `cluster.on('disconnect')` event, but specfic to this worker. +Similar to the `cluster.on('disconnect')` event, but specific to this worker. cluster.fork().on('disconnect', function() { // Worker has disconnected diff --git a/doc/api/dns.markdown b/doc/api/dns.markdown index d8ed53e3fa0f79..7c9f419ce08ae7 100644 --- a/doc/api/dns.markdown +++ b/doc/api/dns.markdown @@ -85,7 +85,7 @@ All properties are optional. An example usage of options is shown below. ``` The callback has arguments `(err, address, family)`. `address` is a string -representation of a IP v4 or v6 address. `family` is either the integer 4 or 6 +representation of an IP v4 or v6 address. `family` is either the integer 4 or 6 and denotes the family of `address` (not necessarily the value initially passed to `lookup`). @@ -163,7 +163,7 @@ attribute (e.g. `[{'priority': 10, 'exchange': 'mx.example.com'},...]`). ## dns.resolveTxt(hostname, callback) The same as `dns.resolve()`, but only for text queries (`TXT` records). -`addresses` is an 2-d array of the text records available for `hostname` (e.g., +`addresses` is a 2-d array of the text records available for `hostname` (e.g., `[ ['v=spf1 ip4:0.0.0.0 ', '~all' ] ]`). Each sub-array contains TXT chunks of one record. Depending on the use case, the could be either joined together or treated separately. diff --git a/lib/_http_client.js b/lib/_http_client.js index a7d714f7e0b0b2..50d1052b44e15c 100644 --- a/lib/_http_client.js +++ b/lib/_http_client.js @@ -359,7 +359,7 @@ function parserOnIncomingClient(res, shouldKeepAlive) { var req = socket._httpMessage; - // propogate "domain" setting... + // propagate "domain" setting... if (req.domain && !res.domain) { debug('setting "res.domain"'); res.domain = req.domain; @@ -465,7 +465,7 @@ function tickOnSocket(req, socket) { socket.parser = parser; socket._httpMessage = req; - // Setup "drain" propogation. + // Setup "drain" propagation. httpSocketSetup(socket); // Propagate headers limit from request object to parser diff --git a/lib/url.js b/lib/url.js index 55c5248e4751dd..45155fee936bbf 100644 --- a/lib/url.js +++ b/lib/url.js @@ -587,7 +587,7 @@ Url.prototype.resolveObject = function(relative) { if (psychotic) { result.hostname = result.host = srcPath.shift(); //occationaly the auth can get stuck only in host - //this especialy happens in cases like + //this especially happens in cases like //url.resolveObject('mailto:local1@domain1', 'local2@domain2') var authInHost = result.host && result.host.indexOf('@') > 0 ? result.host.split('@') : false; @@ -669,7 +669,7 @@ Url.prototype.resolveObject = function(relative) { result.hostname = result.host = isAbsolute ? '' : srcPath.length ? srcPath.shift() : ''; //occationaly the auth can get stuck only in host - //this especialy happens in cases like + //this especially happens in cases like //url.resolveObject('mailto:local1@domain1', 'local2@domain2') var authInHost = result.host && result.host.indexOf('@') > 0 ? result.host.split('@') : false; diff --git a/src/node.cc b/src/node.cc index 7c0a80ec31462b..c272139e5518cd 100644 --- a/src/node.cc +++ b/src/node.cc @@ -2184,7 +2184,7 @@ static void OnFatalError(const char* location, const char* message) { NO_RETURN void FatalError(const char* location, const char* message) { OnFatalError(location, message); - // to supress compiler warning + // to suppress compiler warning abort(); } diff --git a/src/node_object_wrap.h b/src/node_object_wrap.h index d00e1484b7c10c..f0226622272a5c 100644 --- a/src/node_object_wrap.h +++ b/src/node_object_wrap.h @@ -80,7 +80,7 @@ class ObjectWrap { * attached to detached state it will be freed. Be careful not to access * the object after making this call as it might be gone! * (A "weak reference" means an object that only has a - * persistant handle.) + * persistent handle.) * * DO NOT CALL THIS FROM DESTRUCTOR */ From 4a8fbf32d0687b89a590cf402443a33e16aeaed0 Mon Sep 17 00:00:00 2001 From: James M Snell Date: Tue, 4 Aug 2015 14:37:54 -0700 Subject: [PATCH 08/17] updated documentation for fs.createReadStream per: https://github.com/joyent/node/commit/59c67fe3cda1163e4e3cf66a8ab16e7b6d72e6a3 Originally contributed by @skypjack Original commit patch did not land cleanly --- doc/api/fs.markdown | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/api/fs.markdown b/doc/api/fs.markdown index 0a6b178e038232..c851d9a72b8744 100644 --- a/doc/api/fs.markdown +++ b/doc/api/fs.markdown @@ -801,6 +801,10 @@ on Unix systems, it never was. Returns a new ReadStream object (See `Readable Stream`). +Be aware that, unlike the default value set for `highWaterMark` on a +readable stream(16kb), the stream returned by this method has a +default value of 64kb for the same parameter. + `options` is an object or string with the following defaults: { flags: 'r', From 41b890837fb36696e58b35827088311f7311467c Mon Sep 17 00:00:00 2001 From: Jared Fox Date: Wed, 24 Jun 2015 16:58:38 -0400 Subject: [PATCH 09/17] Update child_process.markdown, spelling 'the' to 'then' Reviewed-By: James M Snell PR-URL: https://github.com/joyent/node/pull/25591 --- doc/api/child_process.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/child_process.markdown b/doc/api/child_process.markdown index 3d6e5f5fe2f048..4acd61bfa6a97c 100644 --- a/doc/api/child_process.markdown +++ b/doc/api/child_process.markdown @@ -279,7 +279,7 @@ Here is an example of sending a server: child.send('server', server); }); -And the child would the receive the server object as: +And the child would then receive the server object as: process.on('message', function(m, server) { if (m === 'server') { From d3407bc7610e82467236350c2ecac27e3af7e46c Mon Sep 17 00:00:00 2001 From: Philippe Laferriere Date: Sun, 28 Jun 2015 10:08:25 -0400 Subject: [PATCH 10/17] doc: Clarified read method with specified size argument. Made explicitely clear that when size bytes are not available, it will return null, unless we've ended, in which case the data remaining in the buffer will be returned. Fixes #7273 Reviewed-By: James M Snell PR-URL: https://github.com/joyent/node/pull/25591 --- doc/api/stream.markdown | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/api/stream.markdown b/doc/api/stream.markdown index ba4de626cc7573..f0ee5dabd77d15 100644 --- a/doc/api/stream.markdown +++ b/doc/api/stream.markdown @@ -227,7 +227,9 @@ returns it. If there is no data available, then it will return `null`. If you pass in a `size` argument, then it will return that many -bytes. If `size` bytes are not available, then it will return `null`. +bytes. If `size` bytes are not available, then it will return `null`, +unless we've ended, in which case it will return the data remaining +in the buffer. If you do not specify a `size` argument, then it will return all the data in the internal buffer. From c6d7974d808d1b781d40eb43eab05d1979604339 Mon Sep 17 00:00:00 2001 From: Benjamin Steephenson Date: Tue, 3 Mar 2015 09:59:07 -0500 Subject: [PATCH 11/17] docs:events clarify emitter.listener() behavior Clarifies that emitter.listener() returns a copy, not a reference Resolves issue #9022 Reviewed-By: James M Snell PR-URL: https://github.com/joyent/node/pull/25591 --- doc/api/events.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/events.markdown b/doc/api/events.markdown index fbc04a96239b0f..a51905ab4da110 100644 --- a/doc/api/events.markdown +++ b/doc/api/events.markdown @@ -122,7 +122,7 @@ Note that `emitter.setMaxListeners(n)` still has precedence over ### emitter.listeners(event) -Returns an array of listeners for the specified event. +Returns a copy of the array of listeners for the specified event. server.on('connection', function (stream) { console.log('someone connected!'); From 034b4d563398a1a26b4cbb4c4dc4364db01b3110 Mon Sep 17 00:00:00 2001 From: James M Snell Date: Wed, 1 Jul 2015 12:52:47 -0700 Subject: [PATCH 12/17] doc: two minor stream doc improvements per: https://github.com/joyent/node/issues/14596 1. document that a runtime error will occur if you attempt to unshift after the end event 2. document that calling read after the end event will return null and will not trigger a runtime error Reviewed-By: James M Snell PR-URL: https://github.com/joyent/node/pull/25591 --- doc/api/stream.markdown | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/doc/api/stream.markdown b/doc/api/stream.markdown index f0ee5dabd77d15..eeba19f67f509b 100644 --- a/doc/api/stream.markdown +++ b/doc/api/stream.markdown @@ -228,7 +228,7 @@ returns it. If there is no data available, then it will return If you pass in a `size` argument, then it will return that many bytes. If `size` bytes are not available, then it will return `null`, -unless we've ended, in which case it will return the data remaining +unless we've ended, in which case it will return the data remaining in the buffer. If you do not specify a `size` argument, then it will return all the @@ -251,6 +251,9 @@ readable.on('readable', function() { If this method returns a data chunk, then it will also trigger the emission of a [`'data'` event][]. +Note that calling `readable.read([size])` after the `end` event has been +triggered will return `null`. No runtime error will be raised. + #### readable.setEncoding(encoding) * `encoding` {String} The encoding to use. @@ -422,6 +425,9 @@ parser, which needs to "un-consume" some data that it has optimistically pulled out of the source, so that the stream can be passed on to some other party. +Note that `stream.unshift(chunk)` cannot be called after the `end` event +has been triggered; a runtime error will be raised. + If you find that you must often call `stream.unshift(chunk)` in your programs, consider implementing a [Transform][] stream instead. (See API for Stream Implementors, below.) From d0b54ea29a950176b1f73755a4d121d165fc9a83 Mon Sep 17 00:00:00 2001 From: fresheneesz Date: Thu, 25 Jun 2015 16:05:40 -0700 Subject: [PATCH 13/17] doc: clarify Readable._read and Readable.push Minor clarifications around Readable._read and Readable.push to make their implementation/usage easier to understand. https://github.com/joyent/node/issues/14124#issuecomment-115392674 Reviewed-By: James M Snell PR-URL: https://github.com/joyent/node/pull/25591 --- doc/api/stream.markdown | 45 ++++++++++++++++++----------------------- 1 file changed, 20 insertions(+), 25 deletions(-) diff --git a/doc/api/stream.markdown b/doc/api/stream.markdown index eeba19f67f509b..1fd2e34bac789b 100644 --- a/doc/api/stream.markdown +++ b/doc/api/stream.markdown @@ -936,24 +936,22 @@ initialized. * `size` {Number} Number of bytes to read asynchronously -Note: **Implement this function, but do NOT call it directly.** +Note: **Implement this method, but do NOT call it directly.** -This function should NOT be called directly. It should be implemented -by child classes, and only called by the internal Readable class -methods. +This method is prefixed with an underscore because it is internal to the +class that defines it and should only be called by the internal Readable +class methods. All Readable stream implementations must provide a _read +method to fetch data from the underlying resource. -All Readable stream implementations must provide a `_read` method to -fetch data from the underlying resource. +When _read is called, if data is available from the resource, `_read` should +start pushing that data into the read queue by calling `this.push(dataChunk)`. +`_read` should continue reading from the resource and pushing data until push +returns false, at which point it should stop reading from the resource. Only +when _read is called again after it has stopped should it start reading +more data from the resource and pushing that data onto the queue. -This method is prefixed with an underscore because it is internal to -the class that defines it, and should not be called directly by user -programs. However, you **are** expected to override this method in -your own extension classes. - -When data is available, put it into the read queue by calling -`readable.push(chunk)`. If `push` returns false, then you should stop -reading. When `_read` is called again, you should start pushing more -data. +Note: once the `_read()` method is called, it will not be called again until +the `push` method is called. The `size` argument is advisory. Implementations where a "read" is a single call that returns data can use this to know how much data to @@ -969,19 +967,16 @@ becomes available. There is no need, for example to "wait" until Buffer encoding, such as `'utf8'` or `'ascii'` * return {Boolean} Whether or not more pushes should be performed -Note: **This function should be called by Readable implementors, NOT +Note: **This method should be called by Readable implementors, NOT by consumers of Readable streams.** -The `_read()` function will not be called again until at least one -`push(chunk)` call is made. - -The `Readable` class works by putting data into a read queue to be -pulled out later by calling the `read()` method when the `'readable'` -event fires. +If a value other than null is passed, The `push()` method adds a chunk of data +into the queue for subsequent stream processors to consume. If `null` is +passed, it signals the end of the stream (EOF), after which no more data +can be written. -The `push()` method will explicitly insert some data into the read -queue. If it is called with `null` then it will signal the end of the -data (EOF). +The data added with `push` can be pulled out by calling the `read()` method +when the `'readable'`event fires. This API is designed to be as flexible as possible. For example, you may be wrapping a lower-level source which has some sort of From de790622da8cb928187052b4407103ce4f4e1155 Mon Sep 17 00:00:00 2001 From: James M Snell Date: Mon, 6 Jul 2015 11:18:06 -0700 Subject: [PATCH 14/17] doc: stream.unshift does not reset reading state Per https://github.com/joyent/node/issues/14604, Document that performing an `unshift` during a read can have unexpected results. Following the `unshift` with a `push('')` resets the reading state appropriately. Also indicate that doing an `unshift` during a read is not optimal and should be avoided. Reviewed-By: James M Snell PR-URL: https://github.com/joyent/node/pull/25591 --- doc/api/stream.markdown | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/doc/api/stream.markdown b/doc/api/stream.markdown index 1fd2e34bac789b..a18d59ea469654 100644 --- a/doc/api/stream.markdown +++ b/doc/api/stream.markdown @@ -466,6 +466,13 @@ function parseHeader(stream, callback) { } } ``` +Note that, unlike `stream.push(chunk)`, `stream.unshift(chunk)` will not +end the reading process by resetting the internal reading state of the +stream. This can cause unexpected results if `unshift` is called during a +read (i.e. from within a `_read` implementation on a custom stream). Following +the call to `unshift` with an immediate `stream.push('')` will reset the +reading state appropriately, however it is best to simply avoid calling +`unshift` while in the process of performing a read. #### readable.wrap(stream) @@ -897,6 +904,10 @@ SimpleProtocol.prototype._read = function(n) { // back into the read queue so that our consumer will see it. var b = chunk.slice(split); this.unshift(b); + // calling unshift by itself does not reset the reading state + // of the stream; since we're inside _read, doing an additional + // push('') will reset the state appropriately. + this.push(''); // and let them know that we are done parsing the header. this.emit('header', this.header); @@ -938,19 +949,19 @@ initialized. Note: **Implement this method, but do NOT call it directly.** -This method is prefixed with an underscore because it is internal to the -class that defines it and should only be called by the internal Readable -class methods. All Readable stream implementations must provide a _read +This method is prefixed with an underscore because it is internal to the +class that defines it and should only be called by the internal Readable +class methods. All Readable stream implementations must provide a _read method to fetch data from the underlying resource. -When _read is called, if data is available from the resource, `_read` should -start pushing that data into the read queue by calling `this.push(dataChunk)`. -`_read` should continue reading from the resource and pushing data until push -returns false, at which point it should stop reading from the resource. Only -when _read is called again after it has stopped should it start reading +When _read is called, if data is available from the resource, `_read` should +start pushing that data into the read queue by calling `this.push(dataChunk)`. +`_read` should continue reading from the resource and pushing data until push +returns false, at which point it should stop reading from the resource. Only +when _read is called again after it has stopped should it start reading more data from the resource and pushing that data onto the queue. -Note: once the `_read()` method is called, it will not be called again until +Note: once the `_read()` method is called, it will not be called again until the `push` method is called. The `size` argument is advisory. Implementations where a "read" is a @@ -970,12 +981,12 @@ becomes available. There is no need, for example to "wait" until Note: **This method should be called by Readable implementors, NOT by consumers of Readable streams.** -If a value other than null is passed, The `push()` method adds a chunk of data -into the queue for subsequent stream processors to consume. If `null` is -passed, it signals the end of the stream (EOF), after which no more data +If a value other than null is passed, The `push()` method adds a chunk of data +into the queue for subsequent stream processors to consume. If `null` is +passed, it signals the end of the stream (EOF), after which no more data can be written. -The data added with `push` can be pulled out by calling the `read()` method +The data added with `push` can be pulled out by calling the `read()` method when the `'readable'`event fires. This API is designed to be as flexible as possible. For example, From 3d6d8e95ec32a953375b315f8619fa04a8d935e6 Mon Sep 17 00:00:00 2001 From: James M Snell Date: Mon, 6 Jul 2015 11:50:17 -0700 Subject: [PATCH 15/17] doc: readable event clarification per https://github.com/joyent/node/issues/14597 Indicate that `'readable'` indicates only that data can be read from the stream, not that there is actually data to be consumed. `readable.read([size])` can still return null. Includes an example that illustrates the point. Reviewed-By: James M Snell PR-URL: https://github.com/joyent/node/pull/25591 --- doc/api/stream.markdown | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/doc/api/stream.markdown b/doc/api/stream.markdown index a18d59ea469654..e43828b3e8ef61 100644 --- a/doc/api/stream.markdown +++ b/doc/api/stream.markdown @@ -167,6 +167,32 @@ again when more data is available. The `readable` event is not emitted in the "flowing" mode with the sole exception of the last one, on end-of-stream. +Note that the `'readable'` event indicates only that data *can* be +read from the stream. It does not indicate whether there is actual +data to be consumed. The callback passed to handle the `'readable'` +event must be prepared to handle a `null` response from +`readable.read([size])`. For instance, in the following example, `foo.txt` +is an empty file: + +```javascript +var fs = require('fs'); +var rr = fs.createReadStream('foo.txt'); +rr.on('readable', function() { + console.log('readable:', rr.read()); +}); +rr.on('end', function() { + console.log('end'); +}); +``` + +The output of running this script is: + +``` +bash-3.2$ node test.js +readable: null +end +``` + #### Event: 'data' * `chunk` {Buffer | String} The chunk of data. From 2fa77364dd798590c149b6b7b07db126fc3ab2e0 Mon Sep 17 00:00:00 2001 From: James M Snell Date: Thu, 9 Jul 2015 16:35:32 -0700 Subject: [PATCH 16/17] doc: additional refinement to readable event Per https://github.com/joyent/node/pull/25635#discussion_r33973696 Additional refinement to the clarification on the `readable` event Reviewed-By: James M Snell PR-URL: https://github.com/joyent/node/pull/25591 --- doc/api/stream.markdown | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/doc/api/stream.markdown b/doc/api/stream.markdown index e43828b3e8ef61..19612edb39d014 100644 --- a/doc/api/stream.markdown +++ b/doc/api/stream.markdown @@ -167,11 +167,10 @@ again when more data is available. The `readable` event is not emitted in the "flowing" mode with the sole exception of the last one, on end-of-stream. -Note that the `'readable'` event indicates only that data *can* be -read from the stream. It does not indicate whether there is actual -data to be consumed. The callback passed to handle the `'readable'` -event must be prepared to handle a `null` response from -`readable.read([size])`. For instance, in the following example, `foo.txt` +The 'readable' event indicates that the stream has new information: +either new data is available or the end of the stream has been reached. +In the former case, `.read()` will return that data. In the latter case, +`.read()` will return null. For instance, in the following example, `foo.txt` is an empty file: ```javascript From c071d7a0d84e770ff901dafab37c1ad6217e4070 Mon Sep 17 00:00:00 2001 From: James M Snell Date: Tue, 4 Aug 2015 15:50:53 -0700 Subject: [PATCH 17/17] doc: minor edits based on feedback Additional edits based on Ben's feedback --- doc/api/fs.markdown | 4 ++-- doc/api/stream.markdown | 5 +---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/doc/api/fs.markdown b/doc/api/fs.markdown index c851d9a72b8744..ebc2046d76ac1e 100644 --- a/doc/api/fs.markdown +++ b/doc/api/fs.markdown @@ -802,8 +802,8 @@ on Unix systems, it never was. Returns a new ReadStream object (See `Readable Stream`). Be aware that, unlike the default value set for `highWaterMark` on a -readable stream(16kb), the stream returned by this method has a -default value of 64kb for the same parameter. +readable stream (16 kb), the stream returned by this method has a +default value of 64 kb for the same parameter. `options` is an object or string with the following defaults: diff --git a/doc/api/stream.markdown b/doc/api/stream.markdown index 19612edb39d014..ffad1717f75096 100644 --- a/doc/api/stream.markdown +++ b/doc/api/stream.markdown @@ -209,9 +209,6 @@ readable.on('data', function(chunk) { console.log('got %d bytes of data', chunk.length); }); ``` -Note that the `readable` event should not be used together with `data` -because the assigning the latter switches the stream into "flowing" mode, -so the `readable` event will not be emitted. #### Event: 'end' @@ -1360,7 +1357,7 @@ for examples and testing, but there are occasionally use cases where it can come in handy as a building block for novel sorts of streams. -## Simplified Constructor API +## Simplified Constructor API