diff --git a/api/v2/api.gen.go b/api/v2/api.gen.go index 709c48e2..562c7c3c 100644 --- a/api/v2/api.gen.go +++ b/api/v2/api.gen.go @@ -599,7 +599,7 @@ type Pagination struct { // Queue A queue/process group with its active DAG-runs type Queue struct { - // MaxConcurrency Maximum number of concurrent runs allowed. Only present for 'global' type queues + // MaxConcurrency Maximum number of concurrent runs allowed. For 'global' queues, this is the configured maxConcurrency. For 'dag-based' queues, this is the DAG's maxActiveRuns (default 1) MaxConcurrency *int `json:"maxConcurrency,omitempty"` // Name Name of the queue (global queue name or DAG name if no queue specified) @@ -6144,92 +6144,92 @@ var swaggerSpec = []string{ "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", - "Xf1PAAAA//8sH3d//9wAAA==", + "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", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/api/v2/api.yaml b/api/v2/api.yaml index 635a9d83..cc9bb80a 100644 --- a/api/v2/api.yaml +++ b/api/v2/api.yaml @@ -2368,7 +2368,7 @@ components: description: "Type of queue - 'global' if explicitly defined, 'dag-based' if using DAG name" maxConcurrency: type: integer - description: "Maximum number of concurrent runs allowed. Only present for 'global' type queues" + description: "Maximum number of concurrent runs allowed. For 'global' queues, this is the configured maxConcurrency. For 'dag-based' queues, this is the DAG's maxActiveRuns (default 1)" minimum: 1 running: type: array diff --git a/internal/frontend/api/v2/queues.go b/internal/frontend/api/v2/queues.go index 22cbfd14..1d4d6b52 100644 --- a/internal/frontend/api/v2/queues.go +++ b/internal/frontend/api/v2/queues.go @@ -5,6 +5,7 @@ import ( "github.com/dagu-org/dagu/api/v2" "github.com/dagu-org/dagu/internal/config" + "github.com/dagu-org/dagu/internal/digraph" "github.com/dagu-org/dagu/internal/digraph/status" ) @@ -43,17 +44,28 @@ func (a *API) ListQueues(ctx context.Context, _ api.ListQueuesRequestObject) (ap // Process running DAG runs for groupName, dagRuns := range runningByGroup { - // Group name is the queue name - queue := getOrCreateQueue(queueMap, groupName, a.config) + var dag *digraph.DAG + var queue *queueInfo // Convert each running DAG run to DAGRunSummary for _, dagRun := range dagRuns { - // Get the DAG run status to convert to summary + // Get the DAG run attempt attempt, err := a.dagRunStore.FindAttempt(ctx, dagRun) if err != nil { continue // Skip if we can't find the attempt } + // Get the DAG from the attempt (only once for the group) + if dag == nil { + dag, _ = attempt.ReadDAG(ctx) + } + + // Get or create queue with the DAG info (only once for the group) + if queue == nil { + queue = getOrCreateQueue(queueMap, groupName, a.config, dag) + } + + // Get the status and add to queue runStatus, err := attempt.ReadStatus(ctx) if err != nil { continue // Skip if we can't read status @@ -90,7 +102,7 @@ func (a *API) ListQueues(ctx context.Context, _ api.ListQueuesRequestObject) (ap queueName = dag.Name } - queue := getOrCreateQueue(queueMap, queueName, a.config) + queue := getOrCreateQueue(queueMap, queueName, a.config, dag) // Get the DAG run status to convert to summary attempt, err := a.dagRunStore.FindAttempt(ctx, dagRunRef) @@ -121,8 +133,8 @@ func (a *API) ListQueues(ctx context.Context, _ api.ListQueuesRequestObject) (ap Queued: q.queued, } - // Only include maxConcurrency for global queues - if q.queueType == "global" && q.maxConcurrency > 0 { + // Include maxConcurrency for both global and DAG-based queues + if q.maxConcurrency > 0 { queue.MaxConcurrency = &q.maxConcurrency totalCapacity += q.maxConcurrency } @@ -161,7 +173,7 @@ type queueInfo struct { } // Helper function to get or create queue in the map -func getOrCreateQueue(queueMap map[string]*queueInfo, queueName string, config *config.Config) *queueInfo { +func getOrCreateQueue(queueMap map[string]*queueInfo, queueName string, config *config.Config, dag *digraph.DAG) *queueInfo { queue, exists := queueMap[queueName] if !exists { queue = &queueInfo{ @@ -175,6 +187,9 @@ func getOrCreateQueue(queueMap map[string]*queueInfo, queueName string, config * if isGlobalQueue(queueName, config) { queue.queueType = "global" queue.maxConcurrency = getQueueMaxConcurrency(queueName, config) + } else if dag != nil { + // For DAG-based queues, use the DAG's MaxActiveRuns + queue.maxConcurrency = dag.MaxActiveRuns } queueMap[queueName] = queue diff --git a/ui/src/features/dags/components/common/DAGActions.tsx b/ui/src/features/dags/components/common/DAGActions.tsx index 7a84dad4..d3434932 100644 --- a/ui/src/features/dags/components/common/DAGActions.tsx +++ b/ui/src/features/dags/components/common/DAGActions.tsx @@ -479,15 +479,11 @@ function DAGActions({ return; } - // Navigate to DAG-run detail page - if (data?.dagRunId && dag?.name) { - navigate(`/dag-runs/${dag.name}/${data.dagRunId}`); - } else { - reloadData(); - // Navigate to status tab after execution - if (navigateToStatusTab) { - navigateToStatusTab(); - } + // Just refresh the current page data + reloadData(); + // Navigate to status tab after execution (if available) + if (navigateToStatusTab) { + navigateToStatusTab(); } }} dismissModal={() => { diff --git a/ui/src/features/dags/components/dag-execution/StartDAGModal.tsx b/ui/src/features/dags/components/dag-execution/StartDAGModal.tsx index f1ba67b4..b6acf70a 100644 --- a/ui/src/features/dags/components/dag-execution/StartDAGModal.tsx +++ b/ui/src/features/dags/components/dag-execution/StartDAGModal.tsx @@ -41,13 +41,7 @@ type Props = { /** * Modal dialog for starting or enqueuing a DAG with parameters */ -function StartDAGModal({ - visible, - dag, - dismissModal, - onSubmit, - action = 'start', -}: Props) { +function StartDAGModal({ visible, dag, dismissModal, onSubmit }: Props) { const ref = React.useRef(null); // Parse default parameters from the DAG definition diff --git a/ui/src/features/dags/components/dag-list/DAGTable.tsx b/ui/src/features/dags/components/dag-list/DAGTable.tsx index 8994407f..6349b621 100644 --- a/ui/src/features/dags/components/dag-list/DAGTable.tsx +++ b/ui/src/features/dags/components/dag-list/DAGTable.tsx @@ -149,12 +149,12 @@ const columnHelper = createColumnHelper(); function getTzAndExp(exp: string) { const parts = exp.trim().split(/\s+/); - if (parts[0]?.startsWith("CRON_TZ=")) { - const timezone = parts[0]?.split("=")[1]; - const cronExpr = parts?.slice(1).join(" "); + if (parts[0]?.startsWith('CRON_TZ=')) { + const timezone = parts[0]?.split('=')[1]; + const cronExpr = parts?.slice(1).join(' '); return [timezone, cronExpr]; } else { - return [parts.join(" ")]; + return [parts.join(' ')]; } } @@ -167,13 +167,14 @@ function getNextSchedule( } try { const datesToRun = schedules.map((schedule) => { - const parsedCronExp = getTzAndExp(schedule.expression) + const parsedCronExp = getTzAndExp(schedule.expression); const options = { - tz: (parsedCronExp.length > 1 ? parsedCronExp[0] : getConfig().tz), + tz: parsedCronExp.length > 1 ? parsedCronExp[0] : getConfig().tz, iterator: true, }; // Assuming 'parseExpression' is the correct method name based on library docs - const cronExp = (parsedCronExp.length > 1 ? parsedCronExp[1] : parsedCronExp[0]) + const cronExp = + parsedCronExp.length > 1 ? parsedCronExp[1] : parsedCronExp[0]; const interval = cronParser.parse(cronExp!, options); return interval.next(); }); @@ -316,11 +317,17 @@ const defaultColumns = [ } if (data.kind === ItemKind.DAG) { const name = data.dag.dag.name.toLowerCase(); + const fileName = data.dag.fileName.toLowerCase(); const description = (data.dag.dag.description || '').toLowerCase(); const searchValue = String(filterValue).toLowerCase(); // Search in name and description - if (name.includes(searchValue) || description.includes(searchValue)) { + console.log({ data }); + if ( + fileName.includes(searchValue) || + name.includes(searchValue) || + description.includes(searchValue) + ) { return true; } @@ -395,10 +402,10 @@ const defaultColumns = [ if (finishedAt && finishedAt !== '-') { const start = dayjs(startedAt); const end = dayjs(finishedAt); - + if (start.isValid() && end.isValid()) { const durationMs = end.diff(start); - + if (durationMs > 0) { // Format duration manually without using the custom format function const duration = dayjs.duration(durationMs); @@ -406,15 +413,15 @@ const defaultColumns = [ const hours = duration.hours(); const minutes = duration.minutes(); const seconds = duration.seconds(); - + const parts: string[] = []; if (days > 0) parts.push(`${days}d`); if (hours > 0) parts.push(`${hours}h`); if (minutes > 0) parts.push(`${minutes}m`); if (seconds > 0 && parts.length === 0) parts.push(`${seconds}s`); - + const formattedDuration = parts.join(' '); - + durationContent = (
{formattedDuration} diff --git a/ui/src/features/queues/components/QueueMetrics.tsx b/ui/src/features/queues/components/QueueMetrics.tsx index 5871271d..73b76b88 100644 --- a/ui/src/features/queues/components/QueueMetrics.tsx +++ b/ui/src/features/queues/components/QueueMetrics.tsx @@ -1,11 +1,16 @@ import React from 'react'; -import { Layers, Play, Clock, BarChart3, Settings, GitBranch } from 'lucide-react'; +import { Layers, Play, Clock, BarChart3, Activity } from 'lucide-react'; +import { + Tooltip, + TooltipContent, + TooltipTrigger, +} from '../../../components/ui/tooltip'; interface QueueMetricsProps { metrics: { - totalQueues: number; globalQueues: number; dagBasedQueues: number; + activeQueues: number; totalRunning: number; totalQueued: number; totalActive: number; @@ -18,34 +23,40 @@ function QueueMetrics({ metrics, isLoading }: QueueMetricsProps) { // Define metric cards data const metricCards = [ { - title: 'Total Queues', - value: metrics.totalQueues, - icon: , - }, - { - title: 'Global', + title: 'Global Queues', value: metrics.globalQueues, - icon: , + icon: , + tooltip: 'Number of global queues (shared across multiple DAGs with maxConcurrency limits)', }, { - title: 'DAG-based', + title: 'DAG-based Queues', value: metrics.dagBasedQueues, - icon: , + icon: , + tooltip: 'Number of DAG-based queues (each DAG has its own queue with maxActiveRuns limit, default 1)', + }, + { + title: 'Active Queues', + value: metrics.activeQueues, + icon: , + tooltip: 'Number of queues currently with running or queued DAG runs', }, { title: 'Running', value: metrics.totalRunning, icon: , + tooltip: 'Total number of DAG runs currently executing across all queues', }, { title: 'Queued', value: metrics.totalQueued, icon: , + tooltip: 'Total number of DAG runs waiting to be executed across all queues', }, { title: 'Utilization', value: `${metrics.utilization}%`, icon: , + tooltip: 'Percentage of global queue capacity being used (total running DAG runs รท global queue maxConcurrency)', }, ]; @@ -54,29 +65,33 @@ function QueueMetrics({ metrics, isLoading }: QueueMetricsProps) { {/* Dense metrics */}
{metricCards.map((card) => ( -
-
- {React.cloneElement(card.icon, { - className: card.icon.props.className.replace( - 'h-5 w-5', - 'h-3 w-3' - ), - })} - - {card.title} - -
- - {isLoading ? '-' : card.value} - -
+ + +
+
+ {React.cloneElement(card.icon, { + className: card.icon.props.className.replace( + 'h-5 w-5', + 'h-3 w-3' + ), + })} + + {card.title} + +
+ + {isLoading ? '-' : card.value} + +
+
+ +

{card.tooltip}

+
+
))}
); } -export default QueueMetrics; \ No newline at end of file +export default QueueMetrics; diff --git a/ui/src/pages/queues/index.tsx b/ui/src/pages/queues/index.tsx index 722b8f2e..2969b874 100644 --- a/ui/src/pages/queues/index.tsx +++ b/ui/src/pages/queues/index.tsx @@ -2,6 +2,11 @@ import React from 'react'; import { Layers, Activity, Search, RefreshCw } from 'lucide-react'; import { Input } from '../../components/ui/input'; import { Button } from '../../components/ui/button'; +import { + Tooltip, + TooltipContent, + TooltipTrigger, +} from '../../components/ui/tooltip'; import { AppBarContext } from '../../contexts/AppBarContext'; import { useQuery } from '../../hooks/api'; import type { components } from '../../api/v2/schema'; @@ -62,28 +67,37 @@ function Queues() { filtered = filtered.filter((queue) => queue.type === selectedQueueType); } - return filtered; + // Sort alphabetically by queue name for stable display + return filtered.sort((a, b) => a.name.localeCompare(b.name)); }, [data?.queues, searchText, selectedQueueType]); // Calculate metrics const metrics = React.useMemo(() => { const queues = data?.queues || []; - const totalQueues = queues.length; + + // Count queues by type const globalQueues = queues.filter(q => q.type === 'global').length; const dagBasedQueues = queues.filter(q => q.type === 'dag-based').length; + + // Count active queues (those with running or queued items) + const activeQueues = queues.filter(q => + (q.running?.length || 0) > 0 || (q.queued?.length || 0) > 0 + ).length; + const totalRunning = queues.reduce((sum, q) => sum + (q.running?.length || 0), 0); const totalQueued = queues.reduce((sum, q) => sum + (q.queued?.length || 0), 0); const totalActive = totalRunning + totalQueued; - // Calculate utilization for custom queues - const globalQueuesWithCapacity = queues.filter(q => q.type === 'global' && q.maxConcurrency); - const totalCapacity = globalQueuesWithCapacity.reduce((sum, q) => sum + (q.maxConcurrency || 0), 0); - const utilization = totalCapacity > 0 ? Math.round((totalRunning / totalCapacity) * 100) : 0; + // Calculate utilization for global queues only (DAG-based queues are isolated and don't compete for shared capacity) + const globalQueuesList = queues.filter(q => q.type === 'global'); + const globalRunning = globalQueuesList.reduce((sum, q) => sum + (q.running?.length || 0), 0); + const globalCapacity = globalQueuesList.filter(q => q.maxConcurrency).reduce((sum, q) => sum + (q.maxConcurrency || 0), 0); + const utilization = globalCapacity > 0 ? Math.round((globalRunning / globalCapacity) * 100) : 0; return { - totalQueues, globalQueues, dagBasedQueues, + activeQueues, totalRunning, totalQueued, totalActive, @@ -193,14 +207,28 @@ function Queues() {
Queued
-
-
- Global -
-
-
- DAG-based -
+ + +
+
+ Global +
+ + +

Shared queues with maxConcurrency limits that can process DAG runs from multiple DAGs

+
+ + + +
+
+ DAG-based +
+ + +

Dedicated queues where each DAG has its own queue with maxActiveRuns limit (default 1)

+
+