@highstate/backend 0.9.15 → 0.9.16
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/dist/chunk-RCB4AFGD.js +159 -0
- package/dist/chunk-RCB4AFGD.js.map +1 -0
- package/dist/chunk-WHALQHEZ.js +2017 -0
- package/dist/chunk-WHALQHEZ.js.map +1 -0
- package/dist/highstate.manifest.json +3 -3
- package/dist/index.js +6158 -2178
- package/dist/index.js.map +1 -1
- package/dist/library/worker/main.js +47 -155
- package/dist/library/worker/main.js.map +1 -1
- package/dist/shared/index.js +159 -41
- package/package.json +25 -7
- package/src/artifact/abstractions.ts +46 -0
- package/src/artifact/encryption.ts +69 -0
- package/src/artifact/factory.ts +36 -0
- package/src/artifact/index.ts +3 -0
- package/src/artifact/local.ts +142 -0
- package/src/business/api-key.ts +65 -0
- package/src/business/artifact.ts +288 -0
- package/src/business/backend-unlock.ts +10 -0
- package/src/business/index.ts +9 -0
- package/src/business/instance-lock.ts +124 -0
- package/src/business/instance-state.ts +292 -0
- package/src/business/operation.ts +251 -0
- package/src/business/project-unlock.ts +242 -0
- package/src/business/secret.ts +187 -0
- package/src/business/worker.ts +161 -0
- package/src/common/index.ts +2 -1
- package/src/common/performance.ts +44 -0
- package/src/common/tree.ts +33 -0
- package/src/common/utils.ts +40 -1
- package/src/config.ts +14 -10
- package/src/hotstate/abstractions.ts +48 -0
- package/src/hotstate/factory.ts +17 -0
- package/src/{secret → hotstate}/index.ts +1 -0
- package/src/hotstate/manager.ts +192 -0
- package/src/hotstate/memory.ts +100 -0
- package/src/hotstate/validation.ts +101 -0
- package/src/index.ts +2 -1
- package/src/library/abstractions.ts +10 -23
- package/src/library/factory.ts +2 -2
- package/src/library/local.ts +89 -102
- package/src/library/worker/evaluator.ts +9 -42
- package/src/library/worker/loader.lite.ts +41 -0
- package/src/library/worker/main.ts +14 -65
- package/src/library/worker/protocol.ts +8 -24
- package/src/lock/abstractions.ts +6 -0
- package/src/lock/factory.ts +15 -0
- package/src/{workspace → lock}/index.ts +1 -0
- package/src/lock/manager.ts +82 -0
- package/src/lock/memory.ts +19 -0
- package/src/orchestrator/manager.ts +129 -82
- package/src/orchestrator/operation-workset.ts +168 -77
- package/src/orchestrator/operation.ts +967 -284
- package/src/project/abstractions.ts +20 -7
- package/src/project/factory.ts +1 -1
- package/src/project/index.ts +0 -1
- package/src/project/local.ts +73 -17
- package/src/project/manager.ts +272 -131
- package/src/pubsub/abstractions.ts +13 -0
- package/src/pubsub/factory.ts +19 -0
- package/src/pubsub/index.ts +3 -0
- package/src/pubsub/local.ts +36 -0
- package/src/pubsub/manager.ts +100 -0
- package/src/pubsub/validation.ts +33 -0
- package/src/runner/abstractions.ts +135 -68
- package/src/runner/artifact-env.ts +160 -0
- package/src/runner/factory.ts +20 -5
- package/src/runner/force-abort.ts +117 -0
- package/src/runner/local.ts +281 -371
- package/src/{common → runner}/pulumi.ts +86 -37
- package/src/services.ts +193 -35
- package/src/shared/index.ts +3 -11
- package/src/shared/models/backend/index.ts +3 -0
- package/src/shared/models/backend/project.ts +63 -0
- package/src/shared/models/backend/unlock-method.ts +20 -0
- package/src/shared/models/base.ts +151 -0
- package/src/shared/models/errors.ts +5 -0
- package/src/shared/models/index.ts +4 -0
- package/src/shared/models/project/api-key.ts +62 -0
- package/src/shared/models/project/artifact.ts +113 -0
- package/src/shared/models/project/component.ts +45 -0
- package/src/shared/models/project/index.ts +14 -0
- package/src/shared/{project.ts → models/project/instance.ts} +12 -0
- package/src/shared/models/project/lock.ts +91 -0
- package/src/shared/{operation.ts → models/project/operation.ts} +28 -7
- package/src/shared/models/project/page.ts +57 -0
- package/src/shared/models/project/secret.ts +112 -0
- package/src/shared/models/project/service-account.ts +22 -0
- package/src/shared/models/project/state.ts +432 -0
- package/src/shared/models/project/terminal.ts +99 -0
- package/src/shared/models/project/trigger.ts +56 -0
- package/src/shared/models/project/unlock-method.ts +31 -0
- package/src/shared/models/project/worker.ts +105 -0
- package/src/shared/resolvers/graph-resolver.ts +28 -0
- package/src/shared/resolvers/index.ts +5 -0
- package/src/shared/resolvers/input-hash.ts +53 -15
- package/src/shared/resolvers/input.ts +1 -9
- package/src/shared/resolvers/registry.ts +3 -2
- package/src/shared/resolvers/state.ts +2 -2
- package/src/shared/resolvers/validation.ts +61 -20
- package/src/shared/{async-batcher.ts → utils/async-batcher.ts} +13 -1
- package/src/shared/utils/hash.ts +6 -0
- package/src/shared/utils/index.ts +3 -0
- package/src/shared/utils/promise-tracker.ts +23 -0
- package/src/state/abstractions.ts +330 -101
- package/src/state/encryption.ts +59 -0
- package/src/state/factory.ts +3 -5
- package/src/state/index.ts +3 -0
- package/src/state/keyring.ts +22 -0
- package/src/state/local/backend.ts +299 -0
- package/src/state/local/collection.ts +342 -0
- package/src/state/local/index.ts +2 -0
- package/src/state/manager.ts +804 -18
- package/src/state/repository/index.ts +2 -0
- package/src/state/repository/repository.index.ts +193 -0
- package/src/state/repository/repository.ts +458 -0
- package/src/terminal/{shared.ts → abstractions.ts} +3 -3
- package/src/terminal/docker.ts +18 -14
- package/src/terminal/factory.ts +3 -3
- package/src/terminal/index.ts +1 -1
- package/src/terminal/manager.ts +131 -79
- package/src/terminal/run.sh.ts +21 -11
- package/src/worker/abstractions.ts +42 -0
- package/src/worker/docker.ts +83 -0
- package/src/worker/factory.ts +20 -0
- package/src/worker/index.ts +3 -0
- package/src/worker/manager.ts +139 -0
- package/dist/chunk-KTGKNSKM.js +0 -979
- package/dist/chunk-KTGKNSKM.js.map +0 -1
- package/dist/chunk-WXDYCRTT.js +0 -234
- package/dist/chunk-WXDYCRTT.js.map +0 -1
- package/src/library/worker/loader.ts +0 -114
- package/src/preferences/shared.ts +0 -1
- package/src/project/lock.ts +0 -39
- package/src/secret/abstractions.ts +0 -59
- package/src/secret/factory.ts +0 -22
- package/src/secret/local.ts +0 -152
- package/src/shared/state.ts +0 -247
- package/src/shared/terminal.ts +0 -14
- package/src/state/local.ts +0 -612
- package/src/workspace/abstractions.ts +0 -41
- package/src/workspace/factory.ts +0 -14
- package/src/workspace/local.ts +0 -54
- /package/src/shared/{library.ts → models/backend/library.ts} +0 -0
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import type { Logger } from "pino"
|
|
2
|
+
import type { WorkerBackend } from "./abstractions"
|
|
3
|
+
import type { StateManager } from "../state"
|
|
4
|
+
import type { ApiKeyService, ProjectUnlockService } from "../business"
|
|
5
|
+
import type { LockManager } from "../lock"
|
|
6
|
+
import { PassThrough } from "node:stream"
|
|
7
|
+
import { z } from "zod"
|
|
8
|
+
import c from "ansi-colors"
|
|
9
|
+
import { v7 as uuidv7 } from "uuid"
|
|
10
|
+
import { createAsyncBatcher } from "../shared"
|
|
11
|
+
|
|
12
|
+
export const workerManagerConfig = z.object({
|
|
13
|
+
HIGHSTATE_WORKER_API_PATH: z.string().default("/var/run/highstate.sock"),
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
export class WorkerManager {
|
|
17
|
+
constructor(
|
|
18
|
+
readonly config: z.infer<typeof workerManagerConfig>,
|
|
19
|
+
private readonly workerBackend: WorkerBackend,
|
|
20
|
+
private readonly stateManager: StateManager,
|
|
21
|
+
private readonly projectUnlockService: ProjectUnlockService,
|
|
22
|
+
private readonly lockManager: LockManager,
|
|
23
|
+
private readonly apiKeyService: ApiKeyService,
|
|
24
|
+
private readonly logger: Logger,
|
|
25
|
+
) {
|
|
26
|
+
this.projectUnlockService.registerUnlockTask(
|
|
27
|
+
//
|
|
28
|
+
"launch-active-workers",
|
|
29
|
+
projectId => this.launchActiveWorkers(projectId),
|
|
30
|
+
)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async startWorker(projectId: string, workerId: string, restart = false): Promise<void> {
|
|
34
|
+
await this.lockManager.acquire(["worker", workerId], async () => {
|
|
35
|
+
const worker = await this.stateManager.getWorkerRepository(projectId).get(workerId)
|
|
36
|
+
if (!worker) {
|
|
37
|
+
throw new Error(`Worker "${workerId}" not found in project "${projectId}"`)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (!worker.apiKeyId) {
|
|
41
|
+
throw new Error(`Worker "${workerId}" does not have an API key associated`)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (worker.failedStartAttempts === 5) {
|
|
45
|
+
this.logger.debug(
|
|
46
|
+
{ projectId },
|
|
47
|
+
`skipping worker "%s" start attempt since no attempts left`,
|
|
48
|
+
worker.id,
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
return
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
worker.status = "starting"
|
|
55
|
+
|
|
56
|
+
if (restart) {
|
|
57
|
+
worker.failedStartAttempts += 1
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
await this.stateManager.getWorkerRepository(projectId).putItem(worker)
|
|
61
|
+
|
|
62
|
+
const apiKey = await this.apiKeyService.regenerateToken(projectId, worker.apiKeyId)
|
|
63
|
+
const stdout = new PassThrough()
|
|
64
|
+
|
|
65
|
+
await this.writeSystemMessage(
|
|
66
|
+
projectId,
|
|
67
|
+
worker.id,
|
|
68
|
+
`starting worker container, attempt ${worker.failedStartAttempts + 1}/5`,
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
const logBatcher = createAsyncBatcher<string>(async logs => {
|
|
72
|
+
await this.stateManager
|
|
73
|
+
.getWorkerLogRepository(projectId, worker.id)
|
|
74
|
+
.putMany(logs.map(log => [uuidv7(), log]))
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
stdout.on("data", chunk => {
|
|
78
|
+
const log = String(chunk)
|
|
79
|
+
|
|
80
|
+
logBatcher.call(log)
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
void this.workerBackend
|
|
84
|
+
.run({
|
|
85
|
+
projectId,
|
|
86
|
+
worker,
|
|
87
|
+
apiPath: this.config.HIGHSTATE_WORKER_API_PATH,
|
|
88
|
+
apiKey: apiKey.token,
|
|
89
|
+
stdout,
|
|
90
|
+
})
|
|
91
|
+
// regardless the exit reason, we want to restart the worker if it has remaining attempts
|
|
92
|
+
.finally(() => void this.startWorker(projectId, worker.id, true))
|
|
93
|
+
})
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
async writeSystemMessage(projectId: string, workerId: string, message: string): Promise<void> {
|
|
97
|
+
const prefix = c.bold.magenta("[runtime]")
|
|
98
|
+
|
|
99
|
+
await this.stateManager
|
|
100
|
+
.getWorkerLogRepository(projectId, workerId)
|
|
101
|
+
.put(uuidv7(), `${prefix} ${message}`)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
async setWorkerRunning(projectId: string, workerId: string): Promise<void> {
|
|
105
|
+
await this.lockManager.acquire(["worker", workerId], async () => {
|
|
106
|
+
const worker = await this.stateManager.getWorkerRepository(projectId).get(workerId)
|
|
107
|
+
if (!worker) {
|
|
108
|
+
throw new Error(`Worker "${workerId}" not found in project "${projectId}"`)
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
worker.status = "running"
|
|
112
|
+
worker.failedStartAttempts = 0
|
|
113
|
+
|
|
114
|
+
await this.stateManager.getWorkerRepository(projectId).putItem(worker)
|
|
115
|
+
|
|
116
|
+
this.logger.debug(
|
|
117
|
+
{ projectId, workerId },
|
|
118
|
+
`worker "%s" is now running in project "%s"`,
|
|
119
|
+
workerId,
|
|
120
|
+
projectId,
|
|
121
|
+
)
|
|
122
|
+
})
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
private async launchActiveWorkers(projectId: string): Promise<void> {
|
|
126
|
+
const workers = await this.stateManager.getWorkerRepository(projectId).getAllItems()
|
|
127
|
+
|
|
128
|
+
this.logger.debug(
|
|
129
|
+
{ projectId, workerCount: workers.length },
|
|
130
|
+
`launching %s active workers for project "%s"`,
|
|
131
|
+
workers.length,
|
|
132
|
+
projectId,
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
for (const worker of workers) {
|
|
136
|
+
void this.startWorker(projectId, worker.id)
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|