v0.1.4-pre.015-fix.002
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-app-config-desk/src/logging_editor.rs
|
||||
// version: 2
|
||||
// version: 3
|
||||
|
||||
//! Typed Logging document projection and validated persistence for the Config Desk Logging editor.
|
||||
|
||||
@@ -127,7 +127,13 @@ pub(crate) struct LoggingDocumentSaveResultDto {
|
||||
pub(crate) source_changed: bool,
|
||||
/// Whether Config consumers must reload the document.
|
||||
pub(crate) reload_required: bool,
|
||||
/// Fresh typed document loaded after successful persistence.
|
||||
/// Whether the active KSP Logging runtime was hot-reloaded from the persisted candidate.
|
||||
pub(crate) runtime_applied: bool,
|
||||
/// Runtime generation after the successful hot reload.
|
||||
pub(crate) logging_generation: u32,
|
||||
/// Profile selected and applied to the runtime.
|
||||
pub(crate) active_profile: String,
|
||||
/// Fresh typed document loaded after successful persistence and runtime application.
|
||||
pub(crate) document: LoggingDocumentDto,
|
||||
}
|
||||
|
||||
@@ -136,14 +142,31 @@ pub(crate) fn document(state: &crate::AppState) -> ksp_core_lib::Result<LoggingD
|
||||
return document_from_management(state.config_management());
|
||||
}
|
||||
|
||||
/// Validates and atomically persists one typed Logging candidate through ConfigManagement.
|
||||
/// Validates, atomically persists and hot-reloads one typed Logging candidate through ConfigManagement and `ksp-logging-lib`.
|
||||
pub(crate) fn save(state: &crate::AppState, candidate: LoggingDocumentCandidateDto) -> ksp_core_lib::Result<LoggingDocumentSaveResultDto> {
|
||||
let file_id = ksp_config_lib::ConfigFileId::new(ksp_config_lib::FILE_ID_STD_LOGGING);
|
||||
let file_id = match file_id {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let previous = state.config_management().read_source(&file_id);
|
||||
let previous = match previous {
|
||||
std::result::Result::Ok(value) => value.content().to_owned(),
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let source = config_candidate(candidate);
|
||||
let report = state.config_management().save_logging_document(&source);
|
||||
let report = match report {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let applied = apply_persisted_runtime(state);
|
||||
let (active_profile, logging_generation) = match applied {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => {
|
||||
return rollback_after_runtime_failure(state.config_management(), &file_id, previous.as_str(), report.source_changed(), error);
|
||||
},
|
||||
};
|
||||
let document = document_from_management(state.config_management());
|
||||
let document = match document {
|
||||
std::result::Result::Ok(value) => value,
|
||||
@@ -154,17 +177,68 @@ pub(crate) fn save(state: &crate::AppState, candidate: LoggingDocumentCandidateD
|
||||
domain = crate::TRACING_DOMAIN_LOGGING_EDITOR,
|
||||
source_changed = report.source_changed(),
|
||||
reload_required = report.reload_required(),
|
||||
runtime_applied = true,
|
||||
logging_generation,
|
||||
active_profile = active_profile.as_str(),
|
||||
profile_count = document.profiles.len(),
|
||||
default_profile = document.default_profile.as_str(),
|
||||
"typed Logging document persistence completed; runtime was not reinitialized"
|
||||
"typed Logging document persistence and runtime hot reload completed"
|
||||
);
|
||||
return std::result::Result::Ok(LoggingDocumentSaveResultDto {
|
||||
source_changed: report.source_changed(),
|
||||
reload_required: report.reload_required(),
|
||||
runtime_applied: true,
|
||||
logging_generation,
|
||||
active_profile,
|
||||
document,
|
||||
});
|
||||
}
|
||||
|
||||
fn apply_persisted_runtime(state: &crate::AppState) -> ksp_core_lib::Result<(String, u32)> {
|
||||
let environment = ksp_config_lib::ConfigEnvironment::load();
|
||||
let environment = match environment {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let resolved = state.config_management().engine().load_resolved_logging_config(std::option::Option::None, &environment);
|
||||
let resolved = match resolved {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let profile_id = resolved.profile_id().to_owned();
|
||||
let settings = resolved.into_settings();
|
||||
let generation = state.reinitialize_logging_runtime(profile_id.as_str(), &settings);
|
||||
return match generation {
|
||||
std::result::Result::Ok(value) => std::result::Result::Ok((profile_id, value)),
|
||||
std::result::Result::Err(error) => std::result::Result::Err(error),
|
||||
};
|
||||
}
|
||||
|
||||
fn rollback_after_runtime_failure(
|
||||
management: &ksp_config_lib::ConfigManagement,
|
||||
file_id: &ksp_config_lib::ConfigFileId,
|
||||
previous_source: &str,
|
||||
source_changed: bool,
|
||||
runtime_error: ksp_core_lib::Error,
|
||||
) -> ksp_core_lib::Result<LoggingDocumentSaveResultDto> {
|
||||
if !source_changed {
|
||||
return std::result::Result::Err(runtime_error);
|
||||
}
|
||||
let rollback = management.save_source_candidate(file_id, previous_source);
|
||||
return match rollback {
|
||||
std::result::Result::Ok(_) => std::result::Result::Err(runtime_error),
|
||||
std::result::Result::Err(rollback_error) => std::result::Result::Err(
|
||||
ksp_core_lib::Error::new(
|
||||
crate::ERROR_CODE_LOGGING_SOURCE_ROLLBACK_FAILED,
|
||||
"Logging runtime hot reload failed and the previous persisted source could not be restored",
|
||||
)
|
||||
.with_context("runtime_error_domain", runtime_error.code().domain())
|
||||
.with_context("runtime_error_code", runtime_error.code().code())
|
||||
.with_source(rollback_error),
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
fn document_from_management(management: &ksp_config_lib::ConfigManagement) -> ksp_core_lib::Result<LoggingDocumentDto> {
|
||||
let source = management.load_logging_document();
|
||||
let source = match source {
|
||||
|
||||
Reference in New Issue
Block a user