Skip to content

Commit

Permalink
fix: improvements for deferring load of ink npm
Browse files Browse the repository at this point in the history
  • Loading branch information
starpit committed Apr 17, 2023
1 parent b20be34 commit 66dd77d
Show file tree
Hide file tree
Showing 25 changed files with 150 additions and 89 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ import type { JobRec, HostRec, PodRec, OnData, UpdatePayload, Resource, Resource
import defaultValueFor from "./defaults.js"
import { Breakdown, ValidResources } from "./types.js"

import { themes } from "../../controller/dashboard/utilization/theme.js"
import { defaultUtilizationThemes } from "../../controller/dashboard/grids.js"
import { themes } from "../../controller/dashboard/job/utilization/theme.js"
import { defaultUtilizationThemes } from "../../controller/dashboard/job/grids.js"

type UI = {
/** Force a refresh */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import type { TextProps } from "ink"

import type HistoryConfig from "../history.js"
import type { OnData } from "../../../components/Job/types.js"
import type { OnData } from "../../../../components/Job/types.js"

import { update } from "../history.js"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

import type { Worker } from "../../components/Job/types.js"
import type { Worker } from "../../../components/Job/types.js"

/** Configuration governining the history model of states per worker */
type HistoryConfig = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,74 +16,21 @@

import Debug from "debug"
import type { Arguments } from "@kui-shell/core"
import type Options from "./options.js"

import tailf from "./tailf.js"
import dashboardUI from "./db.js"
import tailf from "../tailf.js"
import usage from "../usage.js"
import dashboardUI from "../db.js"
import status from "./status/index.js"
import utilization from "./utilization/index.js"

import { enterAltBufferMode } from "./term.js"
import jobIdFrom from "./jobid.js"
import { enterAltBufferMode } from "../term.js"
import { KindA, isValidKindA } from "./kinds.js"
import { SupportedGrid, isSupportedGrid } from "./grids.js"
import { KindA, isValidKindA, validKinds } from "./kinds.js"

import type HistoryConfig from "./history.js"
import type { GridSpec } from "../../components/Job/types.js"

export type Options = Arguments["parsedOptions"] & {
s: number
scale: number

demo: boolean

p: string
profile: string
theme: string

/** Frequency of updates to the timeline, in seconds */
u: number
"update-frequency": number
}

export function usage(cmd: string, extraKinds: string[] = []) {
return `Usage: codeflare ${cmd} ${extraKinds.concat(validKinds()).join("|")} [<jobId>|-N]`
}

async function lastNJob(profile: string, N: number) {
const [{ join }, { readdir, stat }, { Profiles }] = await Promise.all([
import("path"),
import("fs/promises"),
import("madwizard"),
])

const dir = Profiles.guidebookJobDataPath({ profile })
const files = await readdir(dir)
if (files.length === 0) {
throw new Error("No jobs available")
return
}

const cTimes = await Promise.all(files.map((_) => stat(join(dir, _)).then((_) => _.ctime.getTime())))
const sorted = files.map((file, idx) => ({ file, lastM: cTimes[idx] })).sort((a, b) => b.lastM - a.lastM)

if (!sorted[N]) {
throw new Error("Specified historical job not available")
} else {
return sorted[N].file
}
}

export async function jobIdFrom(args: Arguments<Options>, cmd: string, offset = 2) {
const profile = args.parsedOptions.p || (await import("madwizard").then((_) => _.Profiles.lastUsed()))

const jobIdFromCommandLine = args.argvNoOptions[args.argvNoOptions.indexOf(cmd) + offset]
const jobId = /^-\d+$/.test(jobIdFromCommandLine)
? await lastNJob(profile, -parseInt(jobIdFromCommandLine, 10))
: jobIdFromCommandLine === undefined
? await lastNJob(profile, 0)
: jobIdFromCommandLine

return { jobId, profile }
}
import type { GridSpec } from "../../../components/Job/types.js"

/** @return grid model for the given `kind` for `jobId` in `profile` */
async function gridFor(
Expand All @@ -104,7 +51,7 @@ async function allGridsFor(
historyConfig: HistoryConfig,
opts: Pick<Options, "demo" | "theme" | "events">
) {
const usesGpus = opts.demo || (await import("../env.js").then((_) => _.usesGpus(profile, jobId)))
const usesGpus = opts.demo || (await import("../../env.js").then((_) => _.usesGpus(profile, jobId)))

const all = [
gridFor("status", profile, jobId, historyConfig, opts),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Copyright 2023 The Kubernetes Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import type { Arguments } from "@kui-shell/core"
import type Options from "./options.js"

async function lastNJob(profile: string, N: number) {
const [{ join }, { readdir, stat }, { Profiles }] = await Promise.all([
import("path"),
import("fs/promises"),
import("madwizard"),
])

const dir = Profiles.guidebookJobDataPath({ profile })
const files = await readdir(dir)
if (files.length === 0) {
throw new Error("No jobs available")
return
}

const cTimes = await Promise.all(files.map((_) => stat(join(dir, _)).then((_) => _.ctime.getTime())))
const sorted = files.map((file, idx) => ({ file, lastM: cTimes[idx] })).sort((a, b) => b.lastM - a.lastM)

if (!sorted[N]) {
throw new Error("Specified historical job not available")
} else {
return sorted[N].file
}
}

export default async function jobIdFrom(args: Arguments<Options>, cmd: string, offset = 2) {
const profile = args.parsedOptions.p || (await import("madwizard").then((_) => _.Profiles.lastUsed()))

const jobIdFromCommandLine = args.argvNoOptions[args.argvNoOptions.indexOf(cmd) + offset]
const jobId = /^-\d+$/.test(jobIdFromCommandLine)
? await lastNJob(profile, -parseInt(jobIdFromCommandLine, 10))
: jobIdFromCommandLine === undefined
? await lastNJob(profile, 0)
: jobIdFromCommandLine

return { jobId, profile }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright 2023 The Kubernetes Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import type { ParsedOptions } from "@kui-shell/core"

type Options = ParsedOptions & {
s: number
scale: number

demo: boolean

p: string
profile: string
theme: string

/** Frequency of updates to the timeline, in seconds */
u: number
"update-frequency": number
}

export default Options
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import type { TextProps } from "ink"

import type HistoryConfig from "../history.js"
import type { WorkerState } from "./states.js"
import type { OnData } from "../../../components/Job/types.js"
import type { OnData } from "../../../../components/Job/types.js"

import { states } from "./states.js"
import GenericDemo from "../generic/Demo.js"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ import ansiRegex from "ansi-regex"
import stripAnsi from "strip-ansi"
import type { TextProps } from "ink"

import stripColors from "../stripColors.js"
import stripColors from "../../stripColors.js"
import type Options from "../options.js"
import type { Tail } from "../tailf.js"
import type { Tail } from "../../tailf.js"
import type HistoryConfig from "../history.js"
import type { WorkerState } from "./states.js"
import type { OnData, Worker } from "../../../components/Job/types.js"
import type { OnData, Worker } from "../../../../components/Job/types.js"

import { rankFor, stateFor } from "./states.js"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@

import type { TextProps } from "ink"

import type { Tail } from "../tailf.js"
import type { Tail } from "../../tailf.js"
import type Options from "../options.js"
import type HistoryConfig from "../history.js"
import type { WorkerState } from "./states.js"
import type { OnData, GridSpec } from "../../../components/Job/types.js"
import type { OnData, GridSpec } from "../../../../components/Job/types.js"

import Demo from "./Demo.js"
import Live from "./Live.js"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import type { TextProps } from "ink"

import type HistoryConfig from "../history.js"
import type { WorkerState } from "./states.js"
import type { OnData } from "../../../components/Job/types.js"
import type { OnData } from "../../../../components/Job/types.js"

import { states } from "./states.js"
import GenericDemo from "../generic/Demo.js"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@
import stripAnsi from "strip-ansi"
import type { TextProps } from "ink"

import type { Tail } from "../tailf.js"
import type { Tail } from "../../tailf.js"
import type { WorkerState } from "./states.js"
import type HistoryConfig from "../history.js"
import type { OnData, Worker } from "../../../components/Job/types.js"
import type { OnData, Worker } from "../../../../components/Job/types.js"

import { states } from "./states.js"
import { update as updateHistory } from "../history.js"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@
import type { TextProps } from "ink"

import type Kind from "../kinds.js"
import type { Tail } from "../tailf.js"
import type { Tail } from "../../tailf.js"
import type Options from "../options.js"
import type HistoryConfig from "../history.js"
import type { WorkerState } from "./states.js"
import type { OnData, GridSpec } from "../../../components/Job/types.js"
import type { OnData, GridSpec } from "../../../../components/Job/types.js"
import { SupportedUtilizationGrid, defaultUtilizationThemes, providerFor } from "../grids.js"

import { states } from "./states.js"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import split2 from "split2"
import chokidar from "chokidar"
import TailFile from "@logdna/tail-file"

import Kind, { KindedSource, resourcePaths } from "./kinds.js"
import Kind, { KindedSource, resourcePaths } from "./job/kinds.js"

export type Tail = {
kind: Kind
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

import type { Arguments } from "@kui-shell/core"

import type { Options } from "./job.js"
import type Options from "./job/options.js"
import type { OnData, HostRec, PodRec, ResourceSpec, UpdatePayload } from "../../components/Top/types.js"

import { enterAltBufferMode } from "./term.js"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Copyright 2023 The Kubernetes Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import { validKinds } from "./job/kinds.js"

export default function usage(cmd: string, extraKinds: string[] = []) {
return `Usage: codeflare ${cmd} ${extraKinds.concat(validKinds()).join("|")} [<jobId>|-N]`
}
13 changes: 9 additions & 4 deletions plugins/plugin-codeflare-dashboard/src/controller/dump.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,10 @@
* limitations under the License.
*/

import { Arguments } from "@kui-shell/core"
import type { Arguments } from "@kui-shell/core"
import type DashboardOptions from "./dashboard/job/options.js"

import { pathsFor } from "./dashboard/tailf.js"
import { filepathOf, isValidKind } from "./dashboard/kinds.js"
import { Options as DashboardOptions, jobIdFrom, usage as dbUsage } from "./dashboard/job.js"
import dbUsage from "./dashboard/usage.js"

export type Options = DashboardOptions & {
f: boolean
Expand All @@ -36,6 +35,12 @@ function usage() {

/** Dump raw info, rather than nicely formatted into a dashboard */
export default async function dump(args: Arguments<Options>) {
const [{ pathsFor }, { filepathOf, isValidKind }, { default: jobIdFrom }] = await Promise.all([
import("./dashboard/tailf.js"),
import("./dashboard/job/kinds.js"),
import("./dashboard/job/jobid.js"),
])

// what kind of data are we being asked to show
const kind = args.argvNoOptions[args.argvNoOptions.indexOf("dump") + 1]

Expand Down
2 changes: 1 addition & 1 deletion plugins/plugin-codeflare-dashboard/src/controller/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import Debug from "debug"
import { join } from "path"

import { resourcePaths, filepathOf } from "./dashboard/kinds.js"
import { resourcePaths, filepathOf } from "./dashboard/job/kinds.js"

type NameValue = { name: string; value: unknown }

Expand Down
2 changes: 1 addition & 1 deletion plugins/plugin-codeflare-dashboard/src/controller/path.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

import type Kind from "./dashboard/kinds.js"
import type Kind from "./dashboard/job/kinds.js"
import { pathsFor } from "./dashboard/tailf.js"

/** @return path to the data captured for the given jobId in the given profile */
Expand Down
7 changes: 3 additions & 4 deletions plugins/plugin-codeflare-dashboard/src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,9 @@
* limitations under the License.
*/

import { KResponse, Registrar } from "@kui-shell/core"

import type { KResponse, Registrar } from "@kui-shell/core"
import type { MyOptions as TopOptions } from "./controller/dashboard/top.js"
import type { Options as DashboardOptions } from "./controller/dashboard/job.js"
import type DashboardOptions from "./controller/dashboard/job/options.js"

import { flags } from "./controller/dashboard/options.js"
import { Options as DumpOptions, flags as dumpFlags } from "./controller/dump.js"
Expand All @@ -26,7 +25,7 @@ import { Options as DumpOptions, flags as dumpFlags } from "./controller/dump.js
export default function registerCodeflareCommands(registrar: Registrar) {
registrar.listen<KResponse, DashboardOptions>(
`/codeflare/top/job`,
(args) => import("./controller/dashboard/job.js").then((_) => _.default(args)),
(args) => import("./controller/dashboard/job/index.js").then((_) => _.default(args)),
{ flags }
)

Expand Down

0 comments on commit 66dd77d

Please sign in to comment.