Browse Source

Add socket.bufferSize

v0.7.4-release
Ryan Dahl 14 years ago
parent
commit
6ede26cb9c
  1. 19
      doc/api/net.markdown
  2. 19
      lib/net.js
  3. 5
      test/pummel/test-net-throttle.js
  4. 5
      test/simple/test-net-pingpong.js

19
doc/api/net.markdown

@ -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

@ -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;

5
test/pummel/test-net-throttle.js

@ -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();
});
});

5
test/simple/test-net-pingpong.js

@ -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…
Cancel
Save