relay_event_schema/protocol/contexts/
threadpool_info.rs

1use crate::processor::ProcessValue;
2use relay_protocol::{Annotated, Empty, FromValue, IntoValue, Object, Value};
3
4/// Thread pool info context.
5#[derive(Clone, Debug, Default, PartialEq, Empty, FromValue, IntoValue, ProcessValue)]
6pub struct ThreadPoolInfoContext {
7    /// Number of worker threads currently available in the thread pool.
8    /// Worker threads are used for executing application code and handling CPU-bound tasks.
9    pub available_worker_threads: Annotated<u64>,
10
11    /// Number of completion port threads (also known as I/O completion port threads) currently available.
12    /// These threads handle I/O operations and asynchronous callbacks.
13    pub available_completion_port_threads: Annotated<u64>,
14
15    /// Maximum number of worker threads the thread pool can have.
16    /// This represents the upper limit for worker thread allocation.
17    pub max_worker_threads: Annotated<u64>,
18
19    /// Maximum number of completion port threads the thread pool can maintain.
20    /// This sets the ceiling for I/O completion port thread allocation.
21    pub max_completion_port_threads: Annotated<u64>,
22
23    /// Minimum number of worker threads maintained by the thread pool.
24    /// The thread pool will always keep at least this many worker threads active.
25    pub min_worker_threads: Annotated<u64>,
26
27    /// Minimum number of completion port threads maintained by the thread pool.
28    /// This ensures a baseline number of threads are available for I/O operations.
29    pub min_completion_port_threads: Annotated<u64>,
30
31    #[metastructure(additional_properties, retain = true, pii = "maybe")]
32    pub other: Object<Value>,
33}
34
35impl super::DefaultContext for ThreadPoolInfoContext {
36    fn default_key() -> &'static str {
37        "threadpool_info"
38    }
39
40    fn from_context(context: super::Context) -> Option<Self> {
41        match context {
42            super::Context::ThreadPoolInfo(c) => Some(*c),
43            _ => None,
44        }
45    }
46
47    fn cast(context: &super::Context) -> Option<&Self> {
48        match context {
49            super::Context::ThreadPoolInfo(c) => Some(c),
50            _ => None,
51        }
52    }
53
54    fn cast_mut(context: &mut super::Context) -> Option<&mut Self> {
55        match context {
56            super::Context::ThreadPoolInfo(c) => Some(c),
57            _ => None,
58        }
59    }
60
61    fn into_context(self) -> super::Context {
62        super::Context::ThreadPoolInfo(Box::new(self))
63    }
64}
65
66#[cfg(test)]
67mod test {
68    use super::*;
69    use crate::protocol::Context;
70
71    #[test]
72    fn test_threadpool_info_context_roundtrip() {
73        let json = r#"{
74  "available_worker_threads": 1022,
75  "available_completion_port_threads": 1000,
76  "max_worker_threads": 1023,
77  "max_completion_port_threads": 1000,
78  "min_worker_threads": 1,
79  "min_completion_port_threads": 1,
80  "unknown_key": [
81    123
82  ],
83  "type": "threadpool_info"
84}"#;
85
86        let other = {
87            let mut map = Object::new();
88            map.insert(
89                "unknown_key".to_owned(),
90                Annotated::new(Value::Array(vec![Annotated::new(Value::I64(123))])),
91            );
92            map
93        };
94        let context = Annotated::new(Context::ThreadPoolInfo(Box::new(ThreadPoolInfoContext {
95            available_worker_threads: Annotated::new(1022),
96            available_completion_port_threads: Annotated::new(1000),
97            max_worker_threads: Annotated::new(1023),
98            max_completion_port_threads: Annotated::new(1000),
99            min_worker_threads: Annotated::new(1),
100            min_completion_port_threads: Annotated::new(1),
101            other,
102        })));
103
104        assert_eq!(context, Annotated::from_json(json).unwrap());
105        assert_eq!(json, context.to_json_pretty().unwrap());
106    }
107}