Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/src/packages/jupyter/kernel/kernel-data.ts
Views: 687
/*1* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.2* License: MS-RSL – see LICENSE.md for details3*/45/*6Use nteracts kernelspecs module to get data about all installed Jupyter kernels.78The result is cached for 10s to avoid wasted effort in case of a flurry of calls.910Specs: https://jupyter-client.readthedocs.io/en/stable/kernels.html#kernel-specs11*/1213import { findAll } from "kernelspecs";14import LRU from "lru-cache";15import type { KernelSpec } from "@cocalc/jupyter/types/types";16import { field_cmp } from "@cocalc/util/misc";17import { reuseInFlight } from "@cocalc/util/reuse-in-flight";1819const cache = new LRU<"kernel_data", KernelSpec[]>({20ttl: 15 * 1000,21max: 5 /* silly since only one possible key */,22});2324/**25* just an edge case for Macaulay2. Full data looks like this:26* m2: {27name: 'm2',28files: [ ... ],29resources_dir: '...',30spec: {31argv: [...],32display_name: 'M2',33language: 'text/x-macaulay2',34codemirror_mode: 'macaulay2'35}36},37*/38function spec2language(spec): string {39if (spec.language === "text/x-macaulay2") {40return "Macaulay2";41} else {42return spec.language;43}44}4546// this is very expensive and can get called many times at once before47// the cache is set, which is very bad... so reuseInFlight.48export const get_kernel_data = reuseInFlight(49async (): Promise<KernelSpec[]> => {50let x = cache.get("kernel_data");51if (x != null) {52return x;53}54const kernel_data = await findAll();55const v: KernelSpec[] = [];56for (const kernel in kernel_data) {57const value = kernel_data[kernel];58v.push({59name: kernel.toLowerCase(),60display_name: value.spec.display_name,61language: spec2language(value.spec),62// @ts-ignore63interrupt_mode: value.spec.interrupt_mode,64env: value.spec.env ?? {},65// @ts-ignore66metadata: value.spec.metadata,67// kernelspecs incorrectly calls it resources_dir instead of resource_dir.68// See https://github.com/nteract/kernelspecs/issues/2569// @ts-ignore70resource_dir: value.resource_dir ?? value.resources_dir,71argv: value.spec.argv,72});73}74v.sort(field_cmp("display_name"));75cache.set("kernel_data", v);76return v;77},78);7980export async function getLanguage(kernelName: string): Promise<string> {81const kernelSpec = await get_kernel_data_by_name(kernelName);82if (kernelSpec != null) {83return kernelSpec.language;84}85throw Error(`unknown kernel ${kernelName}`);86}8788export async function get_kernel_data_by_name(89name: string,90): Promise<KernelSpec> {91name = name.toLowerCase();92const kernel_data = await get_kernel_data();93for (const kernel of kernel_data) {94if (kernel.name == name) {95return kernel;96}97}98throw Error(`no such kernel '${name}'`);99}100101102