| 1040 | /// is removed before the new configuration is activated. |
| 1041 | #[doc(hidden)] |
| 1042 | pub async fn initialize_plugins_exact(config: PluginConfig) -> Result<ConfigReport> { |
| 1043 | let report = validate_plugin_config(&config); |
| 1044 | if report.has_errors() { |
| 1045 | return Err(PluginError::InvalidConfig(join_error_messages(&report))); |
| 1046 | } |
| 1047 | |
| 1048 | let previous = { |
| 1049 | let mut guard = ACTIVE_PLUGIN_CONFIGURATION.lock().map_err(|err| { |
| 1050 | PluginError::Internal(format!("active plugin configuration lock poisoned: {err}")) |
| 1051 | })?; |
| 1052 | guard.take() |
| 1053 | }; |
| 1054 | |
| 1055 | if let Some(mut previous_state) = previous { |
| 1056 | rollback_registrations(&mut previous_state.registrations); |
| 1057 | match initialize_plugin_components(&config).await { |
| 1058 | Ok(registrations) => { |
| 1059 | store_active_plugin_configuration(config, report.clone(), registrations)?; |
| 1060 | Ok(report) |
| 1061 | } |
| 1062 | Err(err) => match initialize_plugin_components(&previous_state.config).await { |
| 1063 | Ok(registrations) => { |
| 1064 | let previous_report = validate_plugin_config(&previous_state.config); |
| 1065 | store_active_plugin_configuration( |
| 1066 | previous_state.config, |
| 1067 | previous_report, |
| 1068 | registrations, |
| 1069 | )?; |
| 1070 | Err(err) |
| 1071 | } |
| 1072 | Err(restore_err) => Err(PluginError::RegistrationFailed(format!( |
| 1073 | "{err}; previous plugin configuration could not be restored: {restore_err}" |
| 1074 | ))), |
| 1075 | }, |
| 1076 | } |
| 1077 | } else { |
| 1078 | let registrations = initialize_plugin_components(&config).await?; |
| 1079 | store_active_plugin_configuration(config, report.clone(), registrations)?; |
| 1080 | Ok(report) |
| 1081 | } |
| 1082 | } |
| 1083 | |
| 1084 | /// Validates and activates `config` layered on top of the discovered |
| 1085 | /// `plugins.toml` configuration, so a direct integration sees the same file |