diff --git a/cloud/apps/relay-edge/test/metrics.test.ts b/cloud/apps/relay-edge/test/metrics.test.ts index 55dc1024343..f44af72c939 100644 --- a/cloud/apps/relay-edge/test/metrics.test.ts +++ b/cloud/apps/relay-edge/test/metrics.test.ts @@ -4,7 +4,9 @@ import type { Env } from '../src/env' const withCf = (cf?: Record) => { const request = new Request('https://edge.test/v1/connect/x') - if (cf) Object.defineProperty(request, 'cf', { value: cf }) + if (cf) { + Object.defineProperty(request, 'cf', { value: cf }) + } return request } diff --git a/cloud/apps/relay/src/app.ts b/cloud/apps/relay/src/app.ts index 662a1a4029d..b1e02e561c0 100644 --- a/cloud/apps/relay/src/app.ts +++ b/cloud/apps/relay/src/app.ts @@ -497,7 +497,9 @@ export function createRelayApp( const edge = operations.edgeAssignments // From the IP table only; the address itself is never kept or logged. const country = edge ? requestCountry(edge.config.ipCountry, context.req.header('x-forwarded-for')) : null - if (edge?.config.ipCountry) edge.regionCountries.record(requestedRegion, country) + if (edge?.config.ipCountry) { + edge.regionCountries.record(requestedRegion, country) + } const toEdge = edge?.ready === true && body.data.regionCorrection?.action !== 'report' && diff --git a/cloud/apps/relay/src/edge-region-country-log.ts b/cloud/apps/relay/src/edge-region-country-log.ts index 6f8b8a2f23f..70801aefc29 100644 --- a/cloud/apps/relay/src/edge-region-country-log.ts +++ b/cloud/apps/relay/src/edge-region-country-log.ts @@ -24,9 +24,13 @@ export class EdgeRegionCountryTally { } flush(): void { - if (this.counts.size === 0) return + if (this.counts.size === 0) { + return + } const counts: Record> = {} - for (const [region, byCountry] of this.counts) counts[region] = Object.fromEntries(byCountry) + for (const [region, byCountry] of this.counts) { + counts[region] = Object.fromEntries(byCountry) + } this.counts = new Map() console.warn(JSON.stringify({ event: EDGE_REGION_COUNTRY_EVENT, windowMs: EDGE_REGION_COUNTRY_WINDOW_MS, counts })) } diff --git a/cloud/apps/relay/src/edge-relay-control.ts b/cloud/apps/relay/src/edge-relay-control.ts index 83eb52f05a8..fea052e79af 100644 --- a/cloud/apps/relay/src/edge-relay-control.ts +++ b/cloud/apps/relay/src/edge-relay-control.ts @@ -156,7 +156,9 @@ export function edgeRegionRolloutPermille( region: RelayRegion ): number | undefined { const regional = flags.regionRolloutPermille?.[region] - if (regional !== undefined) return regional + if (regional !== undefined) { + return regional + } return scope.regions.has(region) ? edgeRolloutPermille(scope.rolloutPercent, flags) : undefined } @@ -171,13 +173,17 @@ export function edgeAnyRegionRolloutPermille( ...scope.regions, ...(Object.keys(flags.regionRolloutPermille ?? {}) as RelayRegion[]) ]) - if (inScope.size === 0) return edgeRolloutPermille(scope.rolloutPercent, flags) + if (inScope.size === 0) { + return edgeRolloutPermille(scope.rolloutPercent, flags) + } return Math.max(...[...inScope].map((region) => edgeRegionRolloutPermille(scope, flags, region)!)) } // Whether the country of an ask keeps the host out of `region`'s cohort. `null`: the ask's country // is unknown. export function edgeCountryExcluded(flags: EdgeControlFlags, region: RelayRegion, country: string | null): boolean { - if (country === null) return flags.regionExcludeUnknownCountry?.[region] === true + if (country === null) { + return flags.regionExcludeUnknownCountry?.[region] === true + } return flags.regionExcludeCountries?.[region]?.includes(country) === true } diff --git a/cloud/apps/relay/src/edge-relay-postgres.test.ts b/cloud/apps/relay/src/edge-relay-postgres.test.ts index 8c1b68f1504..925ca8c42cb 100644 --- a/cloud/apps/relay/src/edge-relay-postgres.test.ts +++ b/cloud/apps/relay/src/edge-relay-postgres.test.ts @@ -284,7 +284,9 @@ describePostgres('relay edge on PostgreSQL', () => { assign: async (body: EdgeAssignBody) => { pushes += 1 // The third push fails: that move, and its region record, roll back. - if (pushes === 3) throw new EdgeAdminUnavailableError('status_503') + if (pushes === 3) { + throw new EdgeAdminUnavailableError('status_503') + } return { outcome: 'applied' as const, assignmentEpoch: body.assignmentEpoch } }, exportHost: async (): Promise => { diff --git a/cloud/apps/relay/src/edge-relay-region.test.ts b/cloud/apps/relay/src/edge-relay-region.test.ts index d0c4a3f861b..0b89dc4ef83 100644 --- a/cloud/apps/relay/src/edge-relay-region.test.ts +++ b/cloud/apps/relay/src/edge-relay-region.test.ts @@ -49,19 +49,35 @@ function previousInEdgeCohort( userId?: string ): boolean { const flags = config.control!() - if (flags.mode !== 'on') return false - if (config.denyHosts.has(relayHostId)) return false - if (config.allowHosts.has(relayHostId)) return true - if (region !== 'any' && !config.regions.has(region ?? RELAY_DEFAULT_REGION)) return false - if (userId !== undefined && config.allowUsers?.has(userId)) return true + if (flags.mode !== 'on') { + return false + } + if (config.denyHosts.has(relayHostId)) { + return false + } + if (config.allowHosts.has(relayHostId)) { + return true + } + if (region !== 'any' && !config.regions.has(region ?? RELAY_DEFAULT_REGION)) { + return false + } + if (userId !== undefined && config.allowUsers?.has(userId)) { + return true + } return edgeCohortBucketPermille(relayHostId) < edgeRolloutPermille(config.rolloutPercent, flags) } function previousMayBeOnEdge(config: EdgeRelayConfig, relayHostId: string, userId?: string): boolean { const flags = config.control!() - if (flags.leaveCeilingPermille === undefined) return true - if (config.allowHosts.has(relayHostId) || config.denyHosts.has(relayHostId)) return true - if (userId !== undefined && config.allowUsers?.has(userId)) return true + if (flags.leaveCeilingPermille === undefined) { + return true + } + if (config.allowHosts.has(relayHostId) || config.denyHosts.has(relayHostId)) { + return true + } + if (userId !== undefined && config.allowUsers?.has(userId)) { + return true + } const ceiling = Math.max(flags.leaveCeilingPermille, edgeRolloutPermille(config.rolloutPercent, flags), config.rolloutPercent * 10) return edgeCohortBucketPermille(relayHostId) < ceiling } @@ -258,7 +274,9 @@ describe('edge move records the region', () => { const databases: RelayDatabase[] = [] afterEach(async () => { vi.restoreAllMocks() - for (const database of databases.splice(0)) await database.close() + for (const database of databases.splice(0)) { + await database.close() + } }) const identity = { userId: 'user-1', relayHostId: 'abcdefghijklmnop' } @@ -346,7 +364,9 @@ describe('edge evacuation by recorded region', () => { const databases: RelayDatabase[] = [] afterEach(async () => { vi.restoreAllMocks() - for (const database of databases.splice(0)) await database.close() + for (const database of databases.splice(0)) { + await database.close() + } }) async function harness(flags: EdgeControlFlags) { diff --git a/cloud/apps/relay/src/edge-relay.ts b/cloud/apps/relay/src/edge-relay.ts index 9051c8b0405..8e97bc9d355 100644 --- a/cloud/apps/relay/src/edge-relay.ts +++ b/cloud/apps/relay/src/edge-relay.ts @@ -98,8 +98,12 @@ export function inEdgeCohort( } else { const asked = region ?? RELAY_DEFAULT_REGION const regional = edgeRegionRolloutPermille(config, flags, asked) - if (regional === undefined) return false - if (country !== undefined && edgeCountryExcluded(flags, asked, country)) return false + if (regional === undefined) { + return false + } + if (country !== undefined && edgeCountryExcluded(flags, asked, country)) { + return false + } rollout = regional } if (userId !== undefined && config.allowUsers?.has(userId)) return true diff --git a/cloud/apps/relay/src/ip-country.ts b/cloud/apps/relay/src/ip-country.ts index a48647383e0..4dbaad5f7f6 100644 --- a/cloud/apps/relay/src/ip-country.ts +++ b/cloud/apps/relay/src/ip-country.ts @@ -48,12 +48,14 @@ export function loadIpCountryTable(path: string): IpCountryLookup { export function parseIpCountryTable(text: string): IpCountryLookup { const codes: string[] = [] const codeIndex = new Map() - const v4: Array<[number, number, number]> = [] - const v6: Array<[bigint, bigint, number]> = [] + const v4: [number, number, number][] = [] + const v6: [bigint, bigint, number][] = [] for (const line of text.split('\n')) { const [first, last, rawCode] = line.split(',').map((field) => field.trim().replace(/^"|"$/g, '')) const code = rawCode?.toUpperCase() - if (!first || !last || !code || !/^[A-Z]{2}$/.test(code) || UNKNOWN_CODES.has(code)) continue + if (!first || !last || !code || !/^[A-Z]{2}$/.test(code) || UNKNOWN_CODES.has(code)) { + continue + } let index = codeIndex.get(code) if (index === undefined) { index = codes.push(code) - 1 @@ -65,7 +67,9 @@ export function parseIpCountryTable(text: string): IpCountryLookup { v6.push([ipv6Prefix64(ipv6Groups(first)), ipv6Prefix64(ipv6Groups(last)), index]) } } - if (v4.length + v6.length === 0) throw new Error('ip_country_table_empty') + if (v4.length + v6.length === 0) { + throw new Error('ip_country_table_empty') + } v4.sort((a, b) => a[0] - b[0]) v6.sort((a, b) => (a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0)) const v4First = Uint32Array.from(v4, (range) => range[0]) @@ -79,7 +83,9 @@ export function parseIpCountryTable(text: string): IpCountryLookup { let v4 = isIPv4(ip) ? ipv4Number(ip) : undefined let groups: number[] | undefined if (v4 === undefined) { - if (!isIPv6(ip)) return undefined + if (!isIPv6(ip)) { + return undefined + } groups = ipv6Groups(ip) // IPv4-mapped (::ffff:a.b.c.d, or its hex spelling ::ffff:abcd:efgh) is the IPv4 address. if (groups.slice(0, 5).every((group) => group === 0) && groups[5] === 0xffff) { @@ -131,7 +137,9 @@ function ipv6Groups(ip: string): number[] { : [Number.parseInt(token, 16)] ) const headGroups = tokens(head) - if (tail === undefined) return headGroups + if (tail === undefined) { + return headGroups + } const tailGroups = tokens(tail) return [...headGroups, ...Array(8 - headGroups.length - tailGroups.length).fill(0), ...tailGroups] } diff --git a/cloud/apps/relay/src/relay-server.ts b/cloud/apps/relay/src/relay-server.ts index 7d47723dbe4..7efa4069f35 100644 --- a/cloud/apps/relay/src/relay-server.ts +++ b/cloud/apps/relay/src/relay-server.ts @@ -201,7 +201,9 @@ export function createRelayServer( ? new EdgeEvacuation(observedDatabase, edgeConfig, edgeAdmin, EDGE_CELL_ID, options.now, options.random) : undefined edgeEvacuation?.start() - if (edgeConfig?.ipCountry) edgeAssignments?.regionCountries.start() + if (edgeConfig?.ipCountry) { + edgeAssignments?.regionCountries.start() + } // A rollback (mode off/down, a smaller share) starts draining within seconds. options.edgeControl?.onChange(() => edgeEvacuation?.controlChanged()) if (edgeAssignments) {