termivar_scanner/distributed/
limits.rs1use super::DistributedError;
2
3pub const MAX_IDENTIFIER_BYTES: usize = 256;
5pub const MAX_TARGET_REF_BYTES: usize = 1_024;
7pub const MAX_TASK_PHASES: usize = 256;
9pub const MAX_WORKER_TAGS: usize = 5;
11pub const UTILIZATION_BASIS_POINTS: u16 = 10_000;
13pub const MAX_TASK_RECORDS: usize = 65_536;
15pub const MAX_ACTIVE_TASKS: usize = 16_384;
17pub const MAX_WORKERS: usize = 4_096;
19pub const MAX_RETRIES: u32 = 32;
21pub const MAX_WORKER_CAPACITY: u32 = 4_096;
23pub const MAX_LEASE_TTL_SECS: u64 = 86_400;
25pub const MAX_TASK_TTL_SECS: u64 = 31 * 86_400;
27pub const MAX_HEARTBEAT_TIMEOUT_SECS: u64 = 86_400;
29pub const MAX_RESULTS: usize = 65_536;
31pub const MAX_RESULT_BYTES: usize = 16 * 1024 * 1024;
33pub const MAX_TOTAL_RESULT_BYTES: usize = 256 * 1024 * 1024;
35pub const MAX_AGGREGATE_ITEMS: usize = 65_536;
37
38#[derive(Debug, Clone, Copy, PartialEq, Eq)]
40pub struct DistributedLimits {
41 pub max_task_records: usize,
42 pub max_active_tasks: usize,
43 pub max_queued_tasks: usize,
44 pub max_terminal_tasks: usize,
45 pub max_workers: usize,
46 pub max_retries: u32,
47 pub max_lease_ttl_secs: u64,
48 pub max_task_ttl_secs: u64,
49 pub heartbeat_timeout_secs: u64,
50}
51
52impl Default for DistributedLimits {
53 fn default() -> Self {
54 Self {
55 max_task_records: 4_096,
56 max_active_tasks: 1_024,
57 max_queued_tasks: 1_024,
58 max_terminal_tasks: 4_096,
59 max_workers: 256,
60 max_retries: 3,
61 max_lease_ttl_secs: 3_600,
62 max_task_ttl_secs: 86_400,
63 heartbeat_timeout_secs: 60,
64 }
65 }
66}
67
68pub(super) fn validate_limits(limits: DistributedLimits) -> Result<(), DistributedError> {
69 for (name, value) in [
70 ("max_task_records", limits.max_task_records),
71 ("max_active_tasks", limits.max_active_tasks),
72 ("max_queued_tasks", limits.max_queued_tasks),
73 ("max_terminal_tasks", limits.max_terminal_tasks),
74 ("max_workers", limits.max_workers),
75 ] {
76 if value == 0 {
77 return Err(DistributedError::InvalidLimit { name });
78 }
79 }
80 for (name, actual, maximum) in [
81 (
82 "max_task_records",
83 limits.max_task_records,
84 MAX_TASK_RECORDS,
85 ),
86 (
87 "max_active_tasks",
88 limits.max_active_tasks,
89 MAX_ACTIVE_TASKS,
90 ),
91 (
92 "max_queued_tasks",
93 limits.max_queued_tasks,
94 MAX_ACTIVE_TASKS,
95 ),
96 (
97 "max_terminal_tasks",
98 limits.max_terminal_tasks,
99 MAX_TASK_RECORDS,
100 ),
101 ("max_workers", limits.max_workers, MAX_WORKERS),
102 ] {
103 if actual > maximum {
104 return Err(DistributedError::CountLimitExceedsMaximum {
105 name,
106 actual,
107 maximum,
108 });
109 }
110 }
111 for (name, actual, maximum) in [
112 (
113 "max_lease_ttl_secs",
114 limits.max_lease_ttl_secs,
115 MAX_LEASE_TTL_SECS,
116 ),
117 (
118 "max_task_ttl_secs",
119 limits.max_task_ttl_secs,
120 MAX_TASK_TTL_SECS,
121 ),
122 (
123 "heartbeat_timeout_secs",
124 limits.heartbeat_timeout_secs,
125 MAX_HEARTBEAT_TIMEOUT_SECS,
126 ),
127 ] {
128 if actual > maximum {
129 return Err(DistributedError::TimeLimitExceedsMaximum {
130 name,
131 actual,
132 maximum,
133 });
134 }
135 }
136 if limits.max_retries > MAX_RETRIES {
137 return Err(DistributedError::RetryLimitExceedsMaximum {
138 actual: limits.max_retries,
139 maximum: MAX_RETRIES,
140 });
141 }
142 for (name, value) in [
143 ("max_lease_ttl_secs", limits.max_lease_ttl_secs),
144 ("max_task_ttl_secs", limits.max_task_ttl_secs),
145 ("heartbeat_timeout_secs", limits.heartbeat_timeout_secs),
146 ] {
147 if value == 0 {
148 return Err(DistributedError::InvalidLimit { name });
149 }
150 }
151 if limits.max_active_tasks > limits.max_task_records {
152 return Err(DistributedError::InvalidLimitRelationship {
153 reason: "max_active_tasks exceeds max_task_records",
154 });
155 }
156 if limits.max_queued_tasks > limits.max_active_tasks {
157 return Err(DistributedError::InvalidLimitRelationship {
158 reason: "max_queued_tasks exceeds max_active_tasks",
159 });
160 }
161 if limits.max_terminal_tasks > limits.max_task_records {
162 return Err(DistributedError::InvalidLimitRelationship {
163 reason: "max_terminal_tasks exceeds max_task_records",
164 });
165 }
166 if limits.max_terminal_tasks < limits.max_active_tasks {
167 return Err(DistributedError::InvalidLimitRelationship {
168 reason: "max_terminal_tasks is smaller than max_active_tasks",
169 });
170 }
171 Ok(())
172}