v0.1.4-pre.015-fix.002

This commit is contained in:
2026-08-16 18:20:32 +02:00
parent 05c65a12f4
commit 9ad61b40e1
25 changed files with 776 additions and 210 deletions

View File

@@ -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 {