Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cli/src/commands/wheels/assets/init.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ component extends="../base" {
if (len(content) && right(content, 1) != chr(10)) {
content &= chr(10);
}
content &= chr(10) & "# Vite build output" & chr(10);
content = content & chr(10) & "## Vite build output" & chr(10);
content &= arguments.entry & chr(10);
fileWrite(gitignorePath, content);
detailOutput.update(".gitignore", true);
Expand Down
74 changes: 26 additions & 48 deletions cli/src/commands/wheels/jobs/monitor.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
* wheels jobs monitor --queue=mailers
* {code}
*/
component extends="../../base" {
component extends="../base" {

property name="detailOutput" inject="DetailOutputService@wheels-cli";

/**
* @interval Refresh interval in seconds (default: 3)
Expand All @@ -25,10 +27,9 @@ component extends="../../base" {
return;
}

print.line();
print.boldMagentaLine("Wheels Job Monitor");
print.line("Press Ctrl+C to stop");
print.line();
detailOutput.header("Wheels Job Monitor");
detailOutput.output("Press Ctrl+C to stop");
detailOutput.line();

while (true) {
// Build URL parameters
Expand All @@ -42,77 +43,54 @@ component extends="../../base" {

if (StructKeyExists(local.result, "success") && local.result.success) {
// Clear previous output with separator
print.line(RepeatString("=", 60));
print.boldCyanLine("Job Queue Dashboard - #TimeFormat(Now(), "HH:mm:ss")#");
print.line(RepeatString("-", 60));
detailOutput.divider("=", 60);
detailOutput.getPrint().boldCyanLine("Job Queue Dashboard - #TimeFormat(Now(), "HH:mm:ss")#");
detailOutput.divider("-", 60);

// Queue statistics
if (StructKeyExists(local.result, "stats") && StructKeyExists(local.result.stats, "totals")) {
local.t = local.result.stats.totals;
print.line();
print.boldLine("Queue Summary:");
print.yellowLine(" Pending: #local.t.pending#");
print.cyanLine(" Processing: #local.t.processing#");
print.greenLine(" Completed: #local.t.completed#");
if (local.t.failed > 0) {
print.redLine(" Failed: #local.t.failed#");
} else {
print.line(" Failed: #local.t.failed#");
}
print.line(" Total: #local.t.total#");
detailOutput.subHeader("Queue Summary");
detailOutput.metric("Pending", local.t.pending);
detailOutput.metric("Processing", local.t.processing);
detailOutput.metric("Completed", local.t.completed);
detailOutput.metric("Failed", local.t.failed);
detailOutput.metric("Total", local.t.total);
}

// Throughput
if (StructKeyExists(local.result, "monitor")) {
local.m = local.result.monitor;

print.line();
print.boldLine("Throughput (last 60 min):");
print.greenLine(" Completed: #local.m.throughput.completed#");
if (local.m.throughput.failed > 0) {
print.redLine(" Failed: #local.m.throughput.failed#");
} else {
print.line(" Failed: #local.m.throughput.failed#");
}
if (local.m.errorRate > 0) {
print.redLine(" Error rate: #local.m.errorRate#%");
} else {
print.greenLine(" Error rate: 0%");
}
detailOutput.subHeader("Throughput (last 60 min)");
detailOutput.metric("Completed", local.m.throughput.completed);
detailOutput.metric("Failed", local.m.throughput.failed);
detailOutput.metric("Error rate", "#local.m.errorRate#%");

if (Len(local.m.oldestPending)) {
print.line();
print.line("Oldest pending job: #DateTimeFormat(local.m.oldestPending, 'yyyy-mm-dd HH:mm:ss')#");
detailOutput.line();
detailOutput.output("Oldest pending job: #DateTimeFormat(local.m.oldestPending, 'yyyy-mm-dd HH:mm:ss')#");
}

// Recent jobs
if (ArrayLen(local.m.recentJobs)) {
print.line();
print.boldLine("Recent Jobs:");
detailOutput.subHeader("Recent Jobs");
local.count = Min(ArrayLen(local.m.recentJobs), 5);
for (local.i = 1; local.i <= local.count; local.i++) {
local.job = local.m.recentJobs[local.i];
local.statusColor = "line";
if (local.job.status == "completed") local.statusColor = "greenLine";
else if (local.job.status == "failed") local.statusColor = "redLine";
else if (local.job.status == "processing") local.statusColor = "cyanLine";
else if (local.job.status == "pending") local.statusColor = "yellowLine";

print["#local.statusColor#"](
" [#local.job.status#] #local.job.jobClass# (#local.job.queue#) - #DateTimeFormat(local.job.updatedAt, 'HH:mm:ss')#"
);
detailOutput.output(" [#local.job.status#] #local.job.jobClass# (#local.job.queue#) - #DateTimeFormat(local.job.updatedAt, 'HH:mm:ss')#");
}
}
}

// Timeout recoveries
if (StructKeyExists(local.result, "timeoutsRecovered") && local.result.timeoutsRecovered > 0) {
print.line();
print.yellowLine("Recovered #local.result.timeoutsRecovered# timed-out job(s)");
detailOutput.line();
detailOutput.statusWarning("Recovered #local.result.timeoutsRecovered# timed-out job(s)");
}
}
} catch (any e) {
print.redLine("[#TimeFormat(Now(), "HH:mm:ss")#] Monitor error: #e.message#");
detailOutput.error("[#TimeFormat(Now(), "HH:mm:ss")#] Monitor error: #e.message#");
}

sleep(arguments.interval * 1000);
Expand Down
21 changes: 9 additions & 12 deletions cli/src/commands/wheels/jobs/purge.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
* wheels jobs purge --completed --failed --force
* {code}
*/
component extends="../../base" {
component extends="../base" {

property name="detailOutput" inject="DetailOutputService@wheels-cli";

/**
* @completed Purge completed jobs (default: true)
Expand All @@ -31,9 +33,7 @@ component extends="../../base" {
return;
}

print.line();
print.boldBlueLine("Purge Jobs");
print.line();
detailOutput.header("Purge Jobs");

local.totalPurged = 0;

Expand All @@ -48,9 +48,9 @@ component extends="../../base" {
if (StructKeyExists(local.result, "success") && local.result.success && StructKeyExists(local.result, "purged")) {
local.totalPurged += local.result.purged;
if (local.result.purged > 0) {
print.greenLine("Purged #local.result.purged# completed job(s) older than #arguments.olderThan# day(s).");
detailOutput.success("Purged #local.result.purged# completed job(s) older than #arguments.olderThan# day(s).");
} else {
print.line("No completed jobs to purge.");
detailOutput.output("No completed jobs to purge.");
}
}
}
Expand All @@ -66,19 +66,16 @@ component extends="../../base" {
if (StructKeyExists(local.result, "success") && local.result.success && StructKeyExists(local.result, "purged")) {
local.totalPurged += local.result.purged;
if (local.result.purged > 0) {
print.greenLine("Purged #local.result.purged# failed job(s) older than #arguments.olderThan# day(s).");
detailOutput.success("Purged #local.result.purged# failed job(s) older than #arguments.olderThan# day(s).");
} else {
print.line("No failed jobs to purge.");
detailOutput.output("No failed jobs to purge.");
}
}
}

if (local.totalPurged > 0) {
print.line();
print.boldGreenLine("Total purged: #local.totalPurged# job(s)");
detailOutput.success("Total purged: #local.totalPurged# job(s)");
}

print.line();
}

}
16 changes: 7 additions & 9 deletions cli/src/commands/wheels/jobs/retry.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
* wheels jobs retry --limit=10
* {code}
*/
component extends="../../base" {
component extends="../base" {

property name="detailOutput" inject="DetailOutputService@wheels-cli";

/**
* @queue Filter by queue name (default: all queues)
Expand All @@ -24,9 +26,7 @@ component extends="../../base" {
return;
}

print.line();
print.boldBlueLine("Retry Failed Jobs");
print.line();
detailOutput.header("Retry Failed Jobs");

// Build URL parameters
local.urlParams = "&command=jobsRetry";
Expand All @@ -44,14 +44,12 @@ component extends="../../base" {

if (StructKeyExists(local.result, "retried")) {
if (local.result.retried > 0) {
print.greenLine("Retried #local.result.retried# failed job(s).");
print.line("Jobs have been reset to 'pending' and will be processed on the next cycle.");
detailOutput.success("Retried #local.result.retried# failed job(s).");
detailOutput.output("Jobs have been reset to 'pending' and will be processed on the next cycle.");
} else {
print.line("No failed jobs to retry.");
detailOutput.output("No failed jobs to retry.");
}
}

print.line();
}

}
66 changes: 33 additions & 33 deletions cli/src/commands/wheels/jobs/status.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
* wheels jobs status --format=json
* {code}
*/
component extends="../../base" {
component extends="../base" {

property name="detailOutput" inject="DetailOutputService@wheels-cli";

/**
* @queue Filter by queue name (default: all queues)
Expand All @@ -24,9 +26,7 @@ component extends="../../base" {
return;
}

print.line();
print.boldBlueLine("Job Queue Status");
print.line();
detailOutput.header("Job Queue Status");

// Build URL parameters
local.urlParams = "&command=jobsStatus";
Expand All @@ -40,7 +40,7 @@ component extends="../../base" {
}

if (arguments.format == "json") {
print.line(SerializeJSON(local.result.stats));
detailOutput.output(SerializeJSON(local.result.stats));
return;
}

Expand All @@ -49,8 +49,8 @@ component extends="../../base" {
local.queues = local.result.stats.queues;

if (StructCount(local.queues) == 0) {
print.line("No jobs found.");
print.line();
detailOutput.output("No jobs found.");
detailOutput.line();
return;
}

Expand All @@ -63,47 +63,47 @@ component extends="../../base" {
PadRight("Total", 10) & " |";
local.separator = RepeatString("-", Len(local.header));

print.line(local.separator);
print.line(local.header);
print.line(local.separator);
detailOutput.getPrint().line(local.separator);
detailOutput.getPrint().line(local.header);
detailOutput.getPrint().line(local.separator);

for (local.queueName in local.queues) {
local.q = local.queues[local.queueName];
print.text("| " & PadRight(local.queueName, 20) & " | ");
print.yellowText(PadRight(local.q.pending, 10));
print.text(" | ");
print.cyanText(PadRight(local.q.processing, 12));
print.text(" | ");
print.greenText(PadRight(local.q.completed, 12));
print.text(" | ");
detailOutput.getPrint().text("| " & PadRight(local.queueName, 20) & " | ");
detailOutput.getPrint().yellowText(PadRight(local.q.pending, 10));
detailOutput.getPrint().text(" | ");
detailOutput.getPrint().cyanText(PadRight(local.q.processing, 12));
detailOutput.getPrint().text(" | ");
detailOutput.getPrint().greenText(PadRight(local.q.completed, 12));
detailOutput.getPrint().text(" | ");
if (local.q.failed > 0) {
print.redText(PadRight(local.q.failed, 10));
detailOutput.getPrint().redText(PadRight(local.q.failed, 10));
} else {
print.text(PadRight(local.q.failed, 10));
detailOutput.getPrint().text(PadRight(local.q.failed, 10));
}
print.line(" | " & PadRight(local.q.total, 10) & " |");
detailOutput.getPrint().line(" | " & PadRight(local.q.total, 10) & " |");
}

// Totals row
local.totals = local.result.stats.totals;
print.line(local.separator);
print.text("| " & PadRight("TOTAL", 20) & " | ");
print.boldYellowText(PadRight(local.totals.pending, 10));
print.text(" | ");
print.boldCyanText(PadRight(local.totals.processing, 12));
print.text(" | ");
print.boldGreenText(PadRight(local.totals.completed, 12));
print.text(" | ");
detailOutput.getPrint().line(local.separator);
detailOutput.getPrint().text("| " & PadRight("TOTAL", 20) & " | ");
detailOutput.getPrint().boldYellowText(PadRight(local.totals.pending, 10));
detailOutput.getPrint().text(" | ");
detailOutput.getPrint().boldCyanText(PadRight(local.totals.processing, 12));
detailOutput.getPrint().text(" | ");
detailOutput.getPrint().boldGreenText(PadRight(local.totals.completed, 12));
detailOutput.getPrint().text(" | ");
if (local.totals.failed > 0) {
print.boldRedText(PadRight(local.totals.failed, 10));
detailOutput.getPrint().boldRedText(PadRight(local.totals.failed, 10));
} else {
print.boldText(PadRight(local.totals.failed, 10));
detailOutput.getPrint().boldText(PadRight(local.totals.failed, 10));
}
print.line(" | " & PadRight(local.totals.total, 10) & " |");
print.line(local.separator);
detailOutput.getPrint().line(" | " & PadRight(local.totals.total, 10) & " |");
detailOutput.getPrint().line(local.separator);
}

print.line();
detailOutput.line();
}

private string function PadRight(required string text, required numeric length) {
Expand Down
Loading
Loading