pub mod manager;
pub use manager::{FallbackEvent, FallbackManager, FallbackStats, FallbackStrategy, Feature};
pub fn create_fallback_manager() -> FallbackManager {
FallbackManager::new()
}
pub async fn create_fallback_manager_with_strategies() -> FallbackManager {
let mut manager = FallbackManager::new();
manager
.register_strategies(vec![
(
Feature::V8Optimization,
FallbackStrategy::RetryLater(std::time::Duration::from_millis(100)),
),
(Feature::V8Optimization, FallbackStrategy::DegradeToBasic),
(Feature::V8Optimization, FallbackStrategy::DisableFeature),
])
.await;
manager
.register_strategies(vec![
(
Feature::PythonRuntime,
FallbackStrategy::UseAlternative("Python subprocess".to_string()),
),
(Feature::PythonRuntime, FallbackStrategy::Ignore),
])
.await;
manager
.register_strategies(vec![
(
Feature::GoRuntime,
FallbackStrategy::SwitchToBackup("Go subprocess".to_string()),
),
(Feature::GoRuntime, FallbackStrategy::LogAndContinue),
])
.await;
manager
.register_strategies(vec![
(
Feature::WebAssembly,
FallbackStrategy::RetryLater(std::time::Duration::from_millis(200)),
),
(
Feature::WebAssembly,
FallbackStrategy::UseAlternative("V8 interpretation".to_string()),
),
])
.await;
manager
.register_strategies(vec![
(
Feature::KubernetesIntegration,
FallbackStrategy::LogAndContinue,
),
(Feature::ServiceMesh, FallbackStrategy::Ignore),
(Feature::SecurityManager, FallbackStrategy::DisableFeature),
(Feature::ComplianceManager, FallbackStrategy::DisableFeature),
])
.await;
manager
.register_strategies(vec![
(Feature::EdgeComputing, FallbackStrategy::DegradeToBasic),
(Feature::OfflineMode, FallbackStrategy::Ignore),
(
Feature::DistributedCoordination,
FallbackStrategy::LogAndContinue,
),
])
.await;
manager
}
pub struct FallbackUtils;
impl FallbackUtils {
pub fn should_fallback(error: &crate::error::AmberError) -> bool {
match error {
crate::error::AmberError::V8Error(_) => true,
crate::error::AmberError::MultiLanguageError(_) => true,
crate::error::AmberError::PlatformError(_) => true,
crate::error::AmberError::PerformanceError(_) => true,
crate::error::AmberError::NetworkError(_) => true,
_ => false,
}
}
pub fn get_default_strategy(feature: &Feature) -> FallbackStrategy {
match feature {
Feature::V8Optimization => FallbackStrategy::DegradeToBasic,
Feature::PythonRuntime => FallbackStrategy::UseAlternative("Subprocess".to_string()),
Feature::GoRuntime => FallbackStrategy::SwitchToBackup("Subprocess".to_string()),
Feature::WebAssembly => FallbackStrategy::UseAlternative("V8".to_string()),
Feature::IOSRuntime | Feature::AndroidRuntime => FallbackStrategy::LogAndContinue,
Feature::KubernetesIntegration | Feature::ServiceMesh => FallbackStrategy::Ignore,
Feature::SecurityManager | Feature::ComplianceManager => {
FallbackStrategy::DisableFeature
}
_ => FallbackStrategy::LogAndContinue,
}
}
pub fn create_fallback_suggestions(feature: &Feature) -> Vec<String> {
match feature {
Feature::V8Optimization => vec![
"Consider using simplified V8 flags".to_string(),
"Reduce optimization level".to_string(),
"Disable V8 optimization temporarily".to_string(),
],
Feature::PythonRuntime => vec![
"Use Python subprocess instead".to_string(),
"Switch to Python C extension".to_string(),
"Disable Python integration".to_string(),
],
Feature::GoRuntime => vec![
"Use Go subprocess".to_string(),
"Switch to Go shared library".to_string(),
"Disable Go integration".to_string(),
],
Feature::WebAssembly => vec![
"Use V8 interpretation mode".to_string(),
"Compile to native code".to_string(),
"Disable WASM support".to_string(),
],
Feature::KubernetesIntegration => vec![
"Use standalone deployment".to_string(),
"Disable K8s integration".to_string(),
],
Feature::ServiceMesh => vec![
"Use direct service calls".to_string(),
"Disable service mesh".to_string(),
],
_ => vec![
"Check feature documentation".to_string(),
"Consider disabling the feature".to_string(),
],
}
}
}
#[macro_export]
macro_rules! with_fallback {
($manager:expr, $feature:expr, $operation:block) => {{
let result: _ = $operation;
if let Err(error) = result {
if $crate::fallback::FallbackUtils::should_fallback(&error) {
match $manager.handle_feature_failure($feature).await {
Ok(_) => {
eprintln!("Fallback successful for feature: {}", $feature);
$operation
}
Err(fallback_error) => {
eprintln!("Fallback failed: {}", fallback_error);
Err(error)
}
}
} else {
Err(error)
}
} else {
result
}
}};
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn test_fallback_manager_creation() {
let manager: _ = create_fallback_manager();
assert!(manager.is_feature_active(&Feature::V8Optimization).await);
}
#[tokio::test]
async fn test_fallback_manager_with_strategies() {
let mut manager = create_fallback_manager();
manager
.register_strategy(
Feature::PythonRuntime,
FallbackStrategy::UseAlternative("Test alternative".to_string()),
)
.await;
let strategies: _ = manager.get_strategies(&Feature::PythonRuntime).await;
assert!(strategies.is_some());
assert!(!strategies.unwrap().is_empty());
}
#[test]
fn test_should_fallback() {
let v8_error: _ = crate::error::AmberError::V8Error("Test".to_string());
let config_error: _ = crate::error::AmberError::ConfigurationError("Test".to_string());
assert!(FallbackUtils::should_fallback(&v8_error));
assert!(!FallbackUtils::should_fallback(&config_error));
}
#[test]
fn test_default_strategy() {
let v8_strategy: _ = FallbackUtils::get_default_strategy(&Feature::V8Optimization);
assert!(matches!(v8_strategy, FallbackStrategy::DegradeToBasic));
let python_strategy: _ = FallbackUtils::get_default_strategy(&Feature::PythonRuntime);
assert!(matches!(
python_strategy,
FallbackStrategy::UseAlternative(_)
));
}
#[test]
fn test_fallback_suggestions() {
let suggestions: _ = FallbackUtils::create_fallback_suggestions(&Feature::V8Optimization);
assert!(!suggestions.is_empty());
assert!(suggestions.iter().any(|s| s.contains("V8")));
}
}