2025-08-30 21:54:11 +08:00
|
|
|
use crate::app_config::MultiAppConfig;
|
refactor(backend): phase 1 - unified error handling with thiserror
Introduce AppError enum to replace Result<T, String> pattern across
the codebase, improving error context preservation and type safety.
## Changes
### Core Infrastructure
- Add src/error.rs with AppError enum using thiserror
- Add thiserror dependency to Cargo.toml
- Implement helper functions: io(), json(), toml() for ergonomic error creation
- Implement From<PoisonError> for automatic lock error conversion
- Implement From<AppError> for String to maintain Tauri command compatibility
### Module Migrations (60% complete)
- config.rs: Full migration to AppError
- read_json_file, write_json_file, atomic_write
- archive_file, copy_file, delete_file
- claude_mcp.rs: Full migration to AppError
- get_mcp_status, read_mcp_json, upsert_mcp_server
- delete_mcp_server, validate_command_in_path
- set_mcp_servers_map
- codex_config.rs: Full migration to AppError
- write_codex_live_atomic with rollback support
- read_and_validate_codex_config_text
- validate_config_toml
- app_config.rs: Partial migration
- MultiAppConfig::load, MultiAppConfig::save
- store.rs: Partial migration
- AppState::save now returns Result<(), AppError>
- commands.rs: Minimal changes
- Use .map_err(Into::into) for compatibility
- mcp.rs: Minimal changes
- sync_enabled_to_claude uses Into::into conversion
### Documentation
- Add docs/BACKEND_REFACTOR_PLAN.md with detailed refactoring roadmap
## Benefits
- Type-safe error handling with preserved error chains
- Better error messages with file paths and context
- Reduced boilerplate code (118 Result<T, String> instances to migrate)
- Automatic error conversion for seamless integration
## Testing
- All existing tests pass (4/4)
- Compilation successful with no warnings
- Build time: 0.61s (no performance regression)
## Remaining Work
- claude_plugin.rs (7 functions)
- migration.rs, import_export.rs
- Add unit tests for error.rs
- Complete commands.rs migration after dependent modules
Co-authored-by: Claude <claude@anthropic.com>
2025-10-27 16:29:11 +08:00
|
|
|
use crate::error::AppError;
|
2025-10-28 12:23:44 +08:00
|
|
|
use std::sync::RwLock;
|
2025-08-23 20:12:35 +08:00
|
|
|
|
|
|
|
|
/// 全局应用状态
|
|
|
|
|
pub struct AppState {
|
2025-10-28 12:23:44 +08:00
|
|
|
pub config: RwLock<MultiAppConfig>,
|
2025-08-23 20:12:35 +08:00
|
|
|
}
|
|
|
|
|
|
refactor(backend): extract MCP service layer with snapshot isolation
Extract all MCP business logic from command layer into `services/mcp.rs`,
implementing snapshot isolation pattern to optimize lock granularity after
RwLock migration in Phase 5.
## Key Changes
### Service Layer (`services/mcp.rs`)
- Add `McpService` with 7 methods: `get_servers`, `upsert_server`,
`delete_server`, `set_enabled`, `sync_enabled`, `import_from_claude`,
`import_from_codex`
- Implement snapshot isolation: acquire write lock only for in-memory
modifications, clone config snapshot, release lock, then perform file I/O
with snapshot
- Use conditional cloning: only clone config when sync is actually needed
(e.g., when `enabled` flag is true or `sync_other_side` is requested)
### Command Layer (`commands/mcp.rs`)
- Reduce to thin wrappers: parse parameters and delegate to `McpService`
- Remove all `*_internal` and `*_test_hook` functions (-94 lines)
- Each command now 5-10 lines (parameter parsing + service call + error mapping)
### Core Logic Refactoring (`mcp.rs`)
- Rename `set_enabled_and_sync_for` → `set_enabled_flag_for`
- Remove file sync logic from low-level function, move sync responsibility
to service layer for better separation of concerns
### Test Adaptation (`tests/mcp_commands.rs`)
- Replace test hooks with direct `McpService` calls
- All 5 MCP integration tests pass
### Additional Fixes
- Add `Default` impl for `AppState` (clippy suggestion)
- Remove unnecessary auto-deref in `commands/provider.rs` and `lib.rs`
- Update Phase 4/5 progress in `BACKEND_REFACTOR_PLAN.md`
## Performance Impact
**Before**: Write lock held during file I/O (~10ms), blocking all readers
**After**: Write lock held only for memory ops (~100μs), file I/O lock-free
Estimated throughput improvement: ~2x in high-concurrency read scenarios
## Testing
- ✅ All tests pass: 5 MCP commands + 7 provider service tests
- ✅ Zero clippy warnings with `-D warnings`
- ✅ No behavioral changes, maintains original save semantics
Part of Phase 4 (Service Layer Abstraction) of backend refactoring roadmap.
2025-10-28 14:59:28 +08:00
|
|
|
impl Default for AppState {
|
|
|
|
|
fn default() -> Self {
|
|
|
|
|
Self::new()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-23 20:12:35 +08:00
|
|
|
impl AppState {
|
|
|
|
|
/// 创建新的应用状态
|
|
|
|
|
pub fn new() -> Self {
|
2025-08-30 21:54:11 +08:00
|
|
|
let config = MultiAppConfig::load().unwrap_or_else(|e| {
|
2025-08-27 11:00:53 +08:00
|
|
|
log::warn!("加载配置失败: {}, 使用默认配置", e);
|
2025-08-30 21:54:11 +08:00
|
|
|
MultiAppConfig::default()
|
2025-08-27 11:00:53 +08:00
|
|
|
});
|
|
|
|
|
|
2025-08-23 20:12:35 +08:00
|
|
|
Self {
|
2025-10-28 12:23:44 +08:00
|
|
|
config: RwLock::new(config),
|
2025-08-23 20:12:35 +08:00
|
|
|
}
|
|
|
|
|
}
|
2025-08-27 11:00:53 +08:00
|
|
|
|
2025-08-23 20:12:35 +08:00
|
|
|
/// 保存配置到文件
|
refactor(backend): phase 1 - unified error handling with thiserror
Introduce AppError enum to replace Result<T, String> pattern across
the codebase, improving error context preservation and type safety.
## Changes
### Core Infrastructure
- Add src/error.rs with AppError enum using thiserror
- Add thiserror dependency to Cargo.toml
- Implement helper functions: io(), json(), toml() for ergonomic error creation
- Implement From<PoisonError> for automatic lock error conversion
- Implement From<AppError> for String to maintain Tauri command compatibility
### Module Migrations (60% complete)
- config.rs: Full migration to AppError
- read_json_file, write_json_file, atomic_write
- archive_file, copy_file, delete_file
- claude_mcp.rs: Full migration to AppError
- get_mcp_status, read_mcp_json, upsert_mcp_server
- delete_mcp_server, validate_command_in_path
- set_mcp_servers_map
- codex_config.rs: Full migration to AppError
- write_codex_live_atomic with rollback support
- read_and_validate_codex_config_text
- validate_config_toml
- app_config.rs: Partial migration
- MultiAppConfig::load, MultiAppConfig::save
- store.rs: Partial migration
- AppState::save now returns Result<(), AppError>
- commands.rs: Minimal changes
- Use .map_err(Into::into) for compatibility
- mcp.rs: Minimal changes
- sync_enabled_to_claude uses Into::into conversion
### Documentation
- Add docs/BACKEND_REFACTOR_PLAN.md with detailed refactoring roadmap
## Benefits
- Type-safe error handling with preserved error chains
- Better error messages with file paths and context
- Reduced boilerplate code (118 Result<T, String> instances to migrate)
- Automatic error conversion for seamless integration
## Testing
- All existing tests pass (4/4)
- Compilation successful with no warnings
- Build time: 0.61s (no performance regression)
## Remaining Work
- claude_plugin.rs (7 functions)
- migration.rs, import_export.rs
- Add unit tests for error.rs
- Complete commands.rs migration after dependent modules
Co-authored-by: Claude <claude@anthropic.com>
2025-10-27 16:29:11 +08:00
|
|
|
pub fn save(&self) -> Result<(), AppError> {
|
2025-10-28 12:23:44 +08:00
|
|
|
let config = self.config.read().map_err(AppError::from)?;
|
2025-08-27 11:00:53 +08:00
|
|
|
|
2025-08-30 21:54:11 +08:00
|
|
|
config.save()
|
2025-08-23 20:12:35 +08:00
|
|
|
}
|
2025-08-25 21:41:35 +08:00
|
|
|
}
|