servers/http/
workload_scheduler.rs1use std::num::NonZeroU32;
16
17use axum::Json;
18use axum::body::Bytes;
19use axum::http::StatusCode;
20use axum::response::IntoResponse;
21use serde::{Deserialize, Serialize};
22use snafu::{ResultExt, ensure};
23
24use crate::error::{InvalidParameterSnafu, ParseJsonSnafu, Result};
25
26#[axum_macros::debug_handler]
27pub(super) async fn set_enabled_handler(body: Bytes) -> Result<impl IntoResponse> {
28 let enabled: bool = serde_json::from_slice(&body).context(ParseJsonSnafu)?;
29 ensure!(
30 common_runtime::set_workload_scheduler_enabled(enabled),
31 InvalidParameterSnafu {
32 reason: "workload scheduler was not constructed at startup",
33 }
34 );
35 let change_note = format!("Workload scheduler enabled={enabled}");
36 Ok((StatusCode::OK, change_note))
37}
38
39#[derive(Debug, Deserialize)]
40struct SchedulerWeightsDto {
41 query: NonZeroU32,
42 write: NonZeroU32,
43}
44
45#[axum_macros::debug_handler]
46pub(super) async fn set_weights_handler(body: Bytes) -> Result<impl IntoResponse> {
47 let weights: SchedulerWeightsDto = serde_json::from_slice(&body).context(ParseJsonSnafu)?;
48 ensure!(
49 common_runtime::set_workload_scheduler_weights(weights.query, weights.write),
50 InvalidParameterSnafu {
51 reason: "workload scheduler was not constructed at startup",
52 }
53 );
54 let change_note = format!(
55 "Workload scheduler weights query={}, write={}",
56 weights.query, weights.write
57 );
58 Ok((StatusCode::OK, change_note))
59}
60
61#[derive(Debug, Serialize)]
63struct ClassStatusDto {
64 weight: u32,
65}
66
67#[derive(Debug, Serialize)]
71struct SchedulerStatusDto {
72 enabled: bool,
73 #[serde(skip_serializing_if = "Option::is_none")]
74 query: Option<ClassStatusDto>,
75 #[serde(skip_serializing_if = "Option::is_none")]
76 write: Option<ClassStatusDto>,
77}
78
79#[axum_macros::debug_handler]
83pub(super) async fn get_status_handler() -> Result<impl IntoResponse> {
84 let enabled = common_runtime::workload_scheduler_enabled();
85 let Some(stats) = common_runtime::workload_scheduler_stats() else {
86 return Ok(Json(SchedulerStatusDto {
87 enabled: false,
88 query: None,
89 write: None,
90 }));
91 };
92
93 let mut query = None;
94 let mut write = None;
95 for (class, class_stats) in &stats.classes {
96 let status = ClassStatusDto {
97 weight: class_stats.weight,
98 };
99 match class.id() {
100 1 => query = Some(status),
101 2 => write = Some(status),
102 _ => {}
103 }
104 }
105
106 Ok(Json(SchedulerStatusDto {
107 enabled,
108 query,
109 write,
110 }))
111}