Add socket.bufferSize
This commit is contained in:
parent
845df3cd2e
commit
6ede26cb9c
@ -174,6 +174,25 @@ The `callback` paramenter will be added as an listener for the 'connect'
|
||||
event.
|
||||
|
||||
|
||||
#### socket.bufferSize
|
||||
|
||||
`net.Socket` has the property that `socket.write()` always works. This is to
|
||||
help users get up an running quickly. The computer cannot necessarily keep up
|
||||
with the amount of data that is written to a socket - the network connection simply
|
||||
might be too slow. Node will internally queue up the data written to a socket and
|
||||
send it out over the wire when it is possible. (Internally it is polling on
|
||||
the socket's file descriptor for being writable).
|
||||
|
||||
The consequence of this internal buffering is that memory may grow. This
|
||||
property shows the number of characters currently buffered to be written.
|
||||
(Number of characters is approximately equal to the number of bytes to be
|
||||
written, but the buffer may contain strings, and the strings are lazily
|
||||
encoded, so the exact number of bytes is not known.)
|
||||
|
||||
Users who experience large or growing `bufferSize` should attempt to
|
||||
"throttle" the data flows in their program with `pause()` and resume()`.
|
||||
|
||||
|
||||
#### socket.setEncoding(encoding=null)
|
||||
|
||||
Sets the encoding (either `'ascii'`, `'utf8'`, or `'base64'`) for data that is
|
||||
|
19
lib/net.js
19
lib/net.js
@ -179,6 +179,8 @@ function initSocket(self) {
|
||||
self._writeQueueEncoding = [];
|
||||
self._writeQueueFD = [];
|
||||
self._writeQueueCallbacks = [];
|
||||
// Number of charactes (which approx. equals number of bytes)
|
||||
self.bufferSize = 0;
|
||||
|
||||
self._writeWatcher = ioWatchers.alloc();
|
||||
self._writeWatcher.socket = self;
|
||||
@ -192,6 +194,7 @@ function Socket(options) {
|
||||
if (!(this instanceof Socket)) return new Socket(arguments[0], arguments[1]);
|
||||
stream.Stream.call(this);
|
||||
|
||||
this.bufferSize = 0;
|
||||
this.fd = null;
|
||||
this.type = null;
|
||||
this.allowHalfOpen = false;
|
||||
@ -270,6 +273,8 @@ Object.defineProperty(Socket.prototype, 'readyState', {
|
||||
Socket.prototype.write = function(data /* [encoding], [fd], [cb] */) {
|
||||
var encoding, fd, cb;
|
||||
|
||||
assert(this.bufferSize >= 0);
|
||||
|
||||
// parse arguments
|
||||
if (typeof arguments[1] == 'string') {
|
||||
encoding = arguments[1];
|
||||
@ -296,6 +301,7 @@ Socket.prototype.write = function(data /* [encoding], [fd], [cb] */) {
|
||||
|
||||
if (this._connecting || (this._writeQueue && this._writeQueue.length)) {
|
||||
if (!this._writeQueue) {
|
||||
this.bufferSize = 0;
|
||||
this._writeQueue = [];
|
||||
this._writeQueueEncoding = [];
|
||||
this._writeQueueFD = [];
|
||||
@ -309,6 +315,8 @@ Socket.prototype.write = function(data /* [encoding], [fd], [cb] */) {
|
||||
|
||||
var last = this._writeQueue.length - 1;
|
||||
|
||||
this.bufferSize += data.length;
|
||||
|
||||
if (typeof data == 'string' &&
|
||||
this._writeQueue.length &&
|
||||
typeof this._writeQueue[last] === 'string' &&
|
||||
@ -403,6 +411,8 @@ Socket.prototype._writeOut = function(data, encoding, fd, cb) {
|
||||
// (data.length - charsWritten) +
|
||||
// ' bytes into the pool\n');
|
||||
// Unshift whatever didn't fit onto the buffer
|
||||
assert(data.length > charsWritten);
|
||||
this.bufferSize += data.length - charsWritten;
|
||||
this._writeQueue.unshift(data.slice(charsWritten));
|
||||
this._writeQueueEncoding.unshift(encoding);
|
||||
this._writeQueueCallbacks.unshift(cb);
|
||||
@ -451,6 +461,7 @@ Socket.prototype._writeOut = function(data, encoding, fd, cb) {
|
||||
//if (!this._writeQueue) initWriteSocket(this);
|
||||
|
||||
// data should be the next thing to write.
|
||||
this.bufferSize += leftOver.length;
|
||||
this._writeQueue.unshift(leftOver);
|
||||
this._writeQueueEncoding.unshift(null);
|
||||
this._writeQueueCallbacks.unshift(cb);
|
||||
@ -478,6 +489,9 @@ Socket.prototype.flush = function() {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Only decrement if it's not the END_OF_FILE object...
|
||||
this.bufferSize -= data.length;
|
||||
|
||||
var flushed = this._writeOut(data, encoding, fd, cb);
|
||||
if (!flushed) return false;
|
||||
}
|
||||
@ -731,7 +745,12 @@ Socket.prototype.destroy = function(exception) {
|
||||
|
||||
// TODO would like to set _writeQueue to null to avoid extra object alloc,
|
||||
// but lots of code assumes this._writeQueue is always an array.
|
||||
assert(this.bufferSize >= 0);
|
||||
this._writeQueue = [];
|
||||
this._writeQueueEncoding = [];
|
||||
this._writeQueueCallbacks = [];
|
||||
this._writeQueueFD = [];
|
||||
this.bufferSize = 0;
|
||||
|
||||
this.readable = this.writable = false;
|
||||
|
||||
|
@ -2,7 +2,7 @@ var common = require('../common');
|
||||
var assert = require('assert');
|
||||
var net = require('net');
|
||||
|
||||
var N = 160 * 1024; // 30kb
|
||||
var N = 160 * 1024;
|
||||
var chars_recved = 0;
|
||||
var npauses = 0;
|
||||
|
||||
@ -17,6 +17,9 @@ console.log('start server on port ' + common.PORT);
|
||||
var server = net.createServer(function(connection) {
|
||||
connection.addListener('connect', function() {
|
||||
assert.equal(false, connection.write(body));
|
||||
console.log('bufferSize: ' + connection.bufferSize);
|
||||
assert.ok(0 <= connection.bufferSize &&
|
||||
connection.bufferSize <= N);
|
||||
connection.end();
|
||||
});
|
||||
});
|
||||
|
@ -21,6 +21,11 @@ function pingPongTest(port, host) {
|
||||
|
||||
socket.setEncoding('utf8');
|
||||
socket.addListener('data', function(data) {
|
||||
// Since we never queue data (we're always waiting for the PING
|
||||
// before sending a pong) the writeQueueSize should always be less
|
||||
// than one message.
|
||||
assert.ok(0 <= socket.bufferSize && socket.bufferSize <= 4);
|
||||
|
||||
console.log('server got: ' + data);
|
||||
assert.equal(true, socket.writable);
|
||||
assert.equal(true, socket.readable);
|
||||
|
Loading…
x
Reference in New Issue
Block a user