UNPKG

@datalayer/core

Version:

[![Datalayer](https://assets.datalayer.tech/datalayer-25.svg)](https://datalayer.io)

230 lines (229 loc) 9.99 kB
/* * Copyright (c) 2023-2025 Datalayer, Inc. * Distributed under the terms of the Modified BSD License. */ /** * Runtimes mixin for managing computational environments and runtime instances. * @module client/mixins/RuntimesMixin */ import * as environments from '../../api/runtimes/environments'; import * as runtimes from '../../api/runtimes/runtimes'; import * as snapshots from '../../api/runtimes/snapshots'; import { EnvironmentDTO } from '../../models/EnvironmentDTO'; import { RuntimeDTO } from '../../models/RuntimeDTO'; import { RuntimeSnapshotDTO } from '../../models/RuntimeSnapshotDTO'; import { HealthCheck } from '../../models/HealthCheck'; /** Runtimes mixin providing computational environment and runtime management. */ export function RuntimesMixin(Base) { return class extends Base { // ======================================================================== // Helper Functions // ======================================================================== _extractRuntimePodName(runtimePodNameOrInstance) { return typeof runtimePodNameOrInstance === 'string' ? runtimePodNameOrInstance : runtimePodNameOrInstance.podName; } _extractSnapshotId(snapshotIdOrInstance) { return typeof snapshotIdOrInstance === 'string' ? snapshotIdOrInstance : snapshotIdOrInstance.uid; } // ======================================================================== // Environments // ======================================================================== /** * List all available computational environments. * @returns Array of Environment model instances */ async listEnvironments() { const token = this.getToken(); const runtimesRunUrl = this.getRuntimesRunUrl(); const response = await environments.listEnvironments(token, runtimesRunUrl); // Save for later use after first call this.environments = response.environments.map(env => new EnvironmentDTO(env, this)); return this.environments; } // ======================================================================== // Runtimes // ======================================================================== /** * Create a new computational runtime. * @param environmentName - Name of the environment to use * @param type - Type of runtime * @param givenName - User-friendly name for the runtime * @param creditsLimit - Credits limit * @returns Created runtime */ async createRuntime(environmentName, type, givenName, minutesLimit, fromSnapshotId) { if (!this.environments) { await this.listEnvironments(); } if (this.environments) { const env = this.environments.find((e) => e.name === environmentName); if (!env) { throw new Error(`Environment "${environmentName}" not found. Available environments: ${this.environments.map((e) => e.name).join(', ')}`); } else { const token = this.getToken(); const runtimesRunUrl = this.getRuntimesRunUrl(); const creditsLimit = this.calculateCreditsFromMinutes(minutesLimit, env.burningRate); const data = { environment_name: environmentName, type, given_name: givenName, credits_limit: creditsLimit, from: fromSnapshotId, }; const response = await runtimes.createRuntime(token, data, runtimesRunUrl); return new RuntimeDTO(response.runtime, this); } } else { throw new Error('Environments not loaded'); } } /** * List all runtimes. * @returns Array of runtimes */ async listRuntimes() { const token = this.getToken(); const runtimesRunUrl = this.getRuntimesRunUrl(); const response = await runtimes.listRuntimes(token, runtimesRunUrl); return response.runtimes.map(r => new RuntimeDTO(r, this)); } /** * Get details for a specific runtime by pod name. * @param podName - Runtime pod name * @returns Runtime details */ async getRuntime(podName) { const token = this.getToken(); const runtimesRunUrl = this.getRuntimesRunUrl(); const runtimeData = await runtimes.getRuntime(token, podName, runtimesRunUrl); return new RuntimeDTO(runtimeData, this); } /** * Delete a runtime permanently. * @param podName - Runtime pod name */ async deleteRuntime(podName) { const token = this.getToken(); const runtimesRunUrl = this.getRuntimesRunUrl(); await runtimes.deleteRuntime(token, podName, runtimesRunUrl); } /** * Terminate all runtimes. * Lists all runtimes and deletes them in parallel. * @returns Array of results for each deletion (fulfilled or rejected) */ async terminateAllRuntimes() { const token = this.getToken(); const runtimesRunUrl = this.getRuntimesRunUrl(); // List all runtimes const response = await runtimes.listRuntimes(token, runtimesRunUrl); // Delete all runtimes in parallel const deletePromises = response.runtimes.map(runtime => runtimes.deleteRuntime(token, runtime.pod_name, runtimesRunUrl)); return Promise.allSettled(deletePromises); } // ======================================================================== // Snapshots // ======================================================================== /** * Create a snapshot of a runtime. * @param podName - Pod name of the runtime to snapshot * @param name - Name for the snapshot * @param description - Description of the snapshot * @param stop - Whether to stop the runtime after creating snapshot (defaults to false) * @returns Created snapshot */ async createSnapshot(podName, name, description, stop = false) { const token = this.getToken(); const runtimesRunUrl = this.getRuntimesRunUrl(); const data = { pod_name: podName, name, description, stop, }; const response = await snapshots.createSnapshot(token, data, runtimesRunUrl); return new RuntimeSnapshotDTO(response.snapshot, this); } /** * List all runtime snapshots. * @returns Array of snapshots */ async listSnapshots() { const token = this.getToken(); const runtimesRunUrl = this.getRuntimesRunUrl(); const response = await snapshots.listSnapshots(token, runtimesRunUrl); return response.snapshots.map(s => new RuntimeSnapshotDTO(s, this)); } /** * Get details for a specific snapshot by ID. * @param id - Snapshot ID * @returns Snapshot details */ async getSnapshot(id) { const token = this.getToken(); const runtimesRunUrl = this.getRuntimesRunUrl(); const response = await snapshots.getSnapshot(token, id, runtimesRunUrl); return new RuntimeSnapshotDTO(response.snapshot, this); } /** * Delete a snapshot permanently. * @param id - Snapshot ID */ async deleteSnapshot(id) { const token = this.getToken(); const runtimesRunUrl = this.getRuntimesRunUrl(); await snapshots.deleteSnapshot(token, id, runtimesRunUrl); } // ======================================================================== // Service Health Checks // ======================================================================== /** * Check the health status of the Runtimes service. * @returns Health check result with status and response time */ async checkRuntimesHealth() { const startTime = Date.now(); const errors = []; let status = 'unknown'; let healthy = false; try { // Test basic connectivity by listing environments (lightweight operation) const environments = await this.listEnvironments(); const responseTime = Date.now() - startTime; if (Array.isArray(environments)) { healthy = true; status = 'operational'; } else { status = 'degraded'; errors.push('Unexpected response format from environments endpoint'); } return new HealthCheck({ healthy, status, responseTime, errors, timestamp: new Date(), }, this); } catch (error) { const responseTime = Date.now() - startTime; status = 'down'; errors.push(`Service unreachable: ${error}`); return new HealthCheck({ healthy: false, status, responseTime, errors, timestamp: new Date(), }, this); } } }; }