102 lines
2.6 KiB
JavaScript
102 lines
2.6 KiB
JavaScript
var spdy = require('../spdy');
|
|
var utils = spdy.utils;
|
|
var scheduler = exports;
|
|
|
|
//
|
|
// ### function Scheduler (connection)
|
|
// #### @connection {spdy.Connection} active connection
|
|
// Connection's streams scheduler
|
|
//
|
|
function Scheduler(connection) {
|
|
this.connection = connection;
|
|
this.priorities = [[], [], [], [], [], [], [], []];
|
|
this._tickListener = this._tickListener.bind(this);
|
|
this._tickListening = false;
|
|
this._tickCallbacks = [];
|
|
this._corked = false;
|
|
}
|
|
|
|
//
|
|
// ### function create (connection)
|
|
// #### @connection {spdy.Connection} active connection
|
|
//
|
|
exports.create = function create(connection) {
|
|
return new Scheduler(connection);
|
|
};
|
|
|
|
//
|
|
// ### function schedule (stream, data)
|
|
// #### @stream {spdy.Stream} Source stream
|
|
// #### @data {Buffer} data to write on tick
|
|
// Use stream priority to invoke callbacks in right order
|
|
//
|
|
Scheduler.prototype.schedule = function schedule(stream, data) {
|
|
// Ignore data from destroyed stream
|
|
if (stream._spdyState.destroyed)
|
|
return;
|
|
this.scheduleLast(stream, data);
|
|
};
|
|
|
|
//
|
|
// ### function scheduleLast (stream, data)
|
|
// #### @stream {spdy.Stream} Source stream
|
|
// #### @data {Buffer} data to write on tick
|
|
// Use stream priority to invoke callbacks in right order
|
|
//
|
|
Scheduler.prototype.scheduleLast = function scheduleLast(stream, data) {
|
|
var priority = stream._spdyState.priority;
|
|
priority = Math.min(priority, 7);
|
|
priority = Math.max(priority, 0);
|
|
this.priorities[priority].push(data);
|
|
};
|
|
|
|
//
|
|
// ### function tickListener ()
|
|
//
|
|
Scheduler.prototype._tickListener = function tickListener() {
|
|
var priorities = this.priorities;
|
|
var tickCallbacks = this._tickCallbacks;
|
|
|
|
this._tickListening = false;
|
|
this.priorities = [[], [], [], [], [], [], [], []];
|
|
this._tickCallbacks = [];
|
|
|
|
// Run all priorities
|
|
for (var i = 0; i < 8; i++)
|
|
for (var j = 0; j < priorities[i].length; j++)
|
|
this.connection.write(priorities[i][j]);
|
|
|
|
// Invoke callbacks
|
|
for (var i = 0; i < tickCallbacks.length; i++)
|
|
tickCallbacks[i]();
|
|
if (this._corked) {
|
|
this.connection.uncork();
|
|
if (this._tickListening)
|
|
this.connection.cork();
|
|
else
|
|
this._corked = false;
|
|
}
|
|
};
|
|
|
|
//
|
|
// ### function tick ()
|
|
// Add .nextTick callback if not already present
|
|
//
|
|
Scheduler.prototype.tick = function tick(cb) {
|
|
if (cb)
|
|
this._tickCallbacks.push(cb);
|
|
if (this._tickListening)
|
|
return;
|
|
this._tickListening = true;
|
|
|
|
if (!this._corked) {
|
|
this.connection.cork();
|
|
this._corked = true;
|
|
}
|
|
if (!this.connection._spdyState.parser.needDrain) {
|
|
utils.nextTick(this._tickListener);
|
|
} else {
|
|
this.connection._spdyState.parser.once('drain', this._tickListener);
|
|
}
|
|
};
|