@andersbakken/fisk 3.5.6 → 3.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/daemon/client.js DELETED
@@ -1,100 +0,0 @@
1
- const EventEmitter = require("events");
2
- const WebSocket = require("ws");
3
- const os = require('os');
4
- const path = require('path');
5
- const fs = require('fs');
6
-
7
- class Client extends EventEmitter {
8
- constructor(option, configVersion) {
9
- super();
10
-
11
- this.configVersion = configVersion;
12
- this.scheduler = option("scheduler", "ws://localhost:8097");
13
- if (this.scheduler.indexOf('://') == -1)
14
- this.scheduler = "ws://" + this.scheduler;
15
- if (!/:[0-9]+$/.exec(this.scheduler))
16
- this.scheduler += ":8097";
17
- this.hostname = option("hostname");
18
- this.name = option("name");
19
- try {
20
- this.npmVersion = JSON.parse(fs.readFileSync(path.join(__dirname, "../package.json"))).version;
21
- } catch (err) {
22
- }
23
- console.log("this is our npm version", this.npmVersion);
24
- if (!this.name) {
25
- if (this.hostname) {
26
- this.name = this.hostname;
27
- } else {
28
- this.name = os.hostname();
29
- }
30
- }
31
- }
32
-
33
- connect() {
34
- const url = `${this.scheduler}/daemon`;
35
- console.log("connecting to", url);
36
-
37
- let headers = {
38
- "x-fisk-port": this.serverPort,
39
- "x-fisk-config-version": this.configVersion,
40
- "x-fisk-daemon-name": this.name,
41
- "x-fisk-npm-version": this.npmVersion
42
- };
43
- if (this.hostname)
44
- headers["x-fisk-builder-hostname"] = this.hostname;
45
-
46
- this.ws = new WebSocket(url, { headers: headers });
47
- this.ws.on("open", () => {
48
- this.emit("connect");
49
- });
50
- this.ws.on("error", err => {
51
- console.error("client websocket error", err.message);
52
- });
53
- this.ws.on("message", msg => {
54
- const error = msg => {
55
- this.ws.send(`{"error": "${msg}"}`);
56
- this.ws.close();
57
- this.emit("error", msg);
58
- };
59
- console.log("Got message from scheduler", msg);
60
- });
61
- this.ws.on("close", () => {
62
- this.emit("close");
63
- if (this.ws)
64
- this.ws.removeAllListeners();
65
- this.ws = undefined;
66
- });
67
- }
68
-
69
- sendBinary(blob) {
70
- try {
71
- this.ws.send(blob);
72
- } catch (err) {
73
- this.emit("err", err.toString());
74
- }
75
- }
76
- send(type, msg) {
77
- if (!this.ws) {
78
- this.emit("error", "No connected websocket");
79
- return;
80
- }
81
- try {
82
- if (msg === undefined) {
83
- this.ws.send(JSON.stringify(type));
84
- } else {
85
- let tosend;
86
- if (typeof msg === "object") {
87
- tosend = msg;
88
- tosend.type = type;
89
- } else {
90
- tosend = { type: type, message: msg };
91
- }
92
- this.ws.send(JSON.stringify(tosend));
93
- }
94
- } catch (err) {
95
- this.emit("err", err.toString());
96
- }
97
- }
98
- }
99
-
100
- module.exports = Client;
@@ -1,73 +0,0 @@
1
- class ClientBuffer
2
- {
3
- constructor()
4
- {
5
- this.buffers = [];
6
- this.offset = 0;
7
- }
8
-
9
- write(buffer)
10
- {
11
- this.buffers.push(buffer);
12
- // console.log("write", buffer.length, this.buffers.length, this.available);
13
- }
14
-
15
- peek()
16
- {
17
- if (!this.available)
18
- throw new Error("No data available");
19
- return this.buffers[0][this.offset];
20
- }
21
-
22
- read(len)
23
- {
24
- if (!len)
25
- throw new Error("Don't be a tool");
26
- if (len > this.available)
27
- throw new Error("We don't have this many bytes available " + len + ">" + this.available);
28
-
29
- // console.log("read", len, this.available);
30
- let ret;
31
-
32
- if (this.buffers[0].length - this.offset >= len) { // buffers[0] is enough
33
- let buf = this.buffers[0];
34
- if (buf.length - this.offset == len) {
35
- ret = this.offset ? buf.slice(this.offset) : buf;
36
- this.offset = 0;
37
- this.buffers.splice(0, 1);
38
- return ret;
39
- }
40
- ret = buf.slice(this.offset, this.offset + len);
41
- this.offset += len;
42
- return ret;
43
- }
44
-
45
- ret = Buffer.allocUnsafe(len);
46
- let retOffset = 0;
47
- this.buffers[0].copy(ret, 0, this.offset);
48
- retOffset += this.buffers[0].length - this.offset;
49
- this.offset = 0;
50
- this.buffers.splice(0, 1);
51
- while (retOffset < len) {
52
- const needed = len - retOffset;
53
- let buf = this.buffers[0];
54
- if (buf.length <= needed) {
55
- this.buffers[0].copy(ret, retOffset);
56
- retOffset += this.buffers[0].length;
57
- this.buffers.splice(0, 1);
58
- } else {
59
- this.buffers[0].copy(ret, retOffset, 0, needed);
60
- retOffset += needed;
61
- this.offset = needed;
62
- }
63
- }
64
- return ret;
65
- }
66
-
67
- get available()
68
- {
69
- return this.buffers.reduce((total, buf) => total + buf.length, 0) - this.offset;
70
- }
71
- };
72
-
73
- module.exports = ClientBuffer;
package/daemon/compile.js DELETED
@@ -1,140 +0,0 @@
1
- const EventEmitter = require('events');
2
- const ClientBuffer = require('./clientbuffer');
3
- const Constants = require('./constants');
4
-
5
- class Compile extends EventEmitter
6
- {
7
- constructor(conn, id, option)
8
- {
9
- super();
10
- this.debug = option("debug");
11
- this.id = id;
12
- this.connection = conn;
13
- this.buffer = new ClientBuffer;
14
- this.messageLength = 0;
15
- this.pid = undefined;
16
-
17
- this.connection.on('data', this._onData.bind(this));
18
- this.connection.on('end', () => {
19
- // console.log("connection ended", id);
20
- this.emit('end');
21
- });
22
- this.connection.on('error', err => {
23
- // console.log("connection error", id, err);
24
- this.emit('error', err);
25
- });
26
- }
27
-
28
- send(message)
29
- {
30
- if (this.debug)
31
- console.log("Compile::send", message);
32
-
33
- try {
34
- if (typeof message === 'number') {
35
- this.connection.write(Buffer.from([message]));
36
- } else {
37
- let msg = Buffer.from(JSON.stringify(message), "utf8");
38
- let header = Buffer.allocUnsafe(5);
39
- header.writeUInt8(Constants.JSONResponse, 0);
40
- header.writeUInt32BE(msg.length, 1);
41
- if (this.debug) {
42
- console.log("Compile::send header", header, Constants.JSONResponse);
43
- }
44
- this.connection.write(header);
45
- this.connection.write(msg);
46
- }
47
- } catch (err) {
48
- console.error("Got error sending message", err);
49
- }
50
- }
51
-
52
- _onData(data)
53
- {
54
-
55
- // console.log("got data", data.length);
56
- this.buffer.write(data);
57
- let available = this.buffer.available;
58
- if (this.debug)
59
- console.log("Compile::_onData", "id", this.id, "pid", this.pid,
60
- data, "available", available, this.messageLength);
61
-
62
- if (!this.pid) {
63
- if (available < 4)
64
- return;
65
-
66
- let pidBuffer = this.buffer.read(4);
67
- available -= 4;
68
- this.pid = pidBuffer.readUInt32BE();
69
- if (this.debug)
70
- console.log("Compile::_onData got pid", "id", this.id, "pid", this.pid);
71
- }
72
-
73
- let emit = type => {
74
- if (this.debug)
75
- console.log("Compile::_onData::emit", type, available);
76
-
77
- let read = this.buffer.read(1);
78
- if (this.debug) {
79
- console.log("Discarded", read);
80
- }
81
- --available;
82
- this.emit(type);
83
- };
84
-
85
- while (available) {
86
- if (!this.messageLength) {
87
- if (this.debug)
88
- console.log("peeking", this.buffer.peek());
89
-
90
- switch (this.buffer.peek()) {
91
- case Constants.AcquireCppSlot:
92
- emit('acquireCppSlot');
93
- continue;
94
- case Constants.AcquireCompileSlot:
95
- emit('acquireCompileSlot');
96
- continue;
97
- case Constants.ReleaseCppSlot:
98
- emit('releaseCppSlot');
99
- continue;
100
- case Constants.ReleaseCompileSlot:
101
- emit('releaseCompileSlot');
102
- continue;
103
- case Constants.JSON:
104
- if (available < 5)
105
- break;
106
- this.buffer.read(1);
107
- this.messageLength = this.buffer.read(4).readUInt32BE();
108
- available -= 5;
109
- break;
110
- default:
111
- console.error("Bad data", this.buffer.peek(), "available", available);
112
- throw new Error("Got unexpected type " + this.buffer.peek());
113
- }
114
- }
115
-
116
- if (!this.messageLength || this.messageLength > available) {
117
- // console.log("Still waiting on data", this.messageLength, this.buffer.available);
118
- break;
119
- }
120
-
121
- let raw = this.buffer.read(this.messageLength);
122
- available -= this.messageLength;
123
- this.messageLength = 0;
124
-
125
- try {
126
- let msg = JSON.parse(raw.toString('utf8'));
127
- if (this.debug)
128
- console.log("Got json message", msg);
129
- // console.log("Got message", msg);
130
- this.emit(msg.type, msg);
131
- } catch (err) {
132
- console.error("Bad JSON received", err);
133
- this.connection.destroy();
134
- break;
135
- }
136
- }
137
- }
138
- }
139
-
140
- module.exports = Compile;
@@ -1,13 +0,0 @@
1
- module.exports = {
2
- // client codes
3
- get AcquireCppSlot() { return 1; },
4
- get AcquireCompileSlot() { return 2; },
5
- get ReleaseCppSlot() { return 3; },
6
- get ReleaseCompileSlot() { return 4; },
7
- get JSON() { return 5; },
8
-
9
- // daemon codes
10
- get CppSlotAcquired() { return 10; },
11
- get CompileSlotAcquired() { return 11; },
12
- get JSONResponse() { return 12; }
13
- };
@@ -1,166 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- const option = require('@jhanssen/options')({ prefix: 'fisk/daemon',
4
- applicationPath: false,
5
- additionalFiles: [ "fisk/daemon.conf.override" ] });
6
- const ws = require('ws');
7
- const os = require('os');
8
- const assert = require('assert');
9
- const common = require('../common')(option);
10
- const Server = require('./server');
11
- const Slots = require('./slots');
12
- const Constants = require('./constants');
13
-
14
- const debug = option('debug');
15
-
16
- process.on('unhandledRejection', (reason, p) => {
17
- console.log('Unhandled Rejection at: Promise', p, 'reason:', reason.stack);
18
- process.exit();
19
- // if (client)
20
- // client.send('log', { message: `Unhandled Rejection at: Promise ${p}, reason: ${reason.stack}` });
21
-
22
- });
23
-
24
- process.on('uncaughtException', err => {
25
- console.error('Uncaught exception', err);
26
- process.exit();
27
- // if (client)
28
- // client.send('log', { message: `Uncaught exception ${err.toString()} ${err.stack}` });
29
- });
30
-
31
- const server = new Server(option, common);
32
- server.listen().then(() => {
33
- console.log('listening on', server.file);
34
- });
35
-
36
- // server.on("message
37
-
38
- server.on('error', (err) => {
39
- console.error('server error', err);
40
- });
41
-
42
- const cppSlots = new Slots(option.int('cpp-slots', Math.max(os.cpus().length * 2, 1)), 'cpp', debug);
43
- const compileSlots = new Slots(option.int('slots', Math.max(os.cpus().length, 1)), 'compile', debug);
44
-
45
- server.on('compile', compile => {
46
- compile.on("dumpSlots", () => {
47
- let ret = { cpp: cppSlots.dump(), compile: compileSlots.dump() };
48
- if (debug)
49
- console.log("sending dump", ret);
50
-
51
- compile.send(ret);
52
- });
53
- let requestedCppSlot = false;
54
- compile.on('acquireCppSlot', () => {
55
- if (debug)
56
- console.log('acquireCppSlot');
57
-
58
- assert(!requestedCppSlot);
59
- requestedCppSlot = true;
60
- cppSlots.acquire(compile.id, {pid: compile.pid}, () => {
61
- // compile.send({ type: 'cppSlotAcquired' });
62
- compile.send(Constants.CppSlotAcquired);
63
- });
64
- });
65
-
66
- compile.on('releaseCppSlot', () => {
67
- if (debug)
68
- console.log('releaseCppSlot');
69
-
70
- assert(requestedCppSlot);
71
- if (requestedCppSlot) {
72
- requestedCppSlot = false;
73
- cppSlots.release(compile.id);
74
- }
75
- });
76
-
77
- let requestedCompileSlot = false;
78
- compile.on('acquireCompileSlot', () => {
79
- if (debug)
80
- console.log('acquireCompileSlot');
81
-
82
- assert(!requestedCompileSlot);
83
- requestedCompileSlot = true;
84
- compileSlots.acquire(compile.id, {pid: compile.pid}, () => {
85
- // compile.send({ type: 'compileSlotAcquired' });
86
- compile.send(Constants.CompileSlotAcquired);
87
- });
88
- });
89
-
90
- compile.on('releaseCompileSlot', () => {
91
- if (debug)
92
- console.log('releaseCompileSlot');
93
-
94
- assert(requestedCompileSlot);
95
- if (requestedCompileSlot) {
96
- requestedCompileSlot = false;
97
- compileSlots.release(compile.id);
98
- }
99
- });
100
-
101
- compile.on('error', err => {
102
- if (debug)
103
- console.error('Got error from fiskc', compile.id, compile.pid, err);
104
- if (requestedCppSlot) {
105
- requestedCppSlot = false;
106
- cppSlots.release(compile.id);
107
- }
108
- if (requestedCompileSlot) {
109
- requestedCompileSlot = false;
110
- compileSlots.release(compile.id);
111
- }
112
- });
113
-
114
- compile.on('end', () => {
115
- if (debug)
116
- console.log("got end from", compile.id, compile.pid);
117
- if (requestedCppSlot) {
118
- requestedCppSlot = false;
119
- cppSlots.release(compile.id);
120
- }
121
- if (requestedCompileSlot) {
122
- requestedCompileSlot = false;
123
- compileSlots.release(compile.id);
124
- }
125
- });
126
- });
127
-
128
- process.on('exit', () => {
129
- server.close();
130
- });
131
-
132
- process.on('SIGINT', sig => {
133
- server.close();
134
- process.exit();
135
- });
136
-
137
- /*
138
- const client = new Client(option, common.Version);
139
-
140
- let connectInterval;
141
- client.on('quit', message => {
142
- process.exit(message.code);
143
- });
144
-
145
- client.on('connect', () => {
146
- console.log('connected');
147
- if (connectInterval) {
148
- clearInterval(connectInterval);
149
- connectInterval = undefined;
150
- }
151
- });
152
-
153
- client.on('error', err => {
154
- console.error('client error', err);
155
- });
156
-
157
- client.on('close', () => {
158
- console.log('client closed');
159
- if (!connectInterval) {
160
- connectInterval = setInterval(() => {
161
- console.log('Reconnecting...');
162
- client.connect();
163
- }, 1000);
164
- }
165
- });
166
- */
package/daemon/server.js DELETED
@@ -1,81 +0,0 @@
1
- const net = require('net');
2
- const path = require('path');
3
- const EventEmitter = require('events');
4
- const fs = require('fs-extra');
5
- const ClientBuffer = require('./clientbuffer');
6
- const Compile = require('./compile');
7
-
8
- class Server extends EventEmitter
9
- {
10
- constructor(option, common)
11
- {
12
- super();
13
- this.debug = option("debug");
14
- this.file = option("socket", path.join(common.cacheDir(option), "socket"));
15
- this.server = undefined;
16
- this.option = option;
17
- this._connections = {};
18
- this._connectionId = 0;
19
- }
20
-
21
- close()
22
- {
23
- if (this.debug)
24
- console.log("Server::close");
25
- if (this.server)
26
- this.server.close();
27
- try {
28
- fs.unlinkSync(this.file);
29
- } catch (err) {
30
- }
31
- }
32
-
33
- listen()
34
- {
35
- try {
36
- fs.unlinkSync(this.file); // this should be more
37
- // complicated with attempts to
38
- // cleanly shut down and whatnot
39
- } catch (err) {
40
- }
41
- return new Promise((resolve, reject) => {
42
- let connected = false;
43
- this.server = net.createServer(this._onConnection.bind(this)).listen(this.file, () => {
44
- fs.chmodSync(this.file, '777');
45
- connected = true;
46
- resolve();
47
- });
48
- this.server.on('error', err => {
49
- if (!connected) {
50
- console.error("Got server error", err);
51
- setTimeout(this.listen.bind(this), 1000);
52
- }
53
- });
54
-
55
- this.server.on('close', () => {
56
- if (!connected) {
57
- console.error("Got server error", err);
58
- setTimeout(this.listen.bind(this), 1000);
59
- }
60
- });
61
- });
62
- }
63
- _onConnection(conn)
64
- {
65
- let compile = new Compile(conn, ++this._connectionId, this.option);
66
- if (this.debug)
67
- console.log("Server::_onConnection", compile.id);
68
- if (this._connectionId == Math.pow(2, 31) - 1)
69
- this._connectionId = 0;
70
- this._connections[compile.id] = conn;
71
- compile.on('end', () => {
72
- if (this.debug)
73
- console.log("Compile::end");
74
-
75
- delete this._connections[compile.id];
76
- });
77
- this.emit('compile', compile);
78
- }
79
- }
80
-
81
- module.exports = Server;
package/daemon/slots.js DELETED
@@ -1,69 +0,0 @@
1
- const EventEmitter = require('events');
2
- const assert = require('assert');
3
-
4
- class Slots extends EventEmitter
5
- {
6
- constructor(count, name, debug)
7
- {
8
- super();
9
- this.count = count;
10
- this.name = name;
11
- this.used = new Map();
12
- this.debug = debug;
13
- this.pending = new Map();
14
- if (this.debug)
15
- console.log("Slots created", this.toString());
16
- }
17
-
18
- acquire(id, data, cb)
19
- {
20
- if (this.used.size < this.count) {
21
- this.used.set(id, data);
22
- if (this.debug)
23
- console.log("acquired slot", id, data, this.toString());
24
- cb();
25
- } else {
26
- if (this.debug)
27
- console.log("pending slot", id, this.toString());
28
- this.pending.set(id, {data: data, cb: cb});
29
- }
30
- }
31
-
32
- release(id)
33
- {
34
- this.pending.delete(id);
35
- if (this.used.has(id)) {
36
- let data = this.used.get(id);
37
- this.used.delete(id);
38
- assert(this.used.size < this.count);
39
- assert(this.used.size + 1 == this.count || this.pending.size == 0);
40
- if (this.debug)
41
- console.log("released", id, data, this.toString());
42
- for (let p of this.pending) {
43
- this.used.set(p[0], p[1].data);
44
- this.pending.delete(p[0]);
45
- p[1].cb();
46
- break;
47
- }
48
- }
49
- }
50
- toString()
51
- {
52
- return `${this.name} ${this.used.size}/${this.count}`;
53
- }
54
-
55
- dump()
56
- {
57
- let pending = {}, used = {};
58
- for (let p of this.pending) {
59
- pending[p[0]] = p[1].data;
60
- }
61
-
62
- for (let p of this.used) {
63
- used[p[0]] = p[1];
64
- }
65
- return { used: used, pending: pending, capacity: this.count, used: this.used.size };
66
- }
67
- }
68
-
69
- module.exports = Slots;