Files
windmill/cli/workers.ts
T
Ruben Fiszel bd6ddc166b feat(cli): add queues, workers and worker-groups commands (#4439)
* all

* all

* all

* all

* all

* all

* all

* all

* all

* all

* all

* all

* all

* all
2024-09-26 11:27:37 +02:00

106 lines
3.3 KiB
TypeScript

import { Command, Table } from "./deps.ts";
import { log } from "./deps.ts";
import * as wmill from "./gen/services.gen.ts";
import { pickInstance } from "./instance.ts";
type GlobalOptions = {
instance?: string;
baseUrl?: string;
};
function toPercent(value: number | undefined): string {
return value != undefined ? `${(value * 100).toFixed(1)}%` : '?%';
}
async function displayWorkers(opts: GlobalOptions) {
const activeInstance = await pickInstance(opts, true);
if (activeInstance) {
const workerGroups = await wmill.listWorkerGroups();
const workers = await wmill.listWorkers({
pingSince: 10
});
const groupedWorkers = workerGroups.map(group => {
const groupWorkers = workers.filter(worker => worker.worker_group === group.name);
return {
groupName: group.name,
workers: groupWorkers
};
});
// Add workers that don't belong to any worker group
const ungroupedWorkers = workers.filter(worker =>
!workerGroups.some(group => group.name === worker.worker_group)
);
if (ungroupedWorkers.length > 0) {
ungroupedWorkers.forEach(worker => {
const groupName = worker.worker_group || "Ungrouped";
let group = groupedWorkers.find(g => g.groupName === groupName);
if (!group) {
group = { groupName, workers: [] };
groupedWorkers.push(group);
}
group.workers.push(worker);
});
}
// Sort groupedWorkers
groupedWorkers.sort((a, b) => {
// Always put 'default' first
if (a.groupName === 'default') return -1;
if (b.groupName === 'default') return 1;
// Then sort by number of workers (descending order)
return b.workers.length - a.workers.length;
});
groupedWorkers.forEach(group => {
log.info(`\nWorker Group: ${group.groupName} (${group.workers.length} workers)`);
if (group.workers.length === 0) {
log.info(" No workers in this group");
} else {
new Table()
.header(["Worker ID", "Host", "Queues", "Jobs", "Occupancy rate 15s/5m/30m/ever)", "Last job", "Last Ping"])
.padding(2)
.border(true)
.maxColWidth(30)
.body(group.workers.map(worker => [
worker.worker,
worker.worker_instance,
worker.custom_tags?.join(', ') || '',
worker.jobs_executed,
`${toPercent(worker.occupancy_rate_15s)}/${toPercent(worker.occupancy_rate_5m)}/${toPercent(worker.occupancy_rate_30m)}/${toPercent(worker.occupancy_rate)}`,
worker.last_job_id ? worker.last_job_id + ' ' +worker.last_job_workspace_id : '',
`${worker.last_ping}s ago`
]))
.render();
}
});
} else {
log.info("No active instance found");
log.info("Use 'wmill instance add' to add a new instance");
}
}
const command = new Command()
.description("List all workers grouped by worker groups")
.option(
"--instance [instance]",
"Name of the instance to push to, override the active instance"
)
.option(
"--base-url [baseUrl]",
"If used with --token, will be used as the base url for the instance"
)
.action(displayWorkers as any);
export default command;