This commit is contained in:
Mikhail Kot
2025-06-05 18:11:05 +01:00
parent 9624fbfeb1
commit 00bb419ed5
8 changed files with 63 additions and 3 deletions

View File

@@ -3,7 +3,7 @@ use chrono::{DateTime, Utc};
use compute_api::privilege::Privilege;
use compute_api::responses::{
ComputeConfig, ComputeCtlConfig, ComputeMetrics, ComputeStatus, LfcOffloadState,
LfcPrewarmState,
LfcPrewarmState, PromoteState
};
use compute_api::spec::{
ComputeAudit, ComputeFeature, ComputeMode, ComputeSpec, ExtVersion, PgIdent,
@@ -161,6 +161,8 @@ pub struct ComputeState {
pub lfc_prewarm_state: LfcPrewarmState,
pub lfc_offload_state: LfcOffloadState,
pub promote_state: PromoteState,
pub metrics: ComputeMetrics,
}

View File

@@ -0,0 +1,26 @@
use compute_api::responses::{LfcOffloadState, PromoteState};
use crate::compute::ComputeNode;
impl ComputeNode {
pub async fn promote(&self) -> PromoteState {
{
let state = &mut self.state.lock().unwrap().promote_state;
if let PromoteState::Promoting =
std::mem::replace(state, PromoteState::Promoting)
{
return state;
}
}
// reference:: configure
// 1. Check if we're not primary
// 4. Check we have safekeepers list supplied from primary
// 2. Check we have prewarmed LFC
// 3. Wait for last LSN to be committed
// 4. Call pg_promote
if !matches!(self.lfc_offload_state(), LfcOffloadState::Completed) {
}
}
}

View File

@@ -10,7 +10,7 @@ pub(in crate::http) async fn prewarm_state(compute: Compute) -> Json<LfcPrewarmS
}
// Following functions are marked async for axum, as it's more convenient than wrapping these
// in async lambdas at call site
// in asyncr is:closed lambdas at call site
pub(in crate::http) async fn offload_state(compute: Compute) -> Json<LfcOffloadState> {
Json(compute.lfc_offload_state())

View File

@@ -12,6 +12,7 @@ pub(in crate::http) mod failpoints;
pub(in crate::http) mod grants;
pub(in crate::http) mod insights;
pub(in crate::http) mod lfc;
pub(in crate::http) mod promote;
pub(in crate::http) mod metrics;
pub(in crate::http) mod metrics_json;
pub(in crate::http) mod status;

View File

@@ -0,0 +1,17 @@
use axum::response::Response;
use compute_api::responses::PromoteState;
use http::StatusCode;
use crate::http::JsonResponse;
type Compute = axum::extract::State<std::sync::Arc<crate::compute::ComputeNode>>;
/// Returns only when promote failes or succeeds.
/// If a network error occurs, this does not stop promotion, and subsequent
/// calls block until first error or success
pub(in crate::http) async fn promote(compute: Compute) -> Response {
let state = compute.promote().await;
if let PromoteState::Failed { error } = state {
return JsonResponse::error(StatusCode::INTERNAL_SERVER_ERROR, error);
}
JsonResponse::success(StatusCode::OK, state)
}

View File

@@ -23,7 +23,7 @@ use super::{
middleware::authorize::Authorize,
routes::{
check_writability, configure, database_schema, dbs_and_roles, extension_server, extensions,
grants, insights, lfc, metrics, metrics_json, status, terminate,
grants, insights, lfc, metrics, metrics_json, promote, status, terminate,
},
};
use crate::compute::ComputeNode;
@@ -87,6 +87,7 @@ impl From<&Server> for Router<Arc<ComputeNode>> {
let authenticated_router = Router::<Arc<ComputeNode>>::new()
.route("/lfc/prewarm", get(lfc::prewarm_state).post(lfc::prewarm))
.route("/lfc/offload", get(lfc::offload_state).post(lfc::offload))
.route("/promote", post(promote::promote))
.route("/check_writability", post(check_writability::is_writable))
.route("/configure", post(configure::configure))
.route("/database_schema", get(database_schema::get_schema_dump))

View File

@@ -12,6 +12,7 @@ pub mod logger;
pub mod catalog;
pub mod compute;
pub mod compute_prewarm;
pub mod compute_promote;
pub mod disk_quota;
pub mod extension_server;
pub mod installed_extensions;

View File

@@ -70,6 +70,18 @@ pub enum LfcOffloadState {
},
}
#[derive(Serialize, Default, Debug, Clone)]
#[serde(tag = "status", rename_all = "snake_case")]
pub enum PromoteState {
#[default]
NotPromoted,
Promoting,
Completed,
Failed {
error: String,
},
}
/// Response of the /status API
#[derive(Serialize, Debug, Deserialize)]
#[serde(rename_all = "snake_case")]