@highstate/backend 0.9.16 → 0.9.18
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-NAAIDR4U.js +8499 -0
- package/dist/chunk-NAAIDR4U.js.map +1 -0
- package/dist/chunk-OU5OQBLB.js +74 -0
- package/dist/chunk-OU5OQBLB.js.map +1 -0
- package/dist/{chunk-WHALQHEZ.js → chunk-Y7DXREVO.js} +502 -774
- package/dist/chunk-Y7DXREVO.js.map +1 -0
- package/dist/highstate.manifest.json +4 -4
- package/dist/index.js +2979 -2233
- package/dist/index.js.map +1 -1
- package/dist/library/package-resolution-worker.js +7 -5
- package/dist/library/package-resolution-worker.js.map +1 -1
- package/dist/library/worker/main.js +40 -41
- package/dist/library/worker/main.js.map +1 -1
- package/dist/magic-string.es-5ABAC4JN.js +1292 -0
- package/dist/magic-string.es-5ABAC4JN.js.map +1 -0
- package/dist/shared/index.js +3 -216
- package/dist/shared/index.js.map +1 -1
- package/package.json +9 -6
- package/src/artifact/encryption.ts +47 -7
- package/src/artifact/factory.ts +2 -2
- package/src/artifact/local.ts +2 -6
- package/src/business/__traces__/secret/update-instance-secrets/create-and-delete-secrets-simultaneously.md +356 -0
- package/src/business/__traces__/secret/update-instance-secrets/create-new-secrets-for-instance.md +274 -0
- package/src/business/__traces__/secret/update-instance-secrets/delete-existing-secrets.md +223 -0
- package/src/business/__traces__/secret/update-instance-secrets/no-op-when-no-changes.md +147 -0
- package/src/business/__traces__/secret/update-instance-secrets/update-existing-secrets.md +280 -0
- package/src/business/__traces__/worker/update-unit-registrations/add-new-unit-registration-when-other-exists.md +360 -0
- package/src/business/__traces__/worker/update-unit-registrations/add-new-unit-registration.md +215 -0
- package/src/business/__traces__/worker/update-unit-registrations/create-multiple-workers-with-different-identities.md +427 -0
- package/src/business/__traces__/worker/update-unit-registrations/handle-nonexistent-registration-id-gracefully.md +217 -0
- package/src/business/__traces__/worker/update-unit-registrations/no-op-when-no-changes.md +132 -0
- package/src/business/__traces__/worker/update-unit-registrations/recreate-worker-when-image-changes.md +454 -0
- package/src/business/__traces__/worker/update-unit-registrations/recreate-worker-when-image-version-changes.md +426 -0
- package/src/business/__traces__/worker/update-unit-registrations/recreate-worker-with-same-identity-reuses-service-account.md +372 -0
- package/src/business/__traces__/worker/update-unit-registrations/remove-one-of-multiple-unit-registrations.md +383 -0
- package/src/business/__traces__/worker/update-unit-registrations/remove-unit-registration.md +245 -0
- package/src/business/__traces__/worker/update-unit-registrations/update-existing-unit-registration-when-params-change.md +174 -0
- package/src/business/__traces__/worker/update-unit-registrations/update-params-and-image-simultaneously.md +432 -0
- package/src/business/__traces__/worker/update-unit-registrations/worker-with-multiple-registrations-not-deleted-when-one-removed.md +220 -0
- package/src/business/artifact.ts +2 -1
- package/src/business/index.ts +1 -0
- package/src/business/instance-lock.ts +3 -2
- package/src/business/instance-state.ts +202 -60
- package/src/business/project-unlock.ts +41 -23
- package/src/business/project.ts +299 -0
- package/src/business/secret.test.ts +178 -0
- package/src/business/secret.ts +139 -45
- package/src/business/worker.test.ts +614 -0
- package/src/business/worker.ts +289 -52
- package/src/common/clock.ts +18 -0
- package/src/common/index.ts +3 -0
- package/src/common/random.ts +68 -0
- package/src/common/test/index.ts +2 -0
- package/src/common/test/render.ts +98 -0
- package/src/common/test/tracer.ts +359 -0
- package/src/config.ts +5 -1
- package/src/hotstate/manager.ts +8 -8
- package/src/hotstate/validation.ts +0 -1
- package/src/library/abstractions.ts +20 -11
- package/src/library/local.ts +6 -13
- package/src/library/worker/evaluator.ts +30 -34
- package/src/library/worker/loader.lite.ts +13 -0
- package/src/library/worker/main.ts +8 -8
- package/src/library/worker/protocol.ts +0 -11
- package/src/lock/index.ts +1 -0
- package/src/lock/manager.ts +17 -2
- package/src/lock/test.ts +108 -0
- package/src/orchestrator/manager.ts +17 -36
- package/src/orchestrator/operation-workset.ts +34 -37
- package/src/orchestrator/operation.ts +129 -74
- package/src/project/abstractions.ts +27 -51
- package/src/project/evaluation.ts +248 -0
- package/src/project/index.ts +1 -1
- package/src/project/local.ts +75 -127
- package/src/pubsub/manager.ts +21 -13
- package/src/runner/abstractions.ts +29 -9
- package/src/runner/artifact-env.ts +3 -3
- package/src/runner/local.ts +29 -19
- package/src/runner/pulumi.ts +4 -1
- package/src/services.ts +77 -24
- package/src/shared/models/backend/library.ts +4 -4
- package/src/shared/models/backend/project.ts +25 -6
- package/src/shared/models/backend/unlock-method.ts +1 -1
- package/src/shared/models/base.ts +1 -84
- package/src/shared/models/project/api-key.ts +5 -2
- package/src/shared/models/project/artifact.ts +3 -33
- package/src/shared/models/project/index.ts +1 -2
- package/src/shared/models/project/lock.ts +3 -3
- package/src/shared/models/project/model.ts +14 -0
- package/src/shared/models/project/operation.ts +3 -3
- package/src/shared/models/project/page.ts +3 -3
- package/src/shared/models/project/secret.ts +4 -18
- package/src/shared/models/project/service-account.ts +2 -2
- package/src/shared/models/project/state.ts +32 -15
- package/src/shared/models/project/terminal.ts +4 -5
- package/src/shared/models/project/trigger.ts +1 -1
- package/src/shared/models/project/unlock-method.ts +9 -2
- package/src/shared/models/project/worker.ts +9 -7
- package/src/shared/resolvers/graph-resolver.ts +41 -26
- package/src/shared/resolvers/input.ts +47 -5
- package/src/shared/resolvers/validation.ts +23 -7
- package/src/shared/utils/args.ts +25 -0
- package/src/shared/utils/index.ts +1 -0
- package/src/state/abstractions.ts +98 -259
- package/src/state/encryption.ts +39 -0
- package/src/state/index.ts +1 -0
- package/src/state/local/backend.ts +29 -222
- package/src/state/local/collection.ts +105 -86
- package/src/state/manager.ts +358 -287
- package/src/state/memory/backend.ts +70 -0
- package/src/state/memory/collection.ts +270 -0
- package/src/state/memory/index.ts +2 -0
- package/src/state/repository/repository.index.ts +1 -1
- package/src/state/repository/repository.ts +71 -22
- package/src/state/test.ts +457 -0
- package/src/unlock/abstractions.ts +49 -0
- package/src/unlock/index.ts +2 -0
- package/src/unlock/memory.ts +32 -0
- package/src/worker/manager.ts +28 -0
- package/dist/chunk-RCB4AFGD.js +0 -159
- package/dist/chunk-RCB4AFGD.js.map +0 -1
- package/dist/chunk-WHALQHEZ.js.map +0 -1
- package/src/project/manager.ts +0 -574
- package/src/shared/models/project/component.ts +0 -45
- package/src/shared/models/project/instance.ts +0 -74
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import type { WorkerData
|
|
1
|
+
import type { WorkerData } from "./protocol"
|
|
2
2
|
import { parentPort, workerData } from "node:worker_threads"
|
|
3
3
|
import { pino } from "pino"
|
|
4
4
|
import { errorToString } from "../../common"
|
|
5
|
-
import {
|
|
5
|
+
import { evaluateProject } from "./evaluator"
|
|
6
6
|
import { loadComponents } from "./loader.lite"
|
|
7
7
|
|
|
8
8
|
const data = workerData as WorkerData
|
|
9
9
|
|
|
10
|
-
const logger = pino({ name: "library-worker"
|
|
10
|
+
const logger = pino({ name: "library-worker" })
|
|
11
11
|
|
|
12
12
|
try {
|
|
13
13
|
const library = await loadComponents(logger, data.libraryModulePaths)
|
|
14
14
|
|
|
15
|
-
const
|
|
15
|
+
const result = evaluateProject(
|
|
16
16
|
logger,
|
|
17
17
|
library,
|
|
18
18
|
data.allInstances,
|
|
@@ -20,12 +20,12 @@ try {
|
|
|
20
20
|
data.instanceIds,
|
|
21
21
|
)
|
|
22
22
|
|
|
23
|
-
parentPort!.postMessage(
|
|
23
|
+
parentPort!.postMessage(result)
|
|
24
24
|
} catch (error) {
|
|
25
|
-
logger.error({ error }, "failed to evaluate")
|
|
25
|
+
logger.error({ error }, "failed to evaluate project")
|
|
26
26
|
|
|
27
27
|
parentPort!.postMessage({
|
|
28
|
-
|
|
28
|
+
success: false,
|
|
29
29
|
error: errorToString(error),
|
|
30
|
-
}
|
|
30
|
+
})
|
|
31
31
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { InstanceModel } from "@highstate/contract"
|
|
2
|
-
import type { InstanceEvaluationResult } from "../abstractions"
|
|
3
2
|
import type { ResolvedInstanceInput } from "../../shared"
|
|
4
3
|
|
|
5
4
|
export type WorkerData = {
|
|
@@ -10,13 +9,3 @@ export type WorkerData = {
|
|
|
10
9
|
resolvedInputs: Record<string, Record<string, ResolvedInstanceInput[]>>
|
|
11
10
|
instanceIds: string[]
|
|
12
11
|
}
|
|
13
|
-
|
|
14
|
-
export type WorkerResponse =
|
|
15
|
-
| {
|
|
16
|
-
type: "results"
|
|
17
|
-
results: InstanceEvaluationResult[]
|
|
18
|
-
}
|
|
19
|
-
| {
|
|
20
|
-
type: "error"
|
|
21
|
-
error: string
|
|
22
|
-
}
|
package/src/lock/index.ts
CHANGED
package/src/lock/manager.ts
CHANGED
|
@@ -3,9 +3,24 @@ import { join } from "remeda"
|
|
|
3
3
|
|
|
4
4
|
export type LockKeyMap = {
|
|
5
5
|
/**
|
|
6
|
-
* Lock for
|
|
6
|
+
* Lock for the project names to ensure uniqueness.
|
|
7
7
|
*/
|
|
8
|
-
project: [
|
|
8
|
+
"project-name": [name: string]
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Lock for instances and hubs of the project.
|
|
12
|
+
*/
|
|
13
|
+
"project-nodes": [projectId: string]
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Locks for the evaluation of the project.
|
|
17
|
+
*/
|
|
18
|
+
"project-evaluation": [projectId: string]
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Lock for all instance states of the project.
|
|
22
|
+
*/
|
|
23
|
+
"project-instance-states": [projectId: string]
|
|
9
24
|
|
|
10
25
|
/**
|
|
11
26
|
* Lock for a specific instance within a project.
|
package/src/lock/test.ts
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import type { Fixtures } from "@vitest/runner"
|
|
2
|
+
import type { LockKey } from "./manager"
|
|
3
|
+
import { linkTraceEntry, renderTraceEntry, type TestTracer, type TraceEntry } from "../common"
|
|
4
|
+
import { LockManager } from "./manager"
|
|
5
|
+
import { MemoryLockBackend } from "./memory"
|
|
6
|
+
|
|
7
|
+
class LockAcquireEntry implements TraceEntry {
|
|
8
|
+
releaseEntry?: TraceEntry
|
|
9
|
+
|
|
10
|
+
constructor(
|
|
11
|
+
readonly id: number,
|
|
12
|
+
private readonly keys: string[],
|
|
13
|
+
) {}
|
|
14
|
+
|
|
15
|
+
render(): string {
|
|
16
|
+
return renderTraceEntry({
|
|
17
|
+
icon: "🔒",
|
|
18
|
+
title: this.releaseEntry
|
|
19
|
+
? `locked, released at ${linkTraceEntry(this.releaseEntry)}`
|
|
20
|
+
: "locked",
|
|
21
|
+
fields: {
|
|
22
|
+
keys: {
|
|
23
|
+
value: this.keys,
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
})
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
class LockReleaseEntry implements TraceEntry {
|
|
31
|
+
constructor(
|
|
32
|
+
readonly id: number,
|
|
33
|
+
private readonly keys: string[],
|
|
34
|
+
private readonly acquireEntry: TraceEntry,
|
|
35
|
+
) {}
|
|
36
|
+
|
|
37
|
+
render(): string {
|
|
38
|
+
return renderTraceEntry({
|
|
39
|
+
icon: "🔓",
|
|
40
|
+
title: `released, locked at ${linkTraceEntry(this.acquireEntry)}`,
|
|
41
|
+
fields: {
|
|
42
|
+
keys: {
|
|
43
|
+
value: this.keys,
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
})
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
class TestLockManager {
|
|
51
|
+
constructor(
|
|
52
|
+
private readonly lockManager: LockManager,
|
|
53
|
+
private readonly tracer: TestTracer,
|
|
54
|
+
) {}
|
|
55
|
+
|
|
56
|
+
async acquire<T>(keys: LockKey | LockKey[], fn: () => Promise<T> | T): Promise<T> {
|
|
57
|
+
const keyStrings = this.formatKeys(keys)
|
|
58
|
+
|
|
59
|
+
// add acquire trace entry
|
|
60
|
+
const acquireEntry = new LockAcquireEntry(this.tracer.nextEntryId(), keyStrings)
|
|
61
|
+
this.tracer.addEntry(acquireEntry)
|
|
62
|
+
|
|
63
|
+
try {
|
|
64
|
+
const result = await this.lockManager.acquire(keys, fn)
|
|
65
|
+
|
|
66
|
+
// add release trace entry
|
|
67
|
+
const releaseEntry = new LockReleaseEntry(this.tracer.nextEntryId(), keyStrings, acquireEntry)
|
|
68
|
+
this.tracer.addEntry(releaseEntry)
|
|
69
|
+
|
|
70
|
+
// link acquire entry to release entry
|
|
71
|
+
acquireEntry.releaseEntry = releaseEntry
|
|
72
|
+
|
|
73
|
+
return result
|
|
74
|
+
} catch (error) {
|
|
75
|
+
// add release trace entry even on error
|
|
76
|
+
const releaseEntry = new LockReleaseEntry(this.tracer.nextEntryId(), keyStrings, acquireEntry)
|
|
77
|
+
this.tracer.addEntry(releaseEntry)
|
|
78
|
+
|
|
79
|
+
// link acquire entry to release entry
|
|
80
|
+
acquireEntry.releaseEntry = releaseEntry
|
|
81
|
+
|
|
82
|
+
throw error
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
private formatKeys(keys: LockKey | LockKey[]): string[] {
|
|
87
|
+
if (typeof keys[0] === "string") {
|
|
88
|
+
return [keys.join(":")]
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return keys.map(key => key.join(":"))
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export const lockFixtures: Fixtures<
|
|
96
|
+
{
|
|
97
|
+
lockManager: LockManager
|
|
98
|
+
},
|
|
99
|
+
{ tracer: TestTracer }
|
|
100
|
+
> = {
|
|
101
|
+
lockManager: async ({ tracer }, use) => {
|
|
102
|
+
const backend = MemoryLockBackend.create()
|
|
103
|
+
const baseLockManager = new LockManager(backend)
|
|
104
|
+
const testLockManager = new TestLockManager(baseLockManager, tracer) as unknown as LockManager
|
|
105
|
+
|
|
106
|
+
await use(testLockManager)
|
|
107
|
+
},
|
|
108
|
+
}
|
|
@@ -10,10 +10,16 @@ import type {
|
|
|
10
10
|
SecretService,
|
|
11
11
|
ProjectUnlockService,
|
|
12
12
|
InstanceStateService,
|
|
13
|
+
WorkerService,
|
|
13
14
|
} from "../business"
|
|
14
15
|
import type { PubSubManager } from "../pubsub"
|
|
15
16
|
import { v7 as uuidv7 } from "uuid"
|
|
16
|
-
import {
|
|
17
|
+
import {
|
|
18
|
+
isFinalOperationStatus,
|
|
19
|
+
type Operation,
|
|
20
|
+
type OperationRequest,
|
|
21
|
+
type Project,
|
|
22
|
+
} from "../shared"
|
|
17
23
|
import { RuntimeOperation } from "./operation"
|
|
18
24
|
|
|
19
25
|
export class OperationManager {
|
|
@@ -29,6 +35,7 @@ export class OperationManager {
|
|
|
29
35
|
private readonly secretService: SecretService,
|
|
30
36
|
private readonly instanceStateService: InstanceStateService,
|
|
31
37
|
private readonly pubsubManager: PubSubManager,
|
|
38
|
+
private readonly workerService: WorkerService,
|
|
32
39
|
private readonly logger: Logger,
|
|
33
40
|
) {
|
|
34
41
|
this.stateUnlockService.registerUnlockTask(
|
|
@@ -74,7 +81,12 @@ export class OperationManager {
|
|
|
74
81
|
|
|
75
82
|
await this.operationService.updateOperation(request.projectId, operation)
|
|
76
83
|
|
|
77
|
-
this.
|
|
84
|
+
const project = await this.stateManager.getProjectRepository().get(request.projectId)
|
|
85
|
+
if (!project) {
|
|
86
|
+
throw new Error(`Project with ID "${request.projectId}" not found`)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
this.startOperation(project, operation)
|
|
78
90
|
|
|
79
91
|
return operation
|
|
80
92
|
}
|
|
@@ -97,9 +109,9 @@ export class OperationManager {
|
|
|
97
109
|
}
|
|
98
110
|
}
|
|
99
111
|
|
|
100
|
-
private startOperation(
|
|
112
|
+
private startOperation(project: Project, operation: Operation): void {
|
|
101
113
|
const runtimeOperation = new RuntimeOperation(
|
|
102
|
-
|
|
114
|
+
project,
|
|
103
115
|
operation,
|
|
104
116
|
this.runnerBackend,
|
|
105
117
|
this.libraryBackend,
|
|
@@ -111,6 +123,7 @@ export class OperationManager {
|
|
|
111
123
|
this.secretService,
|
|
112
124
|
this.instanceStateService,
|
|
113
125
|
this.pubsubManager,
|
|
126
|
+
this.workerService,
|
|
114
127
|
this.logger.child({ operationId: operation.id }),
|
|
115
128
|
)
|
|
116
129
|
|
|
@@ -182,36 +195,4 @@ export class OperationManager {
|
|
|
182
195
|
projectId,
|
|
183
196
|
)
|
|
184
197
|
}
|
|
185
|
-
|
|
186
|
-
static create(
|
|
187
|
-
runnerBackend: RunnerBackend,
|
|
188
|
-
libraryBackend: LibraryBackend,
|
|
189
|
-
projectBackend: ProjectBackend,
|
|
190
|
-
artifactManager: ArtifactService,
|
|
191
|
-
stateManager: StateManager,
|
|
192
|
-
instanceLockService: InstanceLockService,
|
|
193
|
-
stateUnlockService: ProjectUnlockService,
|
|
194
|
-
operationService: OperationService,
|
|
195
|
-
secretService: SecretService,
|
|
196
|
-
instanceService: InstanceStateService,
|
|
197
|
-
pubsubManager: PubSubManager,
|
|
198
|
-
logger: Logger,
|
|
199
|
-
): OperationManager {
|
|
200
|
-
const operator = new OperationManager(
|
|
201
|
-
runnerBackend,
|
|
202
|
-
libraryBackend,
|
|
203
|
-
projectBackend,
|
|
204
|
-
artifactManager,
|
|
205
|
-
stateManager,
|
|
206
|
-
instanceLockService,
|
|
207
|
-
stateUnlockService,
|
|
208
|
-
operationService,
|
|
209
|
-
secretService,
|
|
210
|
-
instanceService,
|
|
211
|
-
pubsubManager,
|
|
212
|
-
logger.child({ service: "OperationManager" }),
|
|
213
|
-
)
|
|
214
|
-
|
|
215
|
-
return operator
|
|
216
|
-
}
|
|
217
198
|
}
|
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
type InstanceStatePatch,
|
|
24
24
|
type LibraryModel,
|
|
25
25
|
type Operation,
|
|
26
|
+
type Project,
|
|
26
27
|
type ResolvedInstanceInput,
|
|
27
28
|
} from "../shared"
|
|
28
29
|
|
|
@@ -62,10 +63,9 @@ export class OperationWorkset {
|
|
|
62
63
|
private readonly lockEventEmitter = new EventEmitter()
|
|
63
64
|
|
|
64
65
|
private constructor(
|
|
65
|
-
public readonly
|
|
66
|
+
public readonly project: Project,
|
|
66
67
|
public readonly operation: Operation,
|
|
67
68
|
public readonly library: LibraryModel,
|
|
68
|
-
public readonly libraryId: string,
|
|
69
69
|
private readonly instanceLockService: InstanceLockService,
|
|
70
70
|
private readonly instanceStateService: InstanceStateService,
|
|
71
71
|
private readonly logger: Logger,
|
|
@@ -116,7 +116,7 @@ export class OperationWorkset {
|
|
|
116
116
|
|
|
117
117
|
public async patchState(patch: InstanceStatePatch): Promise<InstanceState> {
|
|
118
118
|
const state = await this.instanceStateService.patchOperationInstanceState(
|
|
119
|
-
this.
|
|
119
|
+
this.project.id,
|
|
120
120
|
this.operation,
|
|
121
121
|
patch,
|
|
122
122
|
)
|
|
@@ -168,7 +168,12 @@ export class OperationWorkset {
|
|
|
168
168
|
instanceId,
|
|
169
169
|
)
|
|
170
170
|
|
|
171
|
-
await this.instanceStateService.updateInstanceStates(
|
|
171
|
+
await this.instanceStateService.updateInstanceStates(
|
|
172
|
+
this.project.id,
|
|
173
|
+
[initialState],
|
|
174
|
+
true,
|
|
175
|
+
false,
|
|
176
|
+
)
|
|
172
177
|
|
|
173
178
|
if (initialState.parentId) {
|
|
174
179
|
await this.recalculateCompositeInstanceState(initialState.parentId)
|
|
@@ -185,7 +190,12 @@ export class OperationWorkset {
|
|
|
185
190
|
}
|
|
186
191
|
}
|
|
187
192
|
|
|
188
|
-
await this.instanceStateService.updateInstanceStates(
|
|
193
|
+
await this.instanceStateService.updateInstanceStates(
|
|
194
|
+
this.project.id,
|
|
195
|
+
instanceStates,
|
|
196
|
+
false,
|
|
197
|
+
false,
|
|
198
|
+
)
|
|
189
199
|
}
|
|
190
200
|
|
|
191
201
|
public getAffectedCompositeChildren(instanceId: string): InstanceModel[] {
|
|
@@ -532,7 +542,7 @@ export class OperationWorkset {
|
|
|
532
542
|
*/
|
|
533
543
|
public async tryLock(instancesToLock?: string[]): Promise<void> {
|
|
534
544
|
const [, lockedInstanceIds] = await this.instanceLockService.tryLockInstances(
|
|
535
|
-
this.
|
|
545
|
+
this.project.id,
|
|
536
546
|
instancesToLock ?? Array.from(this.instanceIdsToLockIds),
|
|
537
547
|
{
|
|
538
548
|
title: "Operation Lock",
|
|
@@ -552,7 +562,7 @@ export class OperationWorkset {
|
|
|
552
562
|
}
|
|
553
563
|
|
|
554
564
|
public static async load(
|
|
555
|
-
|
|
565
|
+
project: Project,
|
|
556
566
|
operation: Operation,
|
|
557
567
|
projectBackend: ProjectBackend,
|
|
558
568
|
libraryBackend: LibraryBackend,
|
|
@@ -562,59 +572,46 @@ export class OperationWorkset {
|
|
|
562
572
|
logger: Logger,
|
|
563
573
|
signal: AbortSignal,
|
|
564
574
|
): Promise<OperationWorkset> {
|
|
565
|
-
//
|
|
566
|
-
const
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
const [library, project, compositeInstances, states] = await Promise.all([
|
|
573
|
-
libraryBackend.loadLibrary(projectInfo.libraryId, signal),
|
|
574
|
-
projectBackend.getProject(projectId, signal),
|
|
575
|
-
compositeInstanceRepo.getAllItems(),
|
|
576
|
-
instanceStateService.getInstanceStates(projectId),
|
|
575
|
+
// TODO: use hotstate for virtual instances
|
|
576
|
+
const [library, { instances, hubs }, virtualInstances, states] = await Promise.all([
|
|
577
|
+
libraryBackend.loadLibrary(project.libraryId, signal),
|
|
578
|
+
projectBackend.getProjectModel(project, signal),
|
|
579
|
+
stateManager.getVirtualInstanceRepository(project.id).getAllItems(),
|
|
580
|
+
instanceStateService.getInstanceStates(project.id),
|
|
577
581
|
])
|
|
578
582
|
|
|
579
583
|
const workset = new OperationWorkset(
|
|
580
|
-
|
|
584
|
+
project,
|
|
581
585
|
operation,
|
|
582
586
|
library,
|
|
583
|
-
projectInfo.libraryId,
|
|
584
587
|
instanceLockService,
|
|
585
588
|
instanceStateService,
|
|
586
589
|
logger.child({ operationId: operation.id, service: "OperationWorkset" }),
|
|
587
590
|
)
|
|
588
591
|
|
|
589
592
|
// prepare instances
|
|
590
|
-
for (const instance of
|
|
593
|
+
for (const instance of instances) {
|
|
591
594
|
workset.addInstance(instance)
|
|
592
595
|
}
|
|
593
596
|
|
|
594
|
-
for (const instance of
|
|
595
|
-
const worksetInstance = workset.instanceMap.get(instance.
|
|
597
|
+
for (const instance of virtualInstances) {
|
|
598
|
+
const worksetInstance = workset.instanceMap.get(instance.id)
|
|
596
599
|
|
|
597
600
|
if (worksetInstance) {
|
|
598
|
-
worksetInstance.outputs = instance.
|
|
599
|
-
worksetInstance.resolvedOutputs = instance.
|
|
600
|
-
} else if (instance.
|
|
601
|
-
workset.addInstance(instance
|
|
601
|
+
worksetInstance.outputs = instance.outputs
|
|
602
|
+
worksetInstance.resolvedOutputs = instance.resolvedOutputs
|
|
603
|
+
} else if (instance.parentId) {
|
|
604
|
+
workset.addInstance(instance)
|
|
602
605
|
} else {
|
|
603
606
|
workset.logger.warn(
|
|
604
|
-
`ignoring instance "${instance.
|
|
607
|
+
`ignoring virtual instance "${instance.id}" because it is not in the project or is not a part of known composite instance`,
|
|
605
608
|
)
|
|
606
609
|
continue
|
|
607
610
|
}
|
|
608
|
-
|
|
609
|
-
for (const child of instance.children) {
|
|
610
|
-
if (!workset.instanceMap.has(child.id)) {
|
|
611
|
-
workset.addInstance(child)
|
|
612
|
-
}
|
|
613
|
-
}
|
|
614
611
|
}
|
|
615
612
|
|
|
616
613
|
const unitSources = await libraryBackend.getResolvedUnitSources(
|
|
617
|
-
|
|
614
|
+
project.libraryId,
|
|
618
615
|
unique(Array.from(workset.instanceMap.values()).map(i => i.type)),
|
|
619
616
|
)
|
|
620
617
|
|
|
@@ -642,7 +639,7 @@ export class OperationWorkset {
|
|
|
642
639
|
})
|
|
643
640
|
}
|
|
644
641
|
|
|
645
|
-
for (const hub of
|
|
642
|
+
for (const hub of hubs) {
|
|
646
643
|
workset.inputResolverNodes.set(`hub:${hub.id}`, { kind: "hub", hub })
|
|
647
644
|
}
|
|
648
645
|
|