orez-sync-cf-host 0.4.63 → 0.4.64
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/host.ts +18 -3
- package/src/ingest-harness-worker.ts +11 -2
package/package.json
CHANGED
package/src/host.ts
CHANGED
|
@@ -690,7 +690,8 @@ export function createSyncDurableObject<Env extends SyncHostEnv>(
|
|
|
690
690
|
async #fetchDelegatedPush(
|
|
691
691
|
endpoint: URL,
|
|
692
692
|
headers: Headers,
|
|
693
|
-
body: ArrayBuffer
|
|
693
|
+
body: ArrayBuffer,
|
|
694
|
+
provisioning = false
|
|
694
695
|
): Promise<Response> {
|
|
695
696
|
const binding = this.#serviceBinding(
|
|
696
697
|
config.mutateBinding ?? config.upstream?.binding
|
|
@@ -703,7 +704,9 @@ export function createSyncDurableObject<Env extends SyncHostEnv>(
|
|
|
703
704
|
method: 'POST',
|
|
704
705
|
headers,
|
|
705
706
|
body,
|
|
706
|
-
signal: AbortSignal.timeout(
|
|
707
|
+
signal: AbortSignal.timeout(
|
|
708
|
+
provisioning ? Math.max(delegateTimeoutMs, 25_000) : delegateTimeoutMs
|
|
709
|
+
),
|
|
707
710
|
})
|
|
708
711
|
} catch (error) {
|
|
709
712
|
lastError = error
|
|
@@ -1048,7 +1051,8 @@ export function createSyncDurableObject<Env extends SyncHostEnv>(
|
|
|
1048
1051
|
const upstreamResponse = await this.#fetchDelegatedPush(
|
|
1049
1052
|
endpoint,
|
|
1050
1053
|
headers,
|
|
1051
|
-
bytes
|
|
1054
|
+
bytes,
|
|
1055
|
+
this.#engineState()?.upstreamWatermark === '0'
|
|
1052
1056
|
)
|
|
1053
1057
|
if (!upstreamResponse.ok) {
|
|
1054
1058
|
return new Response(upstreamResponse.body, upstreamResponse)
|
|
@@ -1477,6 +1481,17 @@ export function createSyncDurableObject<Env extends SyncHostEnv>(
|
|
|
1477
1481
|
return this.#pull(request, claims, namespace)
|
|
1478
1482
|
}
|
|
1479
1483
|
if (route === '/push' && request.method === 'POST') {
|
|
1484
|
+
// A push may be the first request for a fresh namespace. DATA's
|
|
1485
|
+
// /changes call is also its schema-provisioning barrier, so complete it
|
|
1486
|
+
// before delegating the mutation to APP. Pull already enforces this
|
|
1487
|
+
// ordering above; skipping it here let APP race half-created tables and
|
|
1488
|
+
// surface a terminal, bodyless 500 to Zero.
|
|
1489
|
+
try {
|
|
1490
|
+
await this.#ingest(upstreamPath)
|
|
1491
|
+
} catch (error) {
|
|
1492
|
+
await request.arrayBuffer()
|
|
1493
|
+
return json(errorBody(error), statusOf(error))
|
|
1494
|
+
}
|
|
1480
1495
|
return this.#push(request, claims, namespace, upstreamPath)
|
|
1481
1496
|
}
|
|
1482
1497
|
return json({ error: 'not found' }, 404)
|
|
@@ -29,6 +29,7 @@ interface Env extends SyncHostEnv {
|
|
|
29
29
|
|
|
30
30
|
const runawayNamespaces = new Set<string>()
|
|
31
31
|
const numericTextNamespaces = new Set<string>()
|
|
32
|
+
const hydratedNamespaces = new Set<string>()
|
|
32
33
|
let delegatedFailuresRemaining = 0
|
|
33
34
|
let delegatedAttempts = 0
|
|
34
35
|
|
|
@@ -96,7 +97,7 @@ async function upstreamFetch(request: Request, env: Env): Promise<Response> {
|
|
|
96
97
|
|
|
97
98
|
/** Self service-binding target backed by the real ZeroSqlDO. */
|
|
98
99
|
export class DataService extends WorkerEntrypoint<Env> {
|
|
99
|
-
fetch(request: Request): Promise<Response> {
|
|
100
|
+
async fetch(request: Request): Promise<Response> {
|
|
100
101
|
const url = new URL(request.url)
|
|
101
102
|
const pathname = url.pathname
|
|
102
103
|
if (
|
|
@@ -170,7 +171,9 @@ export class DataService extends WorkerEntrypoint<Env> {
|
|
|
170
171
|
})
|
|
171
172
|
)
|
|
172
173
|
}
|
|
173
|
-
|
|
174
|
+
const response = await upstreamFetch(request, this.env)
|
|
175
|
+
if (pathname.endsWith('/changes') && response.ok) hydratedNamespaces.add(namespace)
|
|
176
|
+
return response
|
|
174
177
|
}
|
|
175
178
|
}
|
|
176
179
|
|
|
@@ -181,6 +184,12 @@ export class AppService extends WorkerEntrypoint<Env> {
|
|
|
181
184
|
new Response('APP route rejected non-push request', { status: 418 })
|
|
182
185
|
)
|
|
183
186
|
}
|
|
187
|
+
const namespace = new URL(request.url).pathname.split('/')[1] ?? ''
|
|
188
|
+
if (!hydratedNamespaces.has(namespace)) {
|
|
189
|
+
return Promise.resolve(
|
|
190
|
+
Response.json({ error: 'schema provisioning has not completed' }, { status: 500 })
|
|
191
|
+
)
|
|
192
|
+
}
|
|
184
193
|
delegatedAttempts++
|
|
185
194
|
if (delegatedFailuresRemaining > 0) {
|
|
186
195
|
delegatedFailuresRemaining--
|