mirror of
https://github.com/whyour/qinglong.git
synced 2026-09-22 19:29:13 +08:00
feat(ql3): establish 3.0 incubation baseline
This commit is contained in:
+103
@@ -0,0 +1,103 @@
|
||||
// Remote Execution transport owns fenced lease-control exchange.
|
||||
import {
|
||||
MAX_REMOTE_WORKER_LEASE_CONTROL_REQUEST_BYTES,
|
||||
MAX_REMOTE_WORKER_LEASE_CONTROL_RESPONSE_BYTES,
|
||||
createRemoteWorkerLeaseControlRequestBody,
|
||||
parseRemoteWorkerLeaseControlResponse,
|
||||
type RemoteWorkerLeaseControlCommand,
|
||||
type RemoteWorkerLeaseControlResult,
|
||||
} from '@qinglong/runtime-core/remote-worker-lease-control';
|
||||
import {
|
||||
WorkerIngressHttpsClient,
|
||||
WorkerIngressHttpsClientError,
|
||||
} from './workerIngressHttpsClient';
|
||||
|
||||
export interface WorkerRemoteLeaseControlClient {
|
||||
control(
|
||||
command: RemoteWorkerLeaseControlCommand,
|
||||
): Promise<Readonly<RemoteWorkerLeaseControlResult>>;
|
||||
}
|
||||
|
||||
export interface WorkerRemoteLeaseControlHttpsClientOptions {
|
||||
readonly client: WorkerIngressHttpsClient;
|
||||
}
|
||||
|
||||
export class WorkerRemoteLeaseControlHttpsError extends Error {
|
||||
constructor(
|
||||
readonly reason:
|
||||
| 'invalid_configuration'
|
||||
| 'request_invalid'
|
||||
| 'transport_unavailable'
|
||||
| 'response_invalid',
|
||||
options?: ErrorOptions,
|
||||
) {
|
||||
super(`Worker remote lease control failed: ${reason}`, options);
|
||||
this.name = 'WorkerRemoteLeaseControlHttpsError';
|
||||
}
|
||||
}
|
||||
|
||||
function path(command: RemoteWorkerLeaseControlCommand): string {
|
||||
return '/api/v3/worker-ingress/workers/' + command.workerId +
|
||||
'/sessions/' + command.workerSessionId + '/lease-control';
|
||||
}
|
||||
|
||||
export class WorkerRemoteLeaseControlHttpsClient
|
||||
implements WorkerRemoteLeaseControlClient {
|
||||
private readonly client: WorkerIngressHttpsClient;
|
||||
|
||||
constructor(options: WorkerRemoteLeaseControlHttpsClientOptions) {
|
||||
if (!options || !(options.client instanceof WorkerIngressHttpsClient)) {
|
||||
throw new WorkerRemoteLeaseControlHttpsError('invalid_configuration');
|
||||
}
|
||||
this.client = options.client;
|
||||
}
|
||||
|
||||
async control(
|
||||
command: RemoteWorkerLeaseControlCommand,
|
||||
): Promise<Readonly<RemoteWorkerLeaseControlResult>> {
|
||||
let body;
|
||||
try {
|
||||
body = createRemoteWorkerLeaseControlRequestBody(command);
|
||||
} catch (error) {
|
||||
throw new WorkerRemoteLeaseControlHttpsError(
|
||||
'request_invalid', { cause: error },
|
||||
);
|
||||
}
|
||||
let serialized: Uint8Array;
|
||||
try {
|
||||
serialized = await this.client.postJson({
|
||||
path: path(command),
|
||||
body,
|
||||
maximumRequestBytes: MAX_REMOTE_WORKER_LEASE_CONTROL_REQUEST_BYTES,
|
||||
maximumResponseBytes: MAX_REMOTE_WORKER_LEASE_CONTROL_RESPONSE_BYTES,
|
||||
});
|
||||
} catch (error) {
|
||||
if (error instanceof WorkerIngressHttpsClientError) {
|
||||
throw new WorkerRemoteLeaseControlHttpsError(
|
||||
'transport_unavailable', { cause: error },
|
||||
);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
try {
|
||||
const result = parseRemoteWorkerLeaseControlResponse(serialized);
|
||||
if (
|
||||
result.projectId !== command.projectId ||
|
||||
result.runId !== command.runId ||
|
||||
result.attemptId !== command.attemptId ||
|
||||
result.offerId !== command.offerId ||
|
||||
result.leaseGeneration !== command.leaseGeneration ||
|
||||
(result.status !== 'terminal' &&
|
||||
result.leaseVersion !== command.expectedLeaseVersion + 1)
|
||||
) throw new TypeError('lease control response authority mismatch');
|
||||
return result;
|
||||
} catch (error) {
|
||||
throw new WorkerRemoteLeaseControlHttpsError(
|
||||
'response_invalid', { cause: error },
|
||||
);
|
||||
} finally {
|
||||
Buffer.from(serialized.buffer, serialized.byteOffset, serialized.byteLength)
|
||||
.fill(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user