@shipfox/api-runners 7.0.1 → 7.1.0
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/.turbo/turbo-build.log +11 -13
- package/CHANGELOG.md +23 -0
- package/dist/presentation/routes/poll-demand.d.ts.map +1 -1
- package/dist/presentation/routes/poll-demand.js +15 -1
- package/dist/presentation/routes/poll-demand.js.map +1 -1
- package/dist/temporal/workflows/index.bundle.js +17164 -3306
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/package.json +9 -29
- package/src/db/runner-instances.test.ts +47 -0
- package/src/presentation/routes/poll-demand.ts +13 -1
- package/tsconfig.build.tsbuildinfo +1 -1
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,21 +1,19 @@
|
|
|
1
1
|
$ shipfox-swc && shipfox-temporal-bundle dist/temporal/workflows/index.js
|
|
2
|
-
Successfully compiled: 94 files with swc (
|
|
3
|
-
2026-07-
|
|
4
|
-
|
|
5
|
-
modules
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
modules by path ../../../node_modules/.pnpm/nexus-rpc@0.0.2/node_modules/nexus-rpc/lib/ 22.3 KiB 13 modules
|
|
9
|
-
+ 2 modules
|
|
10
|
-
modules by path ./dist/ 2.91 KiB
|
|
2
|
+
Successfully compiled: 94 files with swc (690.58ms)
|
|
3
|
+
2026-07-22T13:11:53.643Z [INFO] asset workflow-bundle-0c3da2487e29e352d64e.js 3.17 MiB [emitted] [immutable] (name: main)
|
|
4
|
+
orphan modules 33.5 KiB [orphan] 21 modules
|
|
5
|
+
runtime modules 1.13 KiB 5 modules
|
|
6
|
+
modules by path ../../../node_modules/.pnpm/ 970 KiB 196 modules
|
|
7
|
+
modules by path ./dist/ 3.31 KiB
|
|
11
8
|
modules by path ./dist/temporal/workflows/*.js 2.35 KiB
|
|
12
9
|
./dist/temporal/workflows/index.js 61 bytes [built] [code generated]
|
|
13
10
|
./dist/temporal/workflows/stuck-job-detector.js 2.29 KiB [built] [code generated]
|
|
14
|
-
./dist/temporal/workflows/index-autogenerated-entrypoint.cjs
|
|
11
|
+
./dist/temporal/workflows/index-autogenerated-entrypoint.cjs 932 bytes [built] [code generated]
|
|
15
12
|
./dist/core/maintenance-policy.js 49 bytes [built] [code generated]
|
|
16
13
|
optional modules 30 bytes [optional]
|
|
17
14
|
__temporal_custom_payload_converter (ignored) 15 bytes [optional] [built] [code generated]
|
|
18
15
|
__temporal_custom_failure_converter (ignored) 15 bytes [optional] [built] [code generated]
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
16
|
+
../../shared/node/temporal/dist/workflow-error-interceptor.js 1.21 KiB [built] [code generated]
|
|
17
|
+
webpack 5.107.2 compiled successfully in 8618 ms
|
|
18
|
+
2026-07-22T13:11:53.658Z [INFO] Workflow bundle created { size: '3.17MB' }
|
|
19
|
+
/home/runner/work/shipfox/shipfox/libs/api/runners/dist/temporal/workflows/index.js: 3326598 bytes
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
# @shipfox/api-runners
|
|
2
2
|
|
|
3
|
+
## 7.1.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- ac42c96: Adds boundary-owned reporting for unexpected API runtime failures while preserving expected client and provider outcomes.
|
|
8
|
+
- Updated dependencies [ac42c96]
|
|
9
|
+
- Updated dependencies [769d919]
|
|
10
|
+
- Updated dependencies [6ce08c0]
|
|
11
|
+
- @shipfox/node-error-monitoring@0.2.0
|
|
12
|
+
- @shipfox/node-fastify@0.3.0
|
|
13
|
+
- @shipfox/node-module@0.5.0
|
|
14
|
+
- @shipfox/node-temporal@0.4.0
|
|
15
|
+
- @shipfox/api-auth-dto@7.1.0
|
|
16
|
+
- @shipfox/node-opentelemetry@0.6.0
|
|
17
|
+
- @shipfox/api-auth-context@7.1.0
|
|
18
|
+
|
|
19
|
+
## 7.0.2
|
|
20
|
+
|
|
21
|
+
### Patch Changes
|
|
22
|
+
|
|
23
|
+
- Updated dependencies [81c8f33]
|
|
24
|
+
- @shipfox/node-auth-root-key@0.2.1
|
|
25
|
+
|
|
3
26
|
## 7.0.1
|
|
4
27
|
|
|
5
28
|
### Patch Changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"poll-demand.d.ts","sourceRoot":"","sources":["../../../src/presentation/routes/poll-demand.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"poll-demand.d.ts","sourceRoot":"","sources":["../../../src/presentation/routes/poll-demand.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAC,0BAA0B,EAAC,MAAM,+BAA+B,CAAC;AAe9E,wBAAgB,qBAAqB,CAAC,OAAO,GAAE,0BAA+B,mDA4F7E;AAED,eAAO,MAAM,eAAe,iDAA0B,CAAC"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { requireProvisionerContext, requireWorkspaceProvisionerContext } from '@shipfox/api-auth-context';
|
|
2
2
|
import { pollDemandBodySchema, pollDemandResponseSchema } from '@shipfox/api-runners-dto';
|
|
3
|
+
import { reportError } from '@shipfox/node-error-monitoring';
|
|
3
4
|
import { ClientError, defineRoute } from '@shipfox/node-fastify';
|
|
5
|
+
import { logger } from '@shipfox/node-opentelemetry';
|
|
4
6
|
import { config } from '#config.js';
|
|
5
7
|
import { pollDemand, releaseReservationGrants } from '#core/demand.js';
|
|
6
8
|
import { publishWorkspaceProvisionerCapabilitySnapshot } from '#db/provisioner-capability-snapshots.js';
|
|
@@ -37,7 +39,19 @@ export function createPollDemandRoute(options = {}) {
|
|
|
37
39
|
reply.raw.on('close', ()=>{
|
|
38
40
|
if (!responseFinished) {
|
|
39
41
|
abortController.abort();
|
|
40
|
-
void releaseReservationGrants(responseReservations).catch(()=>
|
|
42
|
+
void releaseReservationGrants(responseReservations).catch((error)=>{
|
|
43
|
+
logger().error({
|
|
44
|
+
err: error,
|
|
45
|
+
reservationCount: responseReservations.length
|
|
46
|
+
}, 'Failed to release reservations after provisioner disconnect');
|
|
47
|
+
reportError(error, {
|
|
48
|
+
boundary: 'runners.cleanup',
|
|
49
|
+
operation: 'release-disconnected-reservations',
|
|
50
|
+
extra: {
|
|
51
|
+
reservationCount: responseReservations.length
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
});
|
|
41
55
|
}
|
|
42
56
|
});
|
|
43
57
|
const provisionerContext = requireProvisionerContext(request);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/presentation/routes/poll-demand.ts"],"sourcesContent":["import {\n requireProvisionerContext,\n requireWorkspaceProvisionerContext,\n} from '@shipfox/api-auth-context';\nimport type {PollDemandTemplateDto} from '@shipfox/api-runners-dto';\nimport {pollDemandBodySchema, pollDemandResponseSchema} from '@shipfox/api-runners-dto';\nimport {ClientError, defineRoute} from '@shipfox/node-fastify';\nimport {config} from '#config.js';\nimport {pollDemand, releaseReservationGrants} from '#core/demand.js';\nimport {publishWorkspaceProvisionerCapabilitySnapshot} from '#db/provisioner-capability-snapshots.js';\nimport {\n listQueuedDemandWorkspaceIds,\n pollInstallationDemandAndReserve,\n type ReservationGrant,\n type ReservationTemplate,\n} from '#db/reservations.js';\nimport type {CreateRunnersModuleOptions} from '#installation-provisioning.js';\nimport {toPollDemandResponseDto} from '#presentation/dto/index.js';\n\nconst TERMINATE_INTENT_LIMIT = 1000;\n\nfunction toReservationTemplates(templates: PollDemandTemplateDto[]): ReservationTemplate[] {\n return templates.map((template) => ({\n templateKey: template.template_key,\n labels: template.labels,\n availableSlots: template.available_slots,\n starting: template.starting,\n running: template.running,\n }));\n}\n\nexport function createPollDemandRoute(options: CreateRunnersModuleOptions = {}) {\n return defineRoute({\n method: 'POST',\n path: '/demand/poll',\n description: 'Poll aggregate runner demand and reserve capacity for a provisioner',\n schema: {\n body: pollDemandBodySchema,\n response: {\n 200: pollDemandResponseSchema,\n },\n },\n handler: async (request, reply) => {\n const abortController = new AbortController();\n let responseFinished = false;\n let responseReservations: ReservationGrant[] = [];\n reply.raw.on('finish', () => {\n responseFinished = true;\n });\n reply.raw.on('close', () => {\n if (!responseFinished) {\n abortController.abort();\n void releaseReservationGrants(responseReservations).catch(() =>
|
|
1
|
+
{"version":3,"sources":["../../../src/presentation/routes/poll-demand.ts"],"sourcesContent":["import {\n requireProvisionerContext,\n requireWorkspaceProvisionerContext,\n} from '@shipfox/api-auth-context';\nimport type {PollDemandTemplateDto} from '@shipfox/api-runners-dto';\nimport {pollDemandBodySchema, pollDemandResponseSchema} from '@shipfox/api-runners-dto';\nimport {reportError} from '@shipfox/node-error-monitoring';\nimport {ClientError, defineRoute} from '@shipfox/node-fastify';\nimport {logger} from '@shipfox/node-opentelemetry';\nimport {config} from '#config.js';\nimport {pollDemand, releaseReservationGrants} from '#core/demand.js';\nimport {publishWorkspaceProvisionerCapabilitySnapshot} from '#db/provisioner-capability-snapshots.js';\nimport {\n listQueuedDemandWorkspaceIds,\n pollInstallationDemandAndReserve,\n type ReservationGrant,\n type ReservationTemplate,\n} from '#db/reservations.js';\nimport type {CreateRunnersModuleOptions} from '#installation-provisioning.js';\nimport {toPollDemandResponseDto} from '#presentation/dto/index.js';\n\nconst TERMINATE_INTENT_LIMIT = 1000;\n\nfunction toReservationTemplates(templates: PollDemandTemplateDto[]): ReservationTemplate[] {\n return templates.map((template) => ({\n templateKey: template.template_key,\n labels: template.labels,\n availableSlots: template.available_slots,\n starting: template.starting,\n running: template.running,\n }));\n}\n\nexport function createPollDemandRoute(options: CreateRunnersModuleOptions = {}) {\n return defineRoute({\n method: 'POST',\n path: '/demand/poll',\n description: 'Poll aggregate runner demand and reserve capacity for a provisioner',\n schema: {\n body: pollDemandBodySchema,\n response: {\n 200: pollDemandResponseSchema,\n },\n },\n handler: async (request, reply) => {\n const abortController = new AbortController();\n let responseFinished = false;\n let responseReservations: ReservationGrant[] = [];\n reply.raw.on('finish', () => {\n responseFinished = true;\n });\n reply.raw.on('close', () => {\n if (!responseFinished) {\n abortController.abort();\n void releaseReservationGrants(responseReservations).catch((error) => {\n logger().error(\n {err: error, reservationCount: responseReservations.length},\n 'Failed to release reservations after provisioner disconnect',\n );\n reportError(error, {\n boundary: 'runners.cleanup',\n operation: 'release-disconnected-reservations',\n extra: {reservationCount: responseReservations.length},\n });\n });\n }\n });\n const provisionerContext = requireProvisionerContext(request);\n if (provisionerContext.scope === 'installation') {\n if (!options.installationProvisioning) {\n throw new ClientError(\n 'Installation provisioner credentials are not accepted on this host',\n 'forbidden',\n {\n status: 403,\n },\n );\n }\n const candidateWorkspaceIds = await listQueuedDemandWorkspaceIds();\n const eligibleWorkspaceIds =\n await options.installationProvisioning.policy.filterEligibleWorkspaceIds(\n candidateWorkspaceIds,\n );\n const templates = toReservationTemplates(request.body.templates);\n const result = await pollInstallationDemandAndReserve({\n provisionerId: provisionerContext.provisionerTokenId,\n maxReservations: request.body.max_reservations,\n ttlSeconds: config.RESERVATION_TTL_SECONDS,\n templates,\n capabilityWindowSeconds: config.PROVISIONER_ACTIVE_WINDOW_SECONDS,\n eligibleWorkspaceIds,\n signal: abortController.signal,\n onReservations: (reservations) => {\n responseReservations.push(...reservations);\n },\n });\n return toPollDemandResponseDto({\n ...result,\n terminateRunnerInstanceIds: [],\n });\n }\n const {provisionerTokenId, workspaceId} = requireWorkspaceProvisionerContext(request);\n\n const templates = toReservationTemplates(request.body.templates);\n await publishWorkspaceProvisionerCapabilitySnapshot({\n workspaceId,\n provisionerId: provisionerTokenId,\n templates,\n });\n\n const result = await pollDemand({\n workspaceId,\n provisionerId: provisionerTokenId,\n maxReservations: request.body.max_reservations,\n waitSeconds: request.body.wait_seconds,\n ttlSeconds: config.RESERVATION_TTL_SECONDS,\n terminateIntentLimit: TERMINATE_INTENT_LIMIT,\n templates,\n signal: abortController.signal,\n });\n responseReservations = result.reservations;\n\n return toPollDemandResponseDto(result);\n },\n });\n}\n\nexport const pollDemandRoute = createPollDemandRoute();\n"],"names":["requireProvisionerContext","requireWorkspaceProvisionerContext","pollDemandBodySchema","pollDemandResponseSchema","reportError","ClientError","defineRoute","logger","config","pollDemand","releaseReservationGrants","publishWorkspaceProvisionerCapabilitySnapshot","listQueuedDemandWorkspaceIds","pollInstallationDemandAndReserve","toPollDemandResponseDto","TERMINATE_INTENT_LIMIT","toReservationTemplates","templates","map","template","templateKey","template_key","labels","availableSlots","available_slots","starting","running","createPollDemandRoute","options","method","path","description","schema","body","response","handler","request","reply","abortController","AbortController","responseFinished","responseReservations","raw","on","abort","catch","error","err","reservationCount","length","boundary","operation","extra","provisionerContext","scope","installationProvisioning","status","candidateWorkspaceIds","eligibleWorkspaceIds","policy","filterEligibleWorkspaceIds","result","provisionerId","provisionerTokenId","maxReservations","max_reservations","ttlSeconds","RESERVATION_TTL_SECONDS","capabilityWindowSeconds","PROVISIONER_ACTIVE_WINDOW_SECONDS","signal","onReservations","reservations","push","terminateRunnerInstanceIds","workspaceId","waitSeconds","wait_seconds","terminateIntentLimit","pollDemandRoute"],"mappings":"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"}
|