|
1 | 1 | /** |
2 | 2 | * Multi-tenancy cache orchestrator. |
3 | 3 | * |
4 | | - * Caches one independent PostGraphile handler per **buildKey** (derived from |
5 | | - * the inputs that materially affect Graphile handler construction). |
| 4 | + * Caches one independent PostGraphile handler per **buildKey** (a canonical |
| 5 | + * string derived from the inputs that materially affect Graphile handler |
| 6 | + * construction). |
6 | 7 | * |
7 | 8 | * Multiple svc_key values with identical build inputs share the same handler. |
8 | 9 | * svc_key remains the request routing key and flush targeting key. |
|
15 | 16 | * databaseIdToBuildKeys: databaseId → Set<buildKey> |
16 | 17 | */ |
17 | 18 |
|
18 | | -import { createHash } from 'node:crypto'; |
19 | 19 | import { createServer } from 'node:http'; |
20 | 20 | import { Logger } from '@pgpmjs/logger'; |
21 | 21 | import express from 'express'; |
@@ -54,6 +54,13 @@ export interface MultiTenancyCacheStats { |
54 | 54 | inflightCreations: number; |
55 | 55 | } |
56 | 56 |
|
| 57 | +interface BuildKeyParts { |
| 58 | + conn: string; |
| 59 | + schemas: string[]; |
| 60 | + anonRole: string; |
| 61 | + roleName: string; |
| 62 | +} |
| 63 | + |
57 | 64 | // --- Internal state --- |
58 | 65 |
|
59 | 66 | /** buildKey → TenantInstance (the real handler cache) */ |
@@ -163,20 +170,24 @@ function getPoolIdentity(pool: Pool): string { |
163 | 170 | * - svc_key (routing-only) |
164 | 171 | * - databaseId (metadata-only) |
165 | 172 | * - token data, host/domain, transient headers |
| 173 | + * |
| 174 | + * The buildKey is intentionally stored as a canonical plain-text string |
| 175 | + * rather than a truncated hash so there is no collision risk between |
| 176 | + * different tenant build inputs. |
166 | 177 | */ |
167 | 178 | export function computeBuildKey( |
168 | 179 | pool: Pool, |
169 | 180 | schemas: string[], |
170 | 181 | anonRole: string, |
171 | 182 | roleName: string, |
172 | 183 | ): string { |
173 | | - const input = JSON.stringify({ |
| 184 | + const input: BuildKeyParts = { |
174 | 185 | conn: getPoolIdentity(pool), |
175 | 186 | schemas, |
176 | 187 | anonRole, |
177 | 188 | roleName, |
178 | | - }); |
179 | | - return createHash('sha256').update(input).digest('hex').slice(0, 16); |
| 189 | + }; |
| 190 | + return JSON.stringify(input); |
180 | 191 | } |
181 | 192 |
|
182 | 193 | // --- Index management --- |
|
0 commit comments