Skip to content

Commit 49f7a37

Browse files
committed
feat(boot): handle v4 boot events in port-polling util
no issue - handles separate 'ready' event from Ghost v4+
1 parent ae12f71 commit 49f7a37

File tree

4 files changed

+114
-8
lines changed

4 files changed

+114
-8
lines changed

lib/process-manager.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ class ProcessManager {
6363
stopOnError: true,
6464
port: this.instance.config.get('server.port'),
6565
host: this.instance.config.get('server.host', 'localhost'),
66-
useNetServer: semver.major(this.instance.version) >= 2
66+
useNetServer: semver.major(this.instance.version) >= 2,
67+
useV4Boot: semver.major(this.instance.version) >= 4
6768
}, options || {});
6869

6970
try {

lib/utils/port-polling.js

+17-3
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,11 @@ const errors = require('../errors');
88
*/
99
const useNetServer = options => new Promise((resolve, reject) => {
1010
const net = require('net');
11+
const {useV4Boot} = options;
12+
1113
let waitTimeout = null;
1214
let ghostSocket = null;
15+
let started = false;
1316

1417
const server = net.createServer((socket) => {
1518
ghostSocket = socket;
@@ -20,7 +23,12 @@ const useNetServer = options => new Promise((resolve, reject) => {
2023
try {
2124
message = JSON.parse(data);
2225
} catch (err) {
23-
message = {started: false, error: err};
26+
message = {started: false, ready: false, error: err};
27+
}
28+
29+
if (useV4Boot && message.started) {
30+
started = true;
31+
return;
2432
}
2533

2634
/* istanbul ignore else */
@@ -32,11 +40,16 @@ const useNetServer = options => new Promise((resolve, reject) => {
3240
ghostSocket = null;
3341

3442
server.close(() => {
35-
if (message.started) {
43+
if ((!useV4Boot && message.started) || (useV4Boot && message.ready)) {
3644
resolve();
3745
} else {
46+
let {message: errMsg} = message.error;
47+
if (useV4Boot && started) {
48+
errMsg = `Ghost was able to start, but errored during boot with: ${errMsg}`;
49+
}
50+
3851
reject(new errors.GhostError({
39-
message: message.error.message,
52+
message: errMsg,
4053
help: message.error.help,
4154
suggestion: options.logSuggestion
4255
}));
@@ -167,6 +180,7 @@ module.exports = function portPolling(options) {
167180
logSuggestion: 'ghost log',
168181
socketTimeoutInMS: 1000 * 60,
169182
useNetServer: false,
183+
useV4Boot: false,
170184
netServerTimeoutInMS: 5 * 60 * 1000,
171185
socketAddress: {
172186
port: 1212,

test/unit/process-manager-spec.js

+8-4
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@ describe('Unit: Process Manager', function () {
7171
stopOnError: true,
7272
port: 2368,
7373
host: '10.0.1.0',
74-
useNetServer: false
74+
useNetServer: false,
75+
useV4Boot: false
7576
})).to.be.true;
7677
expect(stopStub.called).to.be.false;
7778
});
@@ -96,7 +97,8 @@ describe('Unit: Process Manager', function () {
9697
stopOnError: false,
9798
port: 2368,
9899
host: 'localhost',
99-
useNetServer: false
100+
useNetServer: false,
101+
useV4Boot: false
100102
})).to.be.true;
101103
expect(stopStub.called).to.be.false;
102104
});
@@ -122,7 +124,8 @@ describe('Unit: Process Manager', function () {
122124
stopOnError: true,
123125
port: 2368,
124126
host: 'localhost',
125-
useNetServer: false
127+
useNetServer: false,
128+
useV4Boot: false
126129
})).to.be.true;
127130
expect(stopStub.calledOnce).to.be.true;
128131
});
@@ -148,7 +151,8 @@ describe('Unit: Process Manager', function () {
148151
stopOnError: true,
149152
port: 2368,
150153
host: 'localhost',
151-
useNetServer: false
154+
useNetServer: false,
155+
useV4Boot: false
152156
})).to.be.true;
153157
expect(stopStub.calledOnce).to.be.true;
154158
});

test/unit/utils/port-polling-spec.js

+87
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,49 @@ describe('Unit: Utils > portPolling', function () {
6464
});
6565
});
6666

67+
it('Ghost does start, v4', function () {
68+
const netStub = sinon.stub();
69+
const socketStub = sinon.stub();
70+
71+
socketStub.on = sinon.stub().callsFake((event, cb) => {
72+
if (event === 'data') {
73+
cb(JSON.stringify({started: true}));
74+
cb(JSON.stringify({ready: true}));
75+
}
76+
});
77+
78+
socketStub.destroy = sinon.stub();
79+
80+
netStub.listen = sinon.stub();
81+
netStub.close = sinon.stub().callsFake((cb) => {
82+
cb();
83+
});
84+
85+
sinon.stub(net, 'createServer').callsFake((fn) => {
86+
setTimeout(() => {
87+
fn(socketStub);
88+
}, 100);
89+
90+
return netStub;
91+
});
92+
93+
return portPolling({
94+
netServerTimeoutInMS: 1000,
95+
useNetServer: true,
96+
useV4Boot: true
97+
}).then(() => {
98+
expect(net.createServer.calledOnce).to.be.true;
99+
expect(netStub.listen.callCount).to.eql(1);
100+
expect(netStub.listen.calledWithExactly({host: 'localhost', port: 1212})).to.be.true;
101+
expect(netStub.close.callCount).to.eql(1);
102+
103+
expect(socketStub.destroy.callCount).to.eql(1);
104+
expect(socketStub.on.callCount).to.eql(1);
105+
}).catch((err) => {
106+
throw err;
107+
});
108+
});
109+
67110
it('Ghost didn\'t start', function () {
68111
const netStub = sinon.stub();
69112
const socketStub = sinon.stub();
@@ -106,6 +149,50 @@ describe('Unit: Utils > portPolling', function () {
106149
});
107150
});
108151

152+
it('Ghost didn\'t start, v4', function () {
153+
const netStub = sinon.stub();
154+
const socketStub = sinon.stub();
155+
156+
socketStub.on = sinon.stub().callsFake((event, cb) => {
157+
if (event === 'data') {
158+
cb(JSON.stringify({started: true}));
159+
cb(JSON.stringify({false: true, error: {message: 'Syntax Error'}}));
160+
}
161+
});
162+
163+
socketStub.destroy = sinon.stub();
164+
165+
netStub.listen = sinon.stub();
166+
netStub.close = sinon.stub().callsFake((cb) => {
167+
cb();
168+
});
169+
170+
sinon.stub(net, 'createServer').callsFake((fn) => {
171+
setTimeout(() => {
172+
fn(socketStub);
173+
}, 100);
174+
175+
return netStub;
176+
});
177+
178+
return portPolling({
179+
netServerTimeoutInMS: 1000,
180+
useNetServer: true,
181+
useV4Boot: true
182+
}).then(() => {
183+
expect('1').to.equal(1, 'Ghost should not start.');
184+
}).catch((err) => {
185+
expect(err.message).to.eql('Ghost was able to start, but errored during boot with: Syntax Error');
186+
expect(net.createServer.calledOnce).to.be.true;
187+
expect(netStub.listen.calledOnce).to.be.true;
188+
expect(netStub.listen.calledWithExactly({host: 'localhost', port: 1212})).to.be.true;
189+
expect(netStub.close.callCount).to.eql(1);
190+
191+
expect(socketStub.destroy.callCount).to.eql(1);
192+
expect(socketStub.on.callCount).to.eql(1);
193+
});
194+
});
195+
109196
it('Ghost didn\'t start, invalid json', function () {
110197
const netStub = sinon.stub();
111198
const socketStub = sinon.stub();

0 commit comments

Comments
 (0)