Skip to content

Commit b9ec263

Browse files
authored
fix: assign a random port for devtools in case of conflict (#136)
Fixes #77
1 parent 128a052 commit b9ec263

File tree

2 files changed

+48
-12
lines changed

2 files changed

+48
-12
lines changed

packages/server/lib/index.js

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -164,14 +164,28 @@ export default class DevTool {
164164
* @see {@link DevTool.stop}
165165
*/
166166
start() {
167-
return new Promise((resolve) => {
167+
return new Promise((resolve, reject) => {
168168
const start = new Date().getTime();
169-
this.server = this.app.listen(this.port, () => {
170-
const ms = new Date().getTime() - start;
171-
this.port = this.server.address().port;
172-
this.#log.trace(`dev tool server started on port "${this.port}" (in ${ms} ms)`);
173-
resolve();
174-
});
169+
this.server = this.app
170+
.listen(this.port, () => {
171+
const ms = new Date().getTime() - start;
172+
this.port = this.server.address().port;
173+
this.#log.trace(`dev tool server started on port "${this.port}" (in ${ms} ms)`);
174+
resolve();
175+
})
176+
.on("error", (e) => {
177+
if (e.code === "EADDRINUSE") {
178+
this.#log.trace(`dev tool server port ${this.port} is already in use, trying a random port`);
179+
this.server = this.app.listen(0, () => {
180+
const ms = new Date().getTime() - start;
181+
this.port = this.server.address().port;
182+
this.#log.trace(`dev tool server started on port "${this.port}" (in ${ms} ms)`);
183+
resolve();
184+
});
185+
} else {
186+
reject(e);
187+
}
188+
});
175189
});
176190
}
177191

packages/server/lib/index.test.js

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,16 +71,38 @@ test("starting on a random port", async (t) => {
7171
error: t.mock.fn(),
7272
fatal: t.mock.fn(),
7373
};
74-
devTool = new DevTool({ logger, port: 0 });
74+
const a = new DevTool({ logger, port: 4321 });
75+
const b = new DevTool({ logger, port: 4321 });
76+
await a.start();
77+
await b.start();
78+
await a.stop();
79+
await b.stop();
80+
81+
assert.match(logger.trace.mock.calls[0].arguments[0], /dev tool server started on port "4321"/);
82+
assert.match(logger.trace.mock.calls[2].arguments[0], /dev tool server started on port "/);
83+
assert.notEqual(logger.trace.mock.calls[2].arguments[0], "undefined");
84+
assert.notEqual(logger.trace.mock.calls[2].arguments[0], "null");
85+
assert.notEqual(logger.trace.mock.calls[2].arguments[0], "8172");
86+
assert.equal(logger.trace.mock.calls.length, 5);
87+
});
88+
89+
test("assigns a random port if the specified port isn't available", async (t) => {
90+
const logger = {
91+
trace: t.mock.fn(),
92+
debug: t.mock.fn(),
93+
info: t.mock.fn(),
94+
warn: t.mock.fn(),
95+
error: t.mock.fn(),
96+
fatal: t.mock.fn(),
97+
};
98+
devTool = new DevTool({ logger });
7599
devTool.register(podlet);
76100

77101
await devTool.start();
78102
await devTool.stop();
79103

80-
assert.match(logger.trace.mock.calls[0].arguments[0], /dev tool server started on port "/);
81-
assert.notEqual(logger.trace.mock.calls[0].arguments[0], "undefined");
82-
assert.notEqual(logger.trace.mock.calls[0].arguments[0], "null");
83-
assert.notEqual(logger.trace.mock.calls[0].arguments[0], "8172");
104+
assert.match(logger.trace.mock.calls[0].arguments[0], /dev tool server started on port "8172" \(in/);
105+
assert.match(logger.trace.mock.calls[1].arguments[0], /dev tool server shutdown in/);
84106
assert.equal(logger.trace.mock.calls.length, 2);
85107
});
86108

0 commit comments

Comments
 (0)