workers: classify.
This commit is contained in:
parent
f313ca166d
commit
bad24a6f31
@ -10,86 +10,89 @@ const assert = require('assert');
|
|||||||
const EventEmitter = require('events');
|
const EventEmitter = require('events');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Child
|
||||||
* Represents a child process.
|
* Represents a child process.
|
||||||
* @alias module:workers.Child
|
* @alias module:workers.Child
|
||||||
* @constructor
|
* @extends EventEmitter
|
||||||
* @ignore
|
* @ignore
|
||||||
* @param {String} file
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function Child(file) {
|
class Child extends EventEmitter {
|
||||||
if (!(this instanceof Child))
|
/**
|
||||||
return new Child(file);
|
* Represents a child process.
|
||||||
|
* @constructor
|
||||||
|
* @param {String} file
|
||||||
|
*/
|
||||||
|
|
||||||
EventEmitter.call(this);
|
constructor(file) {
|
||||||
|
super();
|
||||||
|
|
||||||
this.init(file);
|
this.init(file);
|
||||||
}
|
|
||||||
|
|
||||||
Object.setPrototypeOf(Child.prototype, EventEmitter.prototype);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test whether child process support is available.
|
|
||||||
* @returns {Boolean}
|
|
||||||
*/
|
|
||||||
|
|
||||||
Child.hasSupport = function hasSupport() {
|
|
||||||
return typeof global.postMessage === 'function';
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize child process. Bind to events.
|
|
||||||
* @private
|
|
||||||
* @param {String} file
|
|
||||||
*/
|
|
||||||
|
|
||||||
Child.prototype.init = function init(file) {
|
|
||||||
this.child = new global.Worker(file);
|
|
||||||
|
|
||||||
this.child.onerror = (event) => {
|
|
||||||
this.emit('error', new Error('Child error.'));
|
|
||||||
this.emit('exit', 1, null);
|
|
||||||
};
|
|
||||||
|
|
||||||
this.child.onmessage = (event) => {
|
|
||||||
let data;
|
|
||||||
if (typeof event.data === 'string') {
|
|
||||||
data = Buffer.from(event.data, 'hex');
|
|
||||||
assert(data.length === event.data.length / 2);
|
|
||||||
} else {
|
|
||||||
assert(event.data && typeof event.data === 'object');
|
|
||||||
assert(event.data.data && typeof event.data.data.length === 'number');
|
|
||||||
data = event.data.data;
|
|
||||||
data.__proto__ = Buffer.prototype;
|
|
||||||
}
|
|
||||||
this.emit('data', data);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send data to child process.
|
|
||||||
* @param {Buffer} data
|
|
||||||
* @returns {Boolean}
|
|
||||||
*/
|
|
||||||
|
|
||||||
Child.prototype.write = function write(data) {
|
|
||||||
if (this.child.postMessage.length === 2) {
|
|
||||||
data.__proto__ = Uint8Array.prototype;
|
|
||||||
this.child.postMessage({ data }, [data]);
|
|
||||||
} else {
|
|
||||||
this.child.postMessage(data.toString('hex'));
|
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroy the child process.
|
* Test whether child process support is available.
|
||||||
*/
|
* @returns {Boolean}
|
||||||
|
*/
|
||||||
|
|
||||||
Child.prototype.destroy = function destroy() {
|
static hasSupport() {
|
||||||
this.child.terminate();
|
return typeof global.postMessage === 'function';
|
||||||
this.emit('exit', 15 | 0x80, 'SIGTERM');
|
}
|
||||||
};
|
|
||||||
|
/**
|
||||||
|
* Initialize child process. Bind to events.
|
||||||
|
* @private
|
||||||
|
* @param {String} file
|
||||||
|
*/
|
||||||
|
|
||||||
|
init(file) {
|
||||||
|
this.child = new global.Worker(file);
|
||||||
|
|
||||||
|
this.child.onerror = (event) => {
|
||||||
|
this.emit('error', new Error('Child error.'));
|
||||||
|
this.emit('exit', 1, null);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.child.onmessage = (event) => {
|
||||||
|
let data;
|
||||||
|
if (typeof event.data === 'string') {
|
||||||
|
data = Buffer.from(event.data, 'hex');
|
||||||
|
assert(data.length === event.data.length / 2);
|
||||||
|
} else {
|
||||||
|
assert(event.data && typeof event.data === 'object');
|
||||||
|
assert(event.data.data && typeof event.data.data.length === 'number');
|
||||||
|
data = event.data.data;
|
||||||
|
data.__proto__ = Buffer.prototype;
|
||||||
|
}
|
||||||
|
this.emit('data', data);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send data to child process.
|
||||||
|
* @param {Buffer} data
|
||||||
|
* @returns {Boolean}
|
||||||
|
*/
|
||||||
|
|
||||||
|
write(data) {
|
||||||
|
if (this.child.postMessage.length === 2) {
|
||||||
|
data.__proto__ = Uint8Array.prototype;
|
||||||
|
this.child.postMessage({ data }, [data]);
|
||||||
|
} else {
|
||||||
|
this.child.postMessage(data.toString('hex'));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy the child process.
|
||||||
|
*/
|
||||||
|
|
||||||
|
destroy() {
|
||||||
|
this.child.terminate();
|
||||||
|
this.emit('exit', 15 | 0x80, 'SIGTERM');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Expose
|
* Expose
|
||||||
|
|||||||
@ -14,97 +14,101 @@ const children = new Set();
|
|||||||
let exitBound = false;
|
let exitBound = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Child
|
||||||
* Represents a child process.
|
* Represents a child process.
|
||||||
* @alias module:workers.Child
|
* @alias module:workers.Child
|
||||||
* @constructor
|
* @extends EventEmitter
|
||||||
* @param {String} file
|
* @ignore
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function Child(file) {
|
class Child extends EventEmitter {
|
||||||
if (!(this instanceof Child))
|
/**
|
||||||
return new Child(file);
|
* Represents a child process.
|
||||||
|
* @constructor
|
||||||
|
* @param {String} file
|
||||||
|
*/
|
||||||
|
|
||||||
EventEmitter.call(this);
|
constructor(file) {
|
||||||
|
super();
|
||||||
|
|
||||||
bindExit();
|
bindExit();
|
||||||
children.add(this);
|
children.add(this);
|
||||||
|
|
||||||
this.init(file);
|
this.init(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test whether child process support is available.
|
||||||
|
* @returns {Boolean}
|
||||||
|
*/
|
||||||
|
|
||||||
|
static hasSupport() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize child process (node.js).
|
||||||
|
* @private
|
||||||
|
* @param {String} file
|
||||||
|
*/
|
||||||
|
|
||||||
|
init(file) {
|
||||||
|
const bin = process.argv[0];
|
||||||
|
const filename = path.resolve(__dirname, file);
|
||||||
|
const options = { stdio: 'pipe', env: process.env };
|
||||||
|
|
||||||
|
this.child = cp.spawn(bin, [filename], options);
|
||||||
|
|
||||||
|
this.child.unref();
|
||||||
|
this.child.stdin.unref();
|
||||||
|
this.child.stdout.unref();
|
||||||
|
this.child.stderr.unref();
|
||||||
|
|
||||||
|
this.child.on('error', (err) => {
|
||||||
|
this.emit('error', err);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.child.once('exit', (code, signal) => {
|
||||||
|
children.delete(this);
|
||||||
|
this.emit('exit', code == null ? -1 : code, signal);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.child.stdin.on('error', (err) => {
|
||||||
|
this.emit('error', err);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.child.stdout.on('error', (err) => {
|
||||||
|
this.emit('error', err);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.child.stderr.on('error', (err) => {
|
||||||
|
this.emit('error', err);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.child.stdout.on('data', (data) => {
|
||||||
|
this.emit('data', data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send data to child process.
|
||||||
|
* @param {Buffer} data
|
||||||
|
* @returns {Boolean}
|
||||||
|
*/
|
||||||
|
|
||||||
|
write(data) {
|
||||||
|
return this.child.stdin.write(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy the child process.
|
||||||
|
*/
|
||||||
|
|
||||||
|
destroy() {
|
||||||
|
this.child.kill('SIGTERM');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Object.setPrototypeOf(Child.prototype, EventEmitter.prototype);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test whether child process support is available.
|
|
||||||
* @returns {Boolean}
|
|
||||||
*/
|
|
||||||
|
|
||||||
Child.hasSupport = function hasSupport() {
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize child process (node.js).
|
|
||||||
* @private
|
|
||||||
* @param {String} file
|
|
||||||
*/
|
|
||||||
|
|
||||||
Child.prototype.init = function init(file) {
|
|
||||||
const bin = process.argv[0];
|
|
||||||
const filename = path.resolve(__dirname, file);
|
|
||||||
const options = { stdio: 'pipe', env: process.env };
|
|
||||||
|
|
||||||
this.child = cp.spawn(bin, [filename], options);
|
|
||||||
|
|
||||||
this.child.unref();
|
|
||||||
this.child.stdin.unref();
|
|
||||||
this.child.stdout.unref();
|
|
||||||
this.child.stderr.unref();
|
|
||||||
|
|
||||||
this.child.on('error', (err) => {
|
|
||||||
this.emit('error', err);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.child.once('exit', (code, signal) => {
|
|
||||||
children.delete(this);
|
|
||||||
this.emit('exit', code == null ? -1 : code, signal);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.child.stdin.on('error', (err) => {
|
|
||||||
this.emit('error', err);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.child.stdout.on('error', (err) => {
|
|
||||||
this.emit('error', err);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.child.stderr.on('error', (err) => {
|
|
||||||
this.emit('error', err);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.child.stdout.on('data', (data) => {
|
|
||||||
this.emit('data', data);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send data to child process.
|
|
||||||
* @param {Buffer} data
|
|
||||||
* @returns {Boolean}
|
|
||||||
*/
|
|
||||||
|
|
||||||
Child.prototype.write = function write(data) {
|
|
||||||
return this.child.stdin.write(data);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Destroy the child process.
|
|
||||||
*/
|
|
||||||
|
|
||||||
Child.prototype.destroy = function destroy() {
|
|
||||||
this.child.kill('SIGTERM');
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cleanup all child processes.
|
* Cleanup all child processes.
|
||||||
* @private
|
* @private
|
||||||
|
|||||||
@ -12,32 +12,35 @@ const bio = require('bufio');
|
|||||||
/**
|
/**
|
||||||
* Framer
|
* Framer
|
||||||
* @alias module:workers.Framer
|
* @alias module:workers.Framer
|
||||||
* @constructor
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function Framer() {
|
class Framer {
|
||||||
if (!(this instanceof Framer))
|
/**
|
||||||
return new Framer();
|
* Create a framer.
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
|
||||||
|
constructor() {}
|
||||||
|
|
||||||
|
packet(payload) {
|
||||||
|
const size = 10 + payload.getSize();
|
||||||
|
const bw = bio.write(size);
|
||||||
|
|
||||||
|
bw.writeU32(payload.id);
|
||||||
|
bw.writeU8(payload.cmd);
|
||||||
|
bw.seek(4);
|
||||||
|
|
||||||
|
payload.toWriter(bw);
|
||||||
|
|
||||||
|
bw.writeU8(0x0a);
|
||||||
|
|
||||||
|
const msg = bw.render();
|
||||||
|
msg.writeUInt32LE(msg.length - 10, 5, true);
|
||||||
|
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Framer.prototype.packet = function packet(payload) {
|
|
||||||
const size = 10 + payload.getSize();
|
|
||||||
const bw = bio.write(size);
|
|
||||||
|
|
||||||
bw.writeU32(payload.id);
|
|
||||||
bw.writeU8(payload.cmd);
|
|
||||||
bw.seek(4);
|
|
||||||
|
|
||||||
payload.toWriter(bw);
|
|
||||||
|
|
||||||
bw.writeU8(0x0a);
|
|
||||||
|
|
||||||
const msg = bw.render();
|
|
||||||
msg.writeUInt32LE(msg.length - 10, 5, true);
|
|
||||||
|
|
||||||
return msg;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Expose
|
* Expose
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -18,174 +18,177 @@ const packets = require('./packets');
|
|||||||
const Parent = require('./parent');
|
const Parent = require('./parent');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Master
|
||||||
* Represents the master process.
|
* Represents the master process.
|
||||||
* @alias module:workers.Master
|
* @alias module:workers.Master
|
||||||
* @constructor
|
* @extends EventEmitter
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function Master() {
|
class Master extends EventEmitter {
|
||||||
if (!(this instanceof Master))
|
/**
|
||||||
return new Master();
|
* Create the master process.
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
|
||||||
EventEmitter.call(this);
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
this.parent = new Parent();
|
this.parent = new Parent();
|
||||||
this.framer = new Framer();
|
this.framer = new Framer();
|
||||||
this.parser = new Parser();
|
this.parser = new Parser();
|
||||||
this.listening = false;
|
this.listening = false;
|
||||||
this.color = false;
|
this.color = false;
|
||||||
|
|
||||||
this.init();
|
this.init();
|
||||||
}
|
|
||||||
|
|
||||||
Object.setPrototypeOf(Master.prototype, EventEmitter.prototype);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize master. Bind events.
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
|
|
||||||
Master.prototype.init = function init() {
|
|
||||||
this.parent.on('data', (data) => {
|
|
||||||
this.parser.feed(data);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.parent.on('error', (err) => {
|
|
||||||
this.emit('error', err);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.parent.on('exception', (err) => {
|
|
||||||
this.send(new packets.ErrorPacket(err));
|
|
||||||
setTimeout(() => this.destroy(), 1000);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.parser.on('error', (err) => {
|
|
||||||
this.emit('error', err);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.parser.on('packet', (packet) => {
|
|
||||||
this.emit('packet', packet);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set environment.
|
|
||||||
* @param {Object} env
|
|
||||||
*/
|
|
||||||
|
|
||||||
Master.prototype.setEnv = function setEnv(env) {
|
|
||||||
this.color = env.BCOIN_WORKER_ISTTY === '1';
|
|
||||||
this.set(env.BCOIN_WORKER_NETWORK);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set primary network.
|
|
||||||
* @param {NetworkType|Network} network
|
|
||||||
*/
|
|
||||||
|
|
||||||
Master.prototype.set = function set(network) {
|
|
||||||
return Network.set(network);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send data to worker.
|
|
||||||
* @param {Buffer} data
|
|
||||||
* @returns {Boolean}
|
|
||||||
*/
|
|
||||||
|
|
||||||
Master.prototype.write = function write(data) {
|
|
||||||
return this.parent.write(data);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Frame and send a packet.
|
|
||||||
* @param {Packet} packet
|
|
||||||
* @returns {Boolean}
|
|
||||||
*/
|
|
||||||
|
|
||||||
Master.prototype.send = function send(packet) {
|
|
||||||
return this.write(this.framer.packet(packet));
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Emit an event on the worker side.
|
|
||||||
* @param {String} event
|
|
||||||
* @param {...Object} arg
|
|
||||||
* @returns {Boolean}
|
|
||||||
*/
|
|
||||||
|
|
||||||
Master.prototype.sendEvent = function sendEvent(...items) {
|
|
||||||
return this.send(new packets.EventPacket(items));
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Destroy the worker.
|
|
||||||
*/
|
|
||||||
|
|
||||||
Master.prototype.destroy = function destroy() {
|
|
||||||
return this.parent.destroy();
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Write a message to stdout in the master process.
|
|
||||||
* @param {Object|String} obj
|
|
||||||
* @param {...String} args
|
|
||||||
*/
|
|
||||||
|
|
||||||
Master.prototype.log = function log() {
|
|
||||||
const text = format.apply(null, arguments);
|
|
||||||
this.send(new packets.LogPacket(text));
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Listen for messages from master process (only if worker).
|
|
||||||
*/
|
|
||||||
|
|
||||||
Master.prototype.listen = function listen() {
|
|
||||||
assert(!this.listening, 'Already listening.');
|
|
||||||
|
|
||||||
this.listening = true;
|
|
||||||
|
|
||||||
this.on('error', (err) => {
|
|
||||||
this.send(new packets.ErrorPacket(err));
|
|
||||||
});
|
|
||||||
|
|
||||||
this.on('packet', (packet) => {
|
|
||||||
try {
|
|
||||||
this.handlePacket(packet);
|
|
||||||
} catch (e) {
|
|
||||||
this.emit('error', e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle packet.
|
|
||||||
* @private
|
|
||||||
* @param {Packet}
|
|
||||||
*/
|
|
||||||
|
|
||||||
Master.prototype.handlePacket = function handlePacket(packet) {
|
|
||||||
let result;
|
|
||||||
|
|
||||||
switch (packet.cmd) {
|
|
||||||
case packets.types.ENV:
|
|
||||||
this.setEnv(packet.env);
|
|
||||||
break;
|
|
||||||
case packets.types.EVENT:
|
|
||||||
this.emit('event', packet.items);
|
|
||||||
this.emit(...packet.items);
|
|
||||||
break;
|
|
||||||
case packets.types.ERROR:
|
|
||||||
this.emit('error', packet.error);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
result = jobs.execute(packet);
|
|
||||||
result.id = packet.id;
|
|
||||||
this.send(result);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
/**
|
||||||
|
* Initialize master. Bind events.
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
|
||||||
|
init() {
|
||||||
|
this.parent.on('data', (data) => {
|
||||||
|
this.parser.feed(data);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.parent.on('error', (err) => {
|
||||||
|
this.emit('error', err);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.parent.on('exception', (err) => {
|
||||||
|
this.send(new packets.ErrorPacket(err));
|
||||||
|
setTimeout(() => this.destroy(), 1000);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.parser.on('error', (err) => {
|
||||||
|
this.emit('error', err);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.parser.on('packet', (packet) => {
|
||||||
|
this.emit('packet', packet);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set environment.
|
||||||
|
* @param {Object} env
|
||||||
|
*/
|
||||||
|
|
||||||
|
setEnv(env) {
|
||||||
|
this.color = env.BCOIN_WORKER_ISTTY === '1';
|
||||||
|
this.set(env.BCOIN_WORKER_NETWORK);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set primary network.
|
||||||
|
* @param {NetworkType|Network} network
|
||||||
|
*/
|
||||||
|
|
||||||
|
set(network) {
|
||||||
|
return Network.set(network);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send data to worker.
|
||||||
|
* @param {Buffer} data
|
||||||
|
* @returns {Boolean}
|
||||||
|
*/
|
||||||
|
|
||||||
|
write(data) {
|
||||||
|
return this.parent.write(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Frame and send a packet.
|
||||||
|
* @param {Packet} packet
|
||||||
|
* @returns {Boolean}
|
||||||
|
*/
|
||||||
|
|
||||||
|
send(packet) {
|
||||||
|
return this.write(this.framer.packet(packet));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Emit an event on the worker side.
|
||||||
|
* @param {String} event
|
||||||
|
* @param {...Object} arg
|
||||||
|
* @returns {Boolean}
|
||||||
|
*/
|
||||||
|
|
||||||
|
sendEvent(...items) {
|
||||||
|
return this.send(new packets.EventPacket(items));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy the worker.
|
||||||
|
*/
|
||||||
|
|
||||||
|
destroy() {
|
||||||
|
return this.parent.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write a message to stdout in the master process.
|
||||||
|
* @param {Object|String} obj
|
||||||
|
* @param {...String} args
|
||||||
|
*/
|
||||||
|
|
||||||
|
log() {
|
||||||
|
const text = format.apply(null, arguments);
|
||||||
|
this.send(new packets.LogPacket(text));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listen for messages from master process (only if worker).
|
||||||
|
*/
|
||||||
|
|
||||||
|
listen() {
|
||||||
|
assert(!this.listening, 'Already listening.');
|
||||||
|
|
||||||
|
this.listening = true;
|
||||||
|
|
||||||
|
this.on('error', (err) => {
|
||||||
|
this.send(new packets.ErrorPacket(err));
|
||||||
|
});
|
||||||
|
|
||||||
|
this.on('packet', (packet) => {
|
||||||
|
try {
|
||||||
|
this.handlePacket(packet);
|
||||||
|
} catch (e) {
|
||||||
|
this.emit('error', e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle packet.
|
||||||
|
* @private
|
||||||
|
* @param {Packet}
|
||||||
|
*/
|
||||||
|
|
||||||
|
handlePacket(packet) {
|
||||||
|
let result;
|
||||||
|
|
||||||
|
switch (packet.cmd) {
|
||||||
|
case packets.types.ENV:
|
||||||
|
this.setEnv(packet.env);
|
||||||
|
break;
|
||||||
|
case packets.types.EVENT:
|
||||||
|
this.emit('event', packet.items);
|
||||||
|
this.emit(...packet.items);
|
||||||
|
break;
|
||||||
|
case packets.types.ERROR:
|
||||||
|
this.emit('error', packet.error);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
result = jobs.execute(packet);
|
||||||
|
result.id = packet.id;
|
||||||
|
this.send(result);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Expose
|
* Expose
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -10,71 +10,74 @@ const assert = require('assert');
|
|||||||
const EventEmitter = require('events');
|
const EventEmitter = require('events');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Parent
|
||||||
* Represents the parent process.
|
* Represents the parent process.
|
||||||
* @alias module:workers.Parent
|
* @alias module:workers.Parent
|
||||||
* @constructor
|
* @extends EventEmitter
|
||||||
* @ignore
|
* @ignore
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function Parent() {
|
class Parent extends EventEmitter {
|
||||||
if (!(this instanceof Parent))
|
/**
|
||||||
return new Parent();
|
* Create the parent process.
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
|
||||||
EventEmitter.call(this);
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
this.init();
|
this.init();
|
||||||
}
|
|
||||||
|
|
||||||
Object.setPrototypeOf(Parent.prototype, EventEmitter.prototype);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize master (web workers).
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
|
|
||||||
Parent.prototype.init = function init() {
|
|
||||||
global.onerror = (event) => {
|
|
||||||
this.emit('error', new Error('Worker error.'));
|
|
||||||
};
|
|
||||||
|
|
||||||
global.onmessage = (event) => {
|
|
||||||
let data;
|
|
||||||
if (typeof event.data === 'string') {
|
|
||||||
data = Buffer.from(event.data, 'hex');
|
|
||||||
assert(data.length === event.data.length / 2);
|
|
||||||
} else {
|
|
||||||
assert(event.data && typeof event.data === 'object');
|
|
||||||
assert(event.data.data && typeof event.data.data.length === 'number');
|
|
||||||
data = event.data.data;
|
|
||||||
data.__proto__ = Buffer.prototype;
|
|
||||||
}
|
|
||||||
this.emit('data', data);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send data to parent process.
|
|
||||||
* @param {Buffer} data
|
|
||||||
* @returns {Boolean}
|
|
||||||
*/
|
|
||||||
|
|
||||||
Parent.prototype.write = function write(data) {
|
|
||||||
if (global.postMessage.length === 2) {
|
|
||||||
data.__proto__ = Uint8Array.prototype;
|
|
||||||
global.postMessage({ data }, [data]);
|
|
||||||
} else {
|
|
||||||
global.postMessage(data.toString('hex'));
|
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroy the parent process.
|
* Initialize master (web workers).
|
||||||
*/
|
* @private
|
||||||
|
*/
|
||||||
|
|
||||||
Parent.prototype.destroy = function destroy() {
|
init() {
|
||||||
global.close();
|
global.onerror = (event) => {
|
||||||
};
|
this.emit('error', new Error('Worker error.'));
|
||||||
|
};
|
||||||
|
|
||||||
|
global.onmessage = (event) => {
|
||||||
|
let data;
|
||||||
|
if (typeof event.data === 'string') {
|
||||||
|
data = Buffer.from(event.data, 'hex');
|
||||||
|
assert(data.length === event.data.length / 2);
|
||||||
|
} else {
|
||||||
|
assert(event.data && typeof event.data === 'object');
|
||||||
|
assert(event.data.data && typeof event.data.data.length === 'number');
|
||||||
|
data = event.data.data;
|
||||||
|
data.__proto__ = Buffer.prototype;
|
||||||
|
}
|
||||||
|
this.emit('data', data);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send data to parent process.
|
||||||
|
* @param {Buffer} data
|
||||||
|
* @returns {Boolean}
|
||||||
|
*/
|
||||||
|
|
||||||
|
write(data) {
|
||||||
|
if (global.postMessage.length === 2) {
|
||||||
|
data.__proto__ = Uint8Array.prototype;
|
||||||
|
global.postMessage({ data }, [data]);
|
||||||
|
} else {
|
||||||
|
global.postMessage(data.toString('hex'));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy the parent process.
|
||||||
|
*/
|
||||||
|
|
||||||
|
destroy() {
|
||||||
|
global.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Expose
|
* Expose
|
||||||
|
|||||||
@ -9,60 +9,63 @@
|
|||||||
const EventEmitter = require('events');
|
const EventEmitter = require('events');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Parent
|
||||||
* Represents the parent process.
|
* Represents the parent process.
|
||||||
* @alias module:workers.Parent
|
* @alias module:workers.Parent
|
||||||
* @constructor
|
* @extends EventEmitter
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function Parent() {
|
class Parent extends EventEmitter {
|
||||||
if (!(this instanceof Parent))
|
/**
|
||||||
return new Parent();
|
* Create the parent process.
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
|
||||||
EventEmitter.call(this);
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
this.init();
|
this.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize master (node.js).
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
|
||||||
|
init() {
|
||||||
|
process.stdin.on('data', (data) => {
|
||||||
|
this.emit('data', data);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Nowhere to send these errors:
|
||||||
|
process.stdin.on('error', () => {});
|
||||||
|
process.stdout.on('error', () => {});
|
||||||
|
process.stderr.on('error', () => {});
|
||||||
|
|
||||||
|
process.on('uncaughtException', (err) => {
|
||||||
|
this.emit('exception', err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send data to parent process.
|
||||||
|
* @param {Buffer} data
|
||||||
|
* @returns {Boolean}
|
||||||
|
*/
|
||||||
|
|
||||||
|
write(data) {
|
||||||
|
return process.stdout.write(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy the parent process.
|
||||||
|
*/
|
||||||
|
|
||||||
|
destroy() {
|
||||||
|
return process.exit(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Object.setPrototypeOf(Parent.prototype, EventEmitter.prototype);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize master (node.js).
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
|
|
||||||
Parent.prototype.init = function init() {
|
|
||||||
process.stdin.on('data', (data) => {
|
|
||||||
this.emit('data', data);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Nowhere to send these errors:
|
|
||||||
process.stdin.on('error', () => {});
|
|
||||||
process.stdout.on('error', () => {});
|
|
||||||
process.stderr.on('error', () => {});
|
|
||||||
|
|
||||||
process.on('uncaughtException', (err) => {
|
|
||||||
this.emit('exception', err);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send data to parent process.
|
|
||||||
* @param {Buffer} data
|
|
||||||
* @returns {Boolean}
|
|
||||||
*/
|
|
||||||
|
|
||||||
Parent.prototype.write = function write(data) {
|
|
||||||
return process.stdout.write(data);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Destroy the parent process.
|
|
||||||
*/
|
|
||||||
|
|
||||||
Parent.prototype.destroy = function destroy() {
|
|
||||||
return process.exit(0);
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Expose
|
* Expose
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
/*!
|
/*!
|
||||||
* workers.js - worker processes for bcoin
|
* parser.js - worker parser for bcoin
|
||||||
* Copyright (c) 2014-2015, Fedor Indutny (MIT License)
|
* Copyright (c) 2014-2015, Fedor Indutny (MIT License)
|
||||||
* Copyright (c) 2014-2017, Christopher Jeffrey (MIT License).
|
* Copyright (c) 2014-2017, Christopher Jeffrey (MIT License).
|
||||||
* https://github.com/bcoin-org/bcoin
|
* https://github.com/bcoin-org/bcoin
|
||||||
@ -14,178 +14,186 @@ const packets = require('./packets');
|
|||||||
/**
|
/**
|
||||||
* Parser
|
* Parser
|
||||||
* @alias module:workers.Parser
|
* @alias module:workers.Parser
|
||||||
* @constructor
|
* @extends EventEmitter
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function Parser() {
|
class Parser extends EventEmitter {
|
||||||
if (!(this instanceof Parser))
|
/**
|
||||||
return new Parser();
|
* Create a parser.
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
|
||||||
EventEmitter.call(this);
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
this.waiting = 9;
|
this.waiting = 9;
|
||||||
this.header = null;
|
this.header = null;
|
||||||
this.pending = [];
|
this.pending = [];
|
||||||
this.total = 0;
|
this.total = 0;
|
||||||
}
|
|
||||||
|
|
||||||
Object.setPrototypeOf(Parser.prototype, EventEmitter.prototype);
|
|
||||||
|
|
||||||
Parser.prototype.feed = function feed(data) {
|
|
||||||
this.total += data.length;
|
|
||||||
this.pending.push(data);
|
|
||||||
|
|
||||||
while (this.total >= this.waiting) {
|
|
||||||
const chunk = this.read(this.waiting);
|
|
||||||
this.parse(chunk);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Parser.prototype.read = function read(size) {
|
|
||||||
assert(this.total >= size, 'Reading too much.');
|
|
||||||
|
|
||||||
if (size === 0)
|
|
||||||
return Buffer.alloc(0);
|
|
||||||
|
|
||||||
const pending = this.pending[0];
|
|
||||||
|
|
||||||
if (pending.length > size) {
|
|
||||||
const chunk = pending.slice(0, size);
|
|
||||||
this.pending[0] = pending.slice(size);
|
|
||||||
this.total -= chunk.length;
|
|
||||||
return chunk;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pending.length === size) {
|
feed(data) {
|
||||||
const chunk = this.pending.shift();
|
this.total += data.length;
|
||||||
this.total -= chunk.length;
|
this.pending.push(data);
|
||||||
return chunk;
|
|
||||||
|
while (this.total >= this.waiting) {
|
||||||
|
const chunk = this.read(this.waiting);
|
||||||
|
this.parse(chunk);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const chunk = Buffer.allocUnsafe(size);
|
read(size) {
|
||||||
let off = 0;
|
assert(this.total >= size, 'Reading too much.');
|
||||||
|
|
||||||
|
if (size === 0)
|
||||||
|
return Buffer.alloc(0);
|
||||||
|
|
||||||
while (off < chunk.length) {
|
|
||||||
const pending = this.pending[0];
|
const pending = this.pending[0];
|
||||||
const len = pending.copy(chunk, off);
|
|
||||||
if (len === pending.length)
|
if (pending.length > size) {
|
||||||
this.pending.shift();
|
const chunk = pending.slice(0, size);
|
||||||
else
|
this.pending[0] = pending.slice(size);
|
||||||
this.pending[0] = pending.slice(len);
|
this.total -= chunk.length;
|
||||||
off += len;
|
return chunk;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pending.length === size) {
|
||||||
|
const chunk = this.pending.shift();
|
||||||
|
this.total -= chunk.length;
|
||||||
|
return chunk;
|
||||||
|
}
|
||||||
|
|
||||||
|
const chunk = Buffer.allocUnsafe(size);
|
||||||
|
let off = 0;
|
||||||
|
|
||||||
|
while (off < chunk.length) {
|
||||||
|
const pending = this.pending[0];
|
||||||
|
const len = pending.copy(chunk, off);
|
||||||
|
if (len === pending.length)
|
||||||
|
this.pending.shift();
|
||||||
|
else
|
||||||
|
this.pending[0] = pending.slice(len);
|
||||||
|
off += len;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.strictEqual(off, chunk.length);
|
||||||
|
|
||||||
|
this.total -= chunk.length;
|
||||||
|
|
||||||
|
return chunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.strictEqual(off, chunk.length);
|
parse(data) {
|
||||||
|
let header = this.header;
|
||||||
|
|
||||||
this.total -= chunk.length;
|
if (!header) {
|
||||||
|
try {
|
||||||
|
header = this.parseHeader(data);
|
||||||
|
} catch (e) {
|
||||||
|
this.emit('error', e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
return chunk;
|
this.header = header;
|
||||||
};
|
this.waiting = header.size + 1;
|
||||||
|
|
||||||
Parser.prototype.parse = function parse(data) {
|
return;
|
||||||
let header = this.header;
|
}
|
||||||
|
|
||||||
if (!header) {
|
this.waiting = 9;
|
||||||
|
this.header = null;
|
||||||
|
|
||||||
|
let packet;
|
||||||
try {
|
try {
|
||||||
header = this.parseHeader(data);
|
packet = this.parsePacket(header, data);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.emit('error', e);
|
this.emit('error', e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.header = header;
|
if (data[data.length - 1] !== 0x0a) {
|
||||||
this.waiting = header.size + 1;
|
this.emit('error', new Error('No trailing newline.'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
packet.id = header.id;
|
||||||
|
|
||||||
|
this.emit('packet', packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.waiting = 9;
|
parseHeader(data) {
|
||||||
this.header = null;
|
const id = data.readUInt32LE(0, true);
|
||||||
|
const cmd = data.readUInt8(4, true);
|
||||||
let packet;
|
const size = data.readUInt32LE(5, true);
|
||||||
try {
|
return new Header(id, cmd, size);
|
||||||
packet = this.parsePacket(header, data);
|
|
||||||
} catch (e) {
|
|
||||||
this.emit('error', e);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data[data.length - 1] !== 0x0a) {
|
parsePacket(header, data) {
|
||||||
this.emit('error', new Error('No trailing newline.'));
|
switch (header.cmd) {
|
||||||
return;
|
case packets.types.ENV:
|
||||||
|
return packets.EnvPacket.fromRaw(data);
|
||||||
|
case packets.types.EVENT:
|
||||||
|
return packets.EventPacket.fromRaw(data);
|
||||||
|
case packets.types.LOG:
|
||||||
|
return packets.LogPacket.fromRaw(data);
|
||||||
|
case packets.types.ERROR:
|
||||||
|
return packets.ErrorPacket.fromRaw(data);
|
||||||
|
case packets.types.ERRORRESULT:
|
||||||
|
return packets.ErrorResultPacket.fromRaw(data);
|
||||||
|
case packets.types.CHECK:
|
||||||
|
return packets.CheckPacket.fromRaw(data);
|
||||||
|
case packets.types.CHECKRESULT:
|
||||||
|
return packets.CheckResultPacket.fromRaw(data);
|
||||||
|
case packets.types.SIGN:
|
||||||
|
return packets.SignPacket.fromRaw(data);
|
||||||
|
case packets.types.SIGNRESULT:
|
||||||
|
return packets.SignResultPacket.fromRaw(data);
|
||||||
|
case packets.types.CHECKINPUT:
|
||||||
|
return packets.CheckInputPacket.fromRaw(data);
|
||||||
|
case packets.types.CHECKINPUTRESULT:
|
||||||
|
return packets.CheckInputResultPacket.fromRaw(data);
|
||||||
|
case packets.types.SIGNINPUT:
|
||||||
|
return packets.SignInputPacket.fromRaw(data);
|
||||||
|
case packets.types.SIGNINPUTRESULT:
|
||||||
|
return packets.SignInputResultPacket.fromRaw(data);
|
||||||
|
case packets.types.ECVERIFY:
|
||||||
|
return packets.ECVerifyPacket.fromRaw(data);
|
||||||
|
case packets.types.ECVERIFYRESULT:
|
||||||
|
return packets.ECVerifyResultPacket.fromRaw(data);
|
||||||
|
case packets.types.ECSIGN:
|
||||||
|
return packets.ECSignPacket.fromRaw(data);
|
||||||
|
case packets.types.ECSIGNRESULT:
|
||||||
|
return packets.ECSignResultPacket.fromRaw(data);
|
||||||
|
case packets.types.MINE:
|
||||||
|
return packets.MinePacket.fromRaw(data);
|
||||||
|
case packets.types.MINERESULT:
|
||||||
|
return packets.MineResultPacket.fromRaw(data);
|
||||||
|
case packets.types.SCRYPT:
|
||||||
|
return packets.ScryptPacket.fromRaw(data);
|
||||||
|
case packets.types.SCRYPTRESULT:
|
||||||
|
return packets.ScryptResultPacket.fromRaw(data);
|
||||||
|
default:
|
||||||
|
throw new Error('Unknown packet.');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
packet.id = header.id;
|
|
||||||
|
|
||||||
this.emit('packet', packet);
|
|
||||||
};
|
|
||||||
|
|
||||||
Parser.prototype.parseHeader = function parseHeader(data) {
|
|
||||||
const id = data.readUInt32LE(0, true);
|
|
||||||
const cmd = data.readUInt8(4, true);
|
|
||||||
const size = data.readUInt32LE(5, true);
|
|
||||||
return new Header(id, cmd, size);
|
|
||||||
};
|
|
||||||
|
|
||||||
Parser.prototype.parsePacket = function parsePacket(header, data) {
|
|
||||||
switch (header.cmd) {
|
|
||||||
case packets.types.ENV:
|
|
||||||
return packets.EnvPacket.fromRaw(data);
|
|
||||||
case packets.types.EVENT:
|
|
||||||
return packets.EventPacket.fromRaw(data);
|
|
||||||
case packets.types.LOG:
|
|
||||||
return packets.LogPacket.fromRaw(data);
|
|
||||||
case packets.types.ERROR:
|
|
||||||
return packets.ErrorPacket.fromRaw(data);
|
|
||||||
case packets.types.ERRORRESULT:
|
|
||||||
return packets.ErrorResultPacket.fromRaw(data);
|
|
||||||
case packets.types.CHECK:
|
|
||||||
return packets.CheckPacket.fromRaw(data);
|
|
||||||
case packets.types.CHECKRESULT:
|
|
||||||
return packets.CheckResultPacket.fromRaw(data);
|
|
||||||
case packets.types.SIGN:
|
|
||||||
return packets.SignPacket.fromRaw(data);
|
|
||||||
case packets.types.SIGNRESULT:
|
|
||||||
return packets.SignResultPacket.fromRaw(data);
|
|
||||||
case packets.types.CHECKINPUT:
|
|
||||||
return packets.CheckInputPacket.fromRaw(data);
|
|
||||||
case packets.types.CHECKINPUTRESULT:
|
|
||||||
return packets.CheckInputResultPacket.fromRaw(data);
|
|
||||||
case packets.types.SIGNINPUT:
|
|
||||||
return packets.SignInputPacket.fromRaw(data);
|
|
||||||
case packets.types.SIGNINPUTRESULT:
|
|
||||||
return packets.SignInputResultPacket.fromRaw(data);
|
|
||||||
case packets.types.ECVERIFY:
|
|
||||||
return packets.ECVerifyPacket.fromRaw(data);
|
|
||||||
case packets.types.ECVERIFYRESULT:
|
|
||||||
return packets.ECVerifyResultPacket.fromRaw(data);
|
|
||||||
case packets.types.ECSIGN:
|
|
||||||
return packets.ECSignPacket.fromRaw(data);
|
|
||||||
case packets.types.ECSIGNRESULT:
|
|
||||||
return packets.ECSignResultPacket.fromRaw(data);
|
|
||||||
case packets.types.MINE:
|
|
||||||
return packets.MinePacket.fromRaw(data);
|
|
||||||
case packets.types.MINERESULT:
|
|
||||||
return packets.MineResultPacket.fromRaw(data);
|
|
||||||
case packets.types.SCRYPT:
|
|
||||||
return packets.ScryptPacket.fromRaw(data);
|
|
||||||
case packets.types.SCRYPTRESULT:
|
|
||||||
return packets.ScryptResultPacket.fromRaw(data);
|
|
||||||
default:
|
|
||||||
throw new Error('Unknown packet.');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Header
|
* Header
|
||||||
* @constructor
|
|
||||||
* @ignore
|
* @ignore
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function Header(id, cmd, size) {
|
class Header {
|
||||||
this.id = id;
|
/**
|
||||||
this.cmd = cmd;
|
* Create a header.
|
||||||
this.size = size;
|
* @constructor
|
||||||
|
*/
|
||||||
|
|
||||||
|
constructor(id, cmd, size) {
|
||||||
|
this.id = id;
|
||||||
|
this.cmd = cmd;
|
||||||
|
this.size = size;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user