Skip to content

Commit 3dce388

Browse files
authored
Cleanup dev registry messaging (#7172)
1 parent f292294 commit 3dce388

File tree

13 files changed

+97
-55
lines changed

13 files changed

+97
-55
lines changed

.changeset/large-otters-search.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"wrangler": patch
3+
---
4+
5+
Clarify dev registry messaging around locally connected services. The connection status of local service bindings & durable object bindings is now indicated by `connected` or `not connected` next to their entry in the bindings summary. For more details, refer to https://developers.cloudflare.com/workers/runtime-apis/bindings/service-bindings/#local-development

packages/wrangler/e2e/__snapshots__/pages-dev.test.ts.snap

+14-13
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ exports[`Pages 'wrangler pages dev --no-x-dev-env' > should merge (with override
1010
▲ [WARNING] This worker is bound to live services: SERVICE_BINDING_1_TOML (SERVICE_NAME_1_TOML), SERVICE_BINDING_2_TOML (SERVICE_NAME_2_TOML)
1111
Your worker has access to the following bindings:
1212
- Durable Objects:
13-
- DO_BINDING_1_TOML: NEW_DO_1 (defined in 🔴 NEW_DO_SCRIPT_1)
14-
- DO_BINDING_2_TOML: DO_2_TOML (defined in 🔴 DO_SCRIPT_2_TOML)
15-
- DO_BINDING_3_ARGS: DO_3_ARGS (defined in 🔴 DO_SCRIPT_3_ARGS)
13+
- DO_BINDING_1_TOML: NEW_DO_1 (defined in NEW_DO_SCRIPT_1 [not connected])
14+
- DO_BINDING_2_TOML: DO_2_TOML (defined in DO_SCRIPT_2_TOML [not connected])
15+
- DO_BINDING_3_ARGS: DO_3_ARGS (defined in DO_SCRIPT_3_ARGS [not connected])
1616
- KV Namespaces:
1717
- KV_BINDING_1_TOML: NEW_KV_ID_1 (local)
1818
- KV_BINDING_2_TOML: KV_ID_2_TOML (local)
@@ -26,15 +26,16 @@ Your worker has access to the following bindings:
2626
- R2_BINDING_2_TOML: R2_BUCKET_2_TOML (local)
2727
- R2_BINDING_3_TOML: R2_BUCKET_3_ARGS (local)
2828
- Services:
29-
- SERVICE_BINDING_1_TOML: 🔴 NEW_SERVICE_NAME_1
30-
- SERVICE_BINDING_2_TOML: 🔴 SERVICE_NAME_2_TOML
31-
- SERVICE_BINDING_3_TOML: 🔴 SERVICE_NAME_3_ARGS
29+
- SERVICE_BINDING_1_TOML: NEW_SERVICE_NAME_1 [not connected]
30+
- SERVICE_BINDING_2_TOML: SERVICE_NAME_2_TOML [not connected]
31+
- SERVICE_BINDING_3_TOML: SERVICE_NAME_3_ARGS [not connected]
3232
- AI:
3333
- Name: AI_BINDING_2_TOML
3434
- Vars:
3535
- VAR1: "(hidden)"
3636
- VAR2: "VAR_2_TOML"
3737
- VAR3: "(hidden)"
38+
Service bindings & durable object bindings connect to other \`wrangler dev\` processes running locally, with their connection status indicated by [connected] or [not connected]. For more details, refer to https://developers.cloudflare.com/workers/runtime-apis/bindings/service-bindings/#local-development
3839
▲ [WARNING] ⎔ Support for service bindings in local mode is experimental and may change.
3940
▲ [WARNING] ⎔ Support for external Durable Objects in local mode is experimental and may change.
4041
"
@@ -49,9 +50,9 @@ exports[`Pages 'wrangler pages dev --x-dev-env' > should merge (with override) \
4950
- {"name":"DO_BINDING_2_TOML","class_name":"DO_2_TOML","script_name":"DO_SCRIPT_2_TOML"}
5051
Your worker has access to the following bindings:
5152
- Durable Objects:
52-
- DO_BINDING_1_TOML: NEW_DO_1 (defined in 🔴 NEW_DO_SCRIPT_1)
53-
- DO_BINDING_2_TOML: DO_2_TOML (defined in 🔴 DO_SCRIPT_2_TOML)
54-
- DO_BINDING_3_ARGS: DO_3_ARGS (defined in 🔴 DO_SCRIPT_3_ARGS)
53+
- DO_BINDING_1_TOML: NEW_DO_1 (defined in NEW_DO_SCRIPT_1 [not connected])
54+
- DO_BINDING_2_TOML: DO_2_TOML (defined in DO_SCRIPT_2_TOML [not connected])
55+
- DO_BINDING_3_ARGS: DO_3_ARGS (defined in DO_SCRIPT_3_ARGS [not connected])
5556
- KV Namespaces:
5657
- KV_BINDING_1_TOML: NEW_KV_ID_1 (local)
5758
- KV_BINDING_2_TOML: KV_ID_2_TOML (local)
@@ -65,16 +66,16 @@ Your worker has access to the following bindings:
6566
- R2_BINDING_2_TOML: R2_BUCKET_2_TOML (local)
6667
- R2_BINDING_3_TOML: R2_BUCKET_3_ARGS (local)
6768
- Services:
68-
- SERVICE_BINDING_1_TOML: 🔴 NEW_SERVICE_NAME_1
69-
- SERVICE_BINDING_2_TOML: 🔴 SERVICE_NAME_2_TOML
70-
- SERVICE_BINDING_3_TOML: 🔴 SERVICE_NAME_3_ARGS
69+
- SERVICE_BINDING_1_TOML: NEW_SERVICE_NAME_1 [not connected]
70+
- SERVICE_BINDING_2_TOML: SERVICE_NAME_2_TOML [not connected]
71+
- SERVICE_BINDING_3_TOML: SERVICE_NAME_3_ARGS [not connected]
7172
- AI:
7273
- Name: AI_BINDING_2_TOML
7374
- Vars:
7475
- VAR1: "(hidden)"
7576
- VAR2: "VAR_2_TOML"
7677
- VAR3: "(hidden)"
77-
▲ [WARNING] This worker is bound to live services: SERVICE_BINDING_1_TOML (NEW_SERVICE_NAME_1), SERVICE_BINDING_3_TOML (SERVICE_NAME_3_ARGS), SERVICE_BINDING_2_TOML (SERVICE_NAME_2_TOML)
78+
Service bindings & durable object bindings connect to other \`wrangler dev\` processes running locally, with their connection status indicated by [connected] or [not connected]. For more details, refer to https://developers.cloudflare.com/workers/runtime-apis/bindings/service-bindings/#local-development
7879
▲ [WARNING] Using Workers AI always accesses your Cloudflare account in order to run AI models, and so will incur usage charges even in local development.
7980
"
8081
`;

packages/wrangler/e2e/dev-registry.test.ts

+5
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { beforeEach, describe, expect, it, vi } from "vitest";
44
import { WranglerE2ETestHelper } from "./helpers/e2e-wrangler-test";
55
import { fetchText } from "./helpers/fetch-text";
66
import { generateResourceName } from "./helpers/generate-resource-name";
7+
import { normalizeOutput } from "./helpers/normalize";
78
import { seed as baseSeed, makeRoot } from "./helpers/setup";
89
import type { RequestInit } from "undici";
910

@@ -180,6 +181,10 @@ describe.each([
180181
async () => await expect(fetchText(url)).resolves.toBe("hello world"),
181182
{ interval: 1000, timeout: 10_000 }
182183
);
184+
185+
expect(normalizeOutput(workerA.currentOutput)).toContain(
186+
"bindings connect to other `wrangler dev` processes running locally"
187+
);
183188
});
184189

185190
it("can fetch b through a (start a, start b)", async () => {

packages/wrangler/e2e/pages-dev.test.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -120,15 +120,15 @@ describe.each([
120120
expect(normalizeOutput(worker.currentOutput)).toContain(
121121
dedent`Your worker has access to the following bindings:
122122
- Durable Objects:
123-
- TEST_DO: TestDurableObject (defined in 🔴 a)
123+
- TEST_DO: TestDurableObject (defined in a [not connected])
124124
- KV Namespaces:
125125
- TEST_KV: TEST_KV (local)
126126
- D1 Databases:
127127
- TEST_D1: local-TEST_D1 (TEST_D1) (local)
128128
- R2 Buckets:
129129
- TEST_R2: TEST_R2 (local)
130130
- Services:
131-
- TEST_SERVICE: 🔴 test-worker
131+
- TEST_SERVICE: test-worker [not connected]
132132
`
133133
);
134134
});

packages/wrangler/src/__tests__/dev.test.ts

+8-16
Original file line numberDiff line numberDiff line change
@@ -1229,9 +1229,9 @@ describe.sequential("wrangler dev", () => {
12291229
"Your worker has access to the following bindings:
12301230
- Durable Objects:
12311231
- NAME_1: CLASS_1
1232-
- NAME_2: CLASS_2 (defined in 🔴 SCRIPT_A)
1232+
- NAME_2: CLASS_2 (defined in SCRIPT_A [not connected])
12331233
- NAME_3: CLASS_3
1234-
- NAME_4: CLASS_4 (defined in 🔴 SCRIPT_B)
1234+
- NAME_4: CLASS_4 (defined in SCRIPT_B [not connected])
12351235
"
12361236
`);
12371237
expect(std.warn).toMatchInlineSnapshot(`
@@ -1809,15 +1809,11 @@ describe.sequential("wrangler dev", () => {
18091809
expect(std.out).toMatchInlineSnapshot(`
18101810
"Your worker has access to the following bindings:
18111811
- Services:
1812-
- WorkerA: 🔴 A
1813-
- WorkerB: 🔴 B
1812+
- WorkerA: A [not connected]
1813+
- WorkerB: B [not connected]
18141814
"
18151815
`);
1816-
expect(std.warn).toMatchInlineSnapshot(`
1817-
"▲ [WARNING] This worker is bound to live services: WorkerA (A), WorkerB (B@staging)
1818-
1819-
"
1820-
`);
1816+
expect(std.warn).toMatchInlineSnapshot(`""`);
18211817
});
18221818
});
18231819

@@ -1834,15 +1830,11 @@ describe.sequential("wrangler dev", () => {
18341830
expect(std.out).toMatchInlineSnapshot(`
18351831
"Your worker has access to the following bindings:
18361832
- Services:
1837-
- WorkerA: 🔴 A
1838-
- WorkerB: 🔴 B
1839-
"
1840-
`);
1841-
expect(std.warn).toMatchInlineSnapshot(`
1842-
"▲ [WARNING] This worker is bound to live services: WorkerA (A), WorkerB (B@staging)
1843-
1833+
- WorkerA: A [not connected]
1834+
- WorkerB: B [not connected]
18441835
"
18451836
`);
1837+
expect(std.warn).toMatchInlineSnapshot(`""`);
18461838
});
18471839

18481840
it("should mask vars that were overriden in .dev.vars", async () => {

packages/wrangler/src/__tests__/logger.test.ts

+25-7
Original file line numberDiff line numberDiff line change
@@ -204,20 +204,38 @@ describe("logger", () => {
204204
});
205205
});
206206

207-
describe("warnOnce", () => {
207+
describe("once", () => {
208208
it("should only log the same message once", () => {
209209
const logger = new Logger();
210-
logger.warnOnce("This is a warnOnce message");
211-
logger.warnOnce("This is a warnOnce message");
212-
logger.warnOnce("This is a warnOnce message");
213-
logger.warnOnce("This is a warnOnce message");
214-
logger.warnOnce("This is a warnOnce message");
210+
logger.once.warn("This is a once.warn message");
211+
logger.once.warn("This is a once.warn message");
212+
logger.once.warn("This is a once.warn message");
213+
logger.once.warn("This is a once.warn message");
214+
logger.once.warn("This is a once.warn message");
215215

216216
expect(std.warn).toMatchInlineSnapshot(`
217-
"[33m▲ [43;33m[[43;30mWARNING[43;33m][0m [1mThis is a warnOnce message[0m
217+
"[33m▲ [43;33m[[43;30mWARNING[43;33m][0m [1mThis is a once.warn message[0m
218218
219219
"
220220
`);
221221
});
222+
223+
it("should log once per log level", () => {
224+
const logger = new Logger();
225+
logger.once.warn("This is a once message");
226+
logger.once.info("This is a once message");
227+
logger.once.warn("This is a once message");
228+
logger.once.warn("This is a once message");
229+
logger.once.info("This is a once message");
230+
logger.once.info("This is a once message");
231+
logger.once.warn("This is a once message");
232+
233+
expect(std.warn).toMatchInlineSnapshot(`
234+
"▲ [WARNING] This is a once message
235+
236+
"
237+
`);
238+
expect(std.info).toMatchInlineSnapshot(`"This is a once message"`);
239+
});
222240
});
223241
});

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ async function resolveConfig(
316316
validateAssetsArgsAndConfig(resolved);
317317

318318
const services = extractBindingsOfType("service", resolved.bindings);
319-
if (services && services.length > 0) {
319+
if (services && services.length > 0 && resolved.dev?.remote) {
320320
logger.warn(
321321
`This worker is bound to live services: ${services
322322
.map(

packages/wrangler/src/config/index.ts

+15-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import fs from "node:fs";
2+
import chalk from "chalk";
23
import dotenv from "dotenv";
34
import { findUpSync } from "find-up";
45
import { FatalError, UserError } from "../errors";
@@ -236,6 +237,7 @@ export function printBindings(
236237
local?: boolean;
237238
} = {}
238239
) {
240+
let hasConnectionStatus = false;
239241
const truncate = (item: string | Record<string, unknown>) => {
240242
const s = typeof item === "string" ? item : JSON.stringify(item);
241243
const maxLength = 40;
@@ -297,15 +299,16 @@ export function printBindings(
297299
if (context.local) {
298300
const registryDefinition = context.registry?.[script_name];
299301

302+
hasConnectionStatus = true;
300303
if (
301304
registryDefinition &&
302305
registryDefinition.durableObjects.some(
303306
(d) => d.className === class_name
304307
)
305308
) {
306-
value += ` (defined in 🟢 ${script_name})`;
309+
value += ` (defined in ${script_name} ${chalk.green("[connected]")})`;
307310
} else {
308-
value += ` (defined in 🔴 ${script_name})`;
311+
value += ` (defined in ${script_name} ${chalk.red("[not connected]")})`;
309312
}
310313
} else {
311314
value += ` (defined in ${script_name})`;
@@ -463,14 +466,16 @@ export function printBindings(
463466

464467
if (context.local) {
465468
const registryDefinition = context.registry?.[service];
469+
hasConnectionStatus = true;
470+
466471
if (
467472
registryDefinition &&
468473
(!entrypoint ||
469474
registryDefinition.entrypointAddresses?.[entrypoint])
470475
) {
471-
value = `🟢 ` + value;
476+
value = value + " " + chalk.green("[connected]");
472477
} else {
473-
value = `🔴 ` + value;
478+
value = value + " " + chalk.red("[not connected]");
474479
}
475480
}
476481
return {
@@ -637,6 +642,12 @@ export function printBindings(
637642
].join("\n");
638643

639644
logger.log(message);
645+
646+
if (hasConnectionStatus) {
647+
logger.once.info(
648+
`\nService bindings & durable object bindings connect to other \`wrangler dev\` processes running locally, with their connection status indicated by ${chalk.green("[connected]")} or ${chalk.red("[not connected]")}. For more details, refer to https://developers.cloudflare.com/workers/runtime-apis/bindings/service-bindings/#local-development\n`
649+
);
650+
}
640651
}
641652

642653
export function withConfig<T>(

packages/wrangler/src/deploy/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ export async function deployHandler(args: DeployArgs) {
284284
}
285285

286286
if (config.workflows?.length) {
287-
logger.warnOnce("Workflows is currently in open beta.");
287+
logger.once.warn("Workflows is currently in open beta.");
288288
}
289289

290290
validateAssetsArgsAndConfig(args, config);

packages/wrangler/src/logger.ts

+18-8
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ function getLoggerLevel(): LoggerLevel {
4040
const expected = Object.keys(LOGGER_LEVELS)
4141
.map((level) => `"${level}"`)
4242
.join(" | ");
43-
logger.warnOnce(
43+
logger.once.warn(
4444
`Unrecognised WRANGLER_LOG value ${JSON.stringify(
4545
fromEnv
4646
)}, expected ${expected}, defaulting to "log"...`
@@ -107,14 +107,24 @@ export class Logger {
107107
Logger.#afterLogHook?.();
108108
}
109109

110-
static warnOnceHistory = new Set();
111-
warnOnce(message: string) {
112-
// using this.constructor.warnOnceHistory, instead of hard-coding Logger.warnOnceHistory, allows for subclassing
113-
const { warnOnceHistory } = this.constructor as typeof Logger;
110+
static onceHistory = new Set();
111+
get once() {
112+
return {
113+
info: (...args: unknown[]) => this.doLogOnce("info", args),
114+
log: (...args: unknown[]) => this.doLogOnce("log", args),
115+
warn: (...args: unknown[]) => this.doLogOnce("warn", args),
116+
error: (...args: unknown[]) => this.doLogOnce("error", args),
117+
};
118+
}
119+
doLogOnce(messageLevel: Exclude<LoggerLevel, "none">, args: unknown[]) {
120+
// using this.constructor.onceHistory, instead of hard-coding Logger.onceHistory, allows for subclassing
121+
const { onceHistory } = this.constructor as typeof Logger;
122+
123+
const cacheKey = `${messageLevel}: ${args.join(" ")}`;
114124

115-
if (!warnOnceHistory.has(message)) {
116-
warnOnceHistory.add(message);
117-
this.warn(message);
125+
if (!onceHistory.has(cacheKey)) {
126+
onceHistory.add(cacheKey);
127+
this.doLog(messageLevel, args);
118128
}
119129
}
120130

packages/wrangler/src/triggers/deploy.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ export default async function triggersDeploy(
241241
}
242242

243243
if (config.workflows?.length) {
244-
logger.warnOnce("Workflows is currently in open beta.");
244+
logger.once.warn("Workflows is currently in open beta.");
245245

246246
for (const workflow of config.workflows) {
247247
deployments.push(

packages/wrangler/src/versions/deploy.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ export async function versionsDeployHandler(args: VersionsDeployArgs) {
123123
}
124124

125125
if (config.workflows?.length) {
126-
logger.warnOnce("Workflows is currently in open beta.");
126+
logger.once.warn("Workflows is currently in open beta.");
127127
}
128128

129129
const versionCache: VersionCache = new Map();

packages/wrangler/src/versions/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ export async function versionsUploadHandler(
226226
}
227227

228228
if (config.workflows?.length) {
229-
logger.warnOnce("Workflows is currently in open beta.");
229+
logger.once.warn("Workflows is currently in open beta.");
230230
}
231231

232232
validateAssetsArgsAndConfig(

0 commit comments

Comments
 (0)