Skip to content

Commit 014ba3e

Browse files
[wrangler] make sure that the ready-on message is printed after the local runtime is ready
1 parent bfc9851 commit 014ba3e

File tree

4 files changed

+72
-7
lines changed

4 files changed

+72
-7
lines changed

.changeset/fluffy-seals-arrive.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"wrangler": patch
3+
---
4+
5+
make sure that the ready-on message is printed after the local runtime is ready
6+
7+
fix the fact that when starting a local dev session the log saying `Ready on http://localhost:xxxx` could be displayed before the local runtime is actually ready to handle requests (this is quite noticeable when running dev sessions with containers, where the ready message currently gets displayed before the container images building/pulling process)

packages/wrangler/e2e/containers.dev.test.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,12 +189,29 @@ describe
189189
}
190190
// from miniflare output:
191191
await worker.readUntil(/Container image\(s\) ready/);
192+
await worker.stop();
193+
});
194+
195+
it("will display the ready-on message after the container(s) have been built/pulled", async () => {
196+
const worker = helper.runLongLived("wrangler dev");
197+
await worker.readUntil(/Container image\(s\) ready/);
198+
199+
await worker.stop();
200+
201+
const fullOutput = await worker.output;
202+
const indexOfContainersReadyMessage = fullOutput.indexOf(
203+
"Container image(s) ready"
204+
);
205+
const indexOfReadyOnMessage = fullOutput.indexOf("Ready on http://");
206+
expect(indexOfReadyOnMessage).toBeGreaterThan(
207+
indexOfContainersReadyMessage
208+
);
192209
});
193210

194211
it(`will be able to interact with the container`, async () => {
195212
const worker = helper.runLongLived("wrangler dev");
196-
const ready = await worker.waitForReady();
197213
await worker.readUntil(/Container image\(s\) ready/);
214+
const ready = await worker.waitForReady();
198215

199216
let response = await fetch(`${ready.url}/status`);
200217
expect(response.status).toBe(200);

packages/wrangler/src/api/startDevWorker/DevEnv.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ export class DevEnv extends EventEmitter {
7777
});
7878
});
7979

80+
this.resolveProxyLocalServerReady().catch(() => {});
81+
8082
runtimes.forEach((runtime) => {
8183
runtime.on("reloadStart", (event) => {
8284
proxy.onReloadStart(event);
@@ -93,6 +95,25 @@ export class DevEnv extends EventEmitter {
9395
});
9496
}
9597

98+
/**
99+
* Awaits for all the local runtime controllers to be ready, and when they are
100+
* it resolves a promise on the proxy controller to let it know that the
101+
* local server is now ready to handle requests
102+
*/
103+
private async resolveProxyLocalServerReady(): Promise<void> {
104+
await Promise.all(
105+
this.runtimes
106+
.filter((runtime) => runtime instanceof LocalRuntimeController)
107+
.map((runtime) => {
108+
return new Promise<void>((resolve) => {
109+
runtime.once("reloadComplete", () => resolve());
110+
});
111+
})
112+
);
113+
114+
this.proxy.localServerReady.resolve();
115+
}
116+
96117
// *********************
97118
// Event Dispatchers
98119
// *********************

packages/wrangler/src/api/startDevWorker/ProxyController.ts

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ import type {
4141
} from "./events";
4242
import type { StartDevWorkerOptions } from "./types";
4343
import type { DeferredPromise } from "./utils";
44-
import type { MiniflareOptions } from "miniflare";
44+
import type { LogOptions, MiniflareOptions } from "miniflare";
4545

4646
type ProxyControllerEventMap = ControllerEventMap & {
4747
ready: [ReadyEvent];
@@ -50,6 +50,8 @@ type ProxyControllerEventMap = ControllerEventMap & {
5050
export class ProxyController extends Controller<ProxyControllerEventMap> {
5151
public ready = createDeferred<ReadyEvent>();
5252

53+
public localServerReady = createDeferred<void>();
54+
5355
public proxyWorker?: Miniflare;
5456
proxyWorkerOptions?: MiniflareOptions;
5557
private inspectorProxyWorkerWebSocket?: DeferredPromise<WebSocket>;
@@ -126,11 +128,17 @@ export class ProxyController extends Controller<ProxyControllerEventMap> {
126128
verbose: logger.loggerLevel === "debug",
127129

128130
// log requests into the ProxyWorker (for local + remote mode)
129-
log: new ProxyControllerLogger(castLogLevel(logger.loggerLevel), {
130-
prefix:
131-
// if debugging, log requests with specic ProxyWorker prefix
132-
logger.loggerLevel === "debug" ? "wrangler-ProxyWorker" : "wrangler",
133-
}),
131+
log: new ProxyControllerLogger(
132+
castLogLevel(logger.loggerLevel),
133+
{
134+
prefix:
135+
// if debugging, log requests with specic ProxyWorker prefix
136+
logger.loggerLevel === "debug"
137+
? "wrangler-ProxyWorker"
138+
: "wrangler",
139+
},
140+
this.localServerReady.promise
141+
),
134142
handleRuntimeStdio,
135143
liveReload: false,
136144
};
@@ -606,6 +614,18 @@ export class ProxyController extends Controller<ProxyControllerEventMap> {
606614
}
607615

608616
class ProxyControllerLogger extends WranglerLog {
617+
constructor(
618+
level: LogLevel,
619+
opts: LogOptions,
620+
private localServerReady: Promise<void>
621+
) {
622+
super(level, opts);
623+
}
624+
625+
logReady(message: string): void {
626+
this.localServerReady.then(() => super.logReady(message)).catch(() => {});
627+
}
628+
609629
log(message: string) {
610630
// filter out request logs being handled by the ProxyWorker
611631
// the requests log remaining are handled by the UserWorker

0 commit comments

Comments
 (0)