Skip to main content

vil_validate/
queue.rs

1// =============================================================================
2// vil_validate::queue — Queue Capability Pass
3// =============================================================================
4
5use std::collections::HashMap;
6use vil_ir::core::WorkflowIR;
7use vil_types::QueueKind;
8
9use crate::traits::{Diagnostic, ValidationPass, ValidationReport};
10
11pub struct QueueCapabilityPass;
12
13impl ValidationPass for QueueCapabilityPass {
14    fn name(&self) -> &'static str {
15        "QueueCapabilityPass"
16    }
17
18    fn run(&self, ir: &WorkflowIR) -> ValidationReport {
19        let mut report = ValidationReport::new();
20
21        // Count producers and consumers for each process port
22        let mut port_connections: HashMap<(String, String), usize> = HashMap::new();
23
24        for route in &ir.routes {
25            let from_key = (route.from_process.clone(), route.from_port.clone());
26            let to_key = (route.to_process.clone(), route.to_port.clone());
27
28            *port_connections.entry(from_key).or_insert(0) += 1;
29            *port_connections.entry(to_key).or_insert(0) += 1;
30        }
31
32        // Validate that Spsc queues are only used for 1-to-1 connections
33        for ((proc_name, port_name), count) in port_connections {
34            if count > 1 {
35                // Determine queue type of this port
36                if let Some(proc_ir) = ir.processes.get(&proc_name) {
37                    if let Some(iface) = ir.interfaces.get(&proc_ir.interface_name) {
38                        if let Some(port) = iface.ports.get(&port_name) {
39                            if port.queue_spec.kind == QueueKind::Spsc {
40                                report.push(Diagnostic::error(
41                                    "E-QUEUE-01",
42                                    format!("Port '{}' on process '{}' has {} connections but is configured as Spsc. Change to Mpmc.", port_name, proc_name, count),
43                                    format!("{}.{}", proc_name, port_name),
44                                ));
45                            }
46                        }
47                    }
48                }
49            }
50        }
51
52        report
53    }
54}