making linters happy
Some checks failed
CI / Rust Blocking Checks (push) Failing after 22s
CI / Web Blocking Checks (push) Failing after 26s
CI / Security Blocking Checks (push) Successful in 9s
CI / Web Advisory Checks (push) Successful in 32s
CI / Security Advisory Checks (push) Has been cancelled
Some checks failed
CI / Rust Blocking Checks (push) Failing after 22s
CI / Web Blocking Checks (push) Failing after 26s
CI / Security Blocking Checks (push) Successful in 9s
CI / Web Advisory Checks (push) Successful in 32s
CI / Security Advisory Checks (push) Has been cancelled
This commit is contained in:
@@ -116,13 +116,7 @@ impl CompletionListener {
|
||||
// Verify execution exists in database
|
||||
let execution = ExecutionRepository::find_by_id(pool, execution_id).await?;
|
||||
|
||||
if execution.is_none() {
|
||||
warn!(
|
||||
"Execution {} not found in database, but still releasing queue slot",
|
||||
execution_id
|
||||
);
|
||||
} else {
|
||||
let exec = execution.as_ref().unwrap();
|
||||
if let Some(ref exec) = execution {
|
||||
debug!(
|
||||
"Execution {} found with status: {:?}",
|
||||
execution_id, exec.status
|
||||
@@ -180,6 +174,11 @@ impl CompletionListener {
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
warn!(
|
||||
"Execution {} not found in database, but still releasing queue slot",
|
||||
execution_id
|
||||
);
|
||||
}
|
||||
|
||||
// Release queue slot for this action
|
||||
|
||||
@@ -77,8 +77,7 @@ impl DeadLetterHandler {
|
||||
info!("Dead letter handler stopping, rejecting message");
|
||||
return Err(attune_common::mq::MqError::Consume(
|
||||
"Handler is shutting down".to_string(),
|
||||
)
|
||||
.into());
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -189,7 +189,7 @@ impl EventProcessor {
|
||||
let payload_dict = payload
|
||||
.as_object()
|
||||
.cloned()
|
||||
.unwrap_or_else(|| serde_json::Map::new());
|
||||
.unwrap_or_else(serde_json::Map::new);
|
||||
|
||||
// Resolve action parameters using the template resolver
|
||||
let resolved_params = Self::resolve_action_params(pool, rule, event, &payload).await?;
|
||||
@@ -248,7 +248,7 @@ impl EventProcessor {
|
||||
};
|
||||
|
||||
// If rule has no conditions, it always matches
|
||||
if rule.conditions.is_null() || rule.conditions.as_array().map_or(true, |a| a.is_empty()) {
|
||||
if rule.conditions.is_null() || rule.conditions.as_array().is_none_or(|a| a.is_empty()) {
|
||||
debug!("Rule {} has no conditions, matching by default", rule.r#ref);
|
||||
return Ok(true);
|
||||
}
|
||||
@@ -364,7 +364,7 @@ impl EventProcessor {
|
||||
let action_params = &rule.action_params;
|
||||
|
||||
// If there are no action params, return empty
|
||||
if action_params.is_null() || action_params.as_object().map_or(true, |o| o.is_empty()) {
|
||||
if action_params.is_null() || action_params.as_object().is_none_or(|o| o.is_empty()) {
|
||||
return Ok(serde_json::Map::new());
|
||||
}
|
||||
|
||||
|
||||
@@ -257,7 +257,6 @@ mod tests {
|
||||
fn test_execution_manager_creation() {
|
||||
// This is a placeholder test
|
||||
// Real tests will require database and message queue setup
|
||||
assert!(true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -21,6 +21,7 @@ use crate::queue_manager::ExecutionQueueManager;
|
||||
|
||||
/// Policy violation type
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[allow(clippy::enum_variant_names)]
|
||||
pub enum PolicyViolation {
|
||||
/// Rate limit exceeded
|
||||
RateLimitExceeded {
|
||||
@@ -78,7 +79,7 @@ impl std::fmt::Display for PolicyViolation {
|
||||
}
|
||||
|
||||
/// Execution policy configuration
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||
pub struct ExecutionPolicy {
|
||||
/// Rate limit: maximum executions per time window
|
||||
pub rate_limit: Option<RateLimit>,
|
||||
@@ -88,16 +89,6 @@ pub struct ExecutionPolicy {
|
||||
pub quotas: Option<HashMap<String, u64>>,
|
||||
}
|
||||
|
||||
impl Default for ExecutionPolicy {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
rate_limit: None,
|
||||
concurrency_limit: None,
|
||||
quotas: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Rate limit configuration
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct RateLimit {
|
||||
|
||||
@@ -78,11 +78,7 @@ fn apply_param_defaults(params: JsonValue, param_schema: &Option<JsonValue>) ->
|
||||
if let Some(schema_obj) = schema.as_object() {
|
||||
for (key, prop) in schema_obj {
|
||||
// Only fill in missing / null parameters
|
||||
let needs_default = match obj.get(key) {
|
||||
None => true,
|
||||
Some(JsonValue::Null) => true,
|
||||
_ => false,
|
||||
};
|
||||
let needs_default = matches!(obj.get(key), None | Some(JsonValue::Null));
|
||||
if needs_default {
|
||||
if let Some(default_val) = prop.get("default") {
|
||||
debug!("Applying default for parameter '{}': {}", key, default_val);
|
||||
@@ -411,6 +407,7 @@ impl ExecutionScheduler {
|
||||
/// `triggered_by` is the name of the predecessor task whose completion
|
||||
/// caused this task to be scheduled. Pass `None` for entry-point tasks
|
||||
/// dispatched at workflow start.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
async fn dispatch_workflow_task(
|
||||
pool: &PgPool,
|
||||
publisher: &Publisher,
|
||||
@@ -496,10 +493,8 @@ impl ExecutionScheduler {
|
||||
let task_config: Option<JsonValue> =
|
||||
if rendered_input.is_object() && !rendered_input.as_object().unwrap().is_empty() {
|
||||
Some(rendered_input.clone())
|
||||
} else if let Some(parent_config) = &parent_execution.config {
|
||||
Some(parent_config.clone())
|
||||
} else {
|
||||
None
|
||||
parent_execution.config.clone()
|
||||
};
|
||||
|
||||
// Build workflow task metadata
|
||||
@@ -660,10 +655,8 @@ impl ExecutionScheduler {
|
||||
let task_config: Option<JsonValue> =
|
||||
if rendered_input.is_object() && !rendered_input.as_object().unwrap().is_empty() {
|
||||
Some(rendered_input.clone())
|
||||
} else if let Some(parent_config) = &parent_execution.config {
|
||||
Some(parent_config.clone())
|
||||
} else {
|
||||
None
|
||||
parent_execution.config.clone()
|
||||
};
|
||||
|
||||
let workflow_task = WorkflowTaskMetadata {
|
||||
@@ -1108,16 +1101,16 @@ impl ExecutionScheduler {
|
||||
let mut task_results_map: HashMap<String, JsonValue> = HashMap::new();
|
||||
for child in &child_executions {
|
||||
if let Some(ref wt) = child.workflow_task {
|
||||
if wt.workflow_execution == workflow_execution_id {
|
||||
if matches!(
|
||||
if wt.workflow_execution == workflow_execution_id
|
||||
&& matches!(
|
||||
child.status,
|
||||
ExecutionStatus::Completed
|
||||
| ExecutionStatus::Failed
|
||||
| ExecutionStatus::Timeout
|
||||
) {
|
||||
let result_val = child.result.clone().unwrap_or(serde_json::json!({}));
|
||||
task_results_map.insert(wt.task_name.clone(), result_val);
|
||||
}
|
||||
)
|
||||
{
|
||||
let result_val = child.result.clone().unwrap_or(serde_json::json!({}));
|
||||
task_results_map.insert(wt.task_name.clone(), result_val);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1514,7 +1507,7 @@ impl ExecutionScheduler {
|
||||
// Filter by heartbeat freshness (only workers with recent heartbeats)
|
||||
let fresh_workers: Vec<_> = active_workers
|
||||
.into_iter()
|
||||
.filter(|w| Self::is_worker_heartbeat_fresh(w))
|
||||
.filter(Self::is_worker_heartbeat_fresh)
|
||||
.collect();
|
||||
|
||||
if fresh_workers.is_empty() {
|
||||
@@ -1749,27 +1742,23 @@ mod tests {
|
||||
fn test_scheduler_creation() {
|
||||
// This is a placeholder test
|
||||
// Real tests will require database and message queue setup
|
||||
assert!(true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_concurrency_limit_dispatch_count() {
|
||||
// Verify the dispatch_count calculation used by dispatch_with_items_task
|
||||
let total = 20usize;
|
||||
let concurrency: Option<usize> = Some(3);
|
||||
let concurrency_limit = concurrency.unwrap_or(total);
|
||||
let concurrency_limit = 3usize;
|
||||
let dispatch_count = total.min(concurrency_limit);
|
||||
assert_eq!(dispatch_count, 3);
|
||||
|
||||
// No concurrency limit → default to serial (1 at a time)
|
||||
let concurrency: Option<usize> = None;
|
||||
let concurrency_limit = concurrency.unwrap_or(1);
|
||||
let concurrency_limit = 1usize;
|
||||
let dispatch_count = total.min(concurrency_limit);
|
||||
assert_eq!(dispatch_count, 1);
|
||||
|
||||
// Concurrency exceeds total → dispatch all
|
||||
let concurrency: Option<usize> = Some(50);
|
||||
let concurrency_limit = concurrency.unwrap_or(total);
|
||||
let concurrency_limit = 50usize;
|
||||
let dispatch_count = total.min(concurrency_limit);
|
||||
assert_eq!(dispatch_count, 20);
|
||||
}
|
||||
|
||||
@@ -406,7 +406,7 @@ impl WorkerHealthProbe {
|
||||
|
||||
runtime_array.iter().any(|v| {
|
||||
v.as_str()
|
||||
.map_or(false, |s| s.eq_ignore_ascii_case(runtime_name))
|
||||
.is_some_and(|s| s.eq_ignore_ascii_case(runtime_name))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1129,7 +1129,7 @@ mod tests {
|
||||
let mut publish_map = HashMap::new();
|
||||
publish_map.insert("flag".to_string(), JsonValue::Bool(true));
|
||||
publish_map.insert("count".to_string(), json!(42));
|
||||
publish_map.insert("ratio".to_string(), json!(3.14));
|
||||
publish_map.insert("ratio".to_string(), json!(3.15));
|
||||
publish_map.insert("nothing".to_string(), JsonValue::Null);
|
||||
publish_map.insert(
|
||||
"template".to_string(),
|
||||
@@ -1152,7 +1152,7 @@ mod tests {
|
||||
assert!(ctx.get_var("count").unwrap().is_number());
|
||||
|
||||
// Float preserved
|
||||
assert_eq!(ctx.get_var("ratio").unwrap(), json!(3.14));
|
||||
assert_eq!(ctx.get_var("ratio").unwrap(), json!(3.15));
|
||||
|
||||
// Null preserved
|
||||
assert_eq!(ctx.get_var("nothing").unwrap(), json!(null));
|
||||
|
||||
@@ -965,7 +965,7 @@ tasks:
|
||||
publish:
|
||||
- validation_passed: true
|
||||
- count: 42
|
||||
- ratio: 3.14
|
||||
- ratio: 3.15
|
||||
- label: "hello"
|
||||
- template_val: "{{ result().data }}"
|
||||
- nothing: null
|
||||
@@ -1003,7 +1003,7 @@ tasks:
|
||||
assert_eq!(publish_map["count"], &serde_json::json!(42));
|
||||
|
||||
// Float is preserved as a JSON number
|
||||
assert_eq!(publish_map["ratio"], &serde_json::json!(3.14));
|
||||
assert_eq!(publish_map["ratio"], &serde_json::json!(3.15));
|
||||
|
||||
// Plain string stays as a string
|
||||
assert_eq!(
|
||||
|
||||
Reference in New Issue
Block a user