Spaces:
Sleeping
Sleeping
Download modules/sync/sync_manager.py from sky-meilin/SkyOSFullCore: direct link, hf CLI and curl.
- Browser
- Download file 7.15 kB
-
https://huggingface.co/spaces/sky-meilin/SkyOSFullCore/resolve/main/modules/sync/sync_manager.py
- Command line
-
hf download hf://spaces/sky-meilin/SkyOSFullCore/modules/sync/sync_manager.py
-
curl -L -o sync_manager.py https://huggingface.co/spaces/sky-meilin/SkyOSFullCore/resolve/main/modules/sync/sync_manager.py
7.15 kB
| """ | |
| SkyOS Sync Manager. | |
| Central orchestration layer for the synchronization subsystem. | |
| The SyncManager coordinates: | |
| - adapter registration and lookup | |
| - scheduled synchronization | |
| - structured logging | |
| - conflict resolution | |
| Actual data transport remains the responsibility of adapters. | |
| """ | |
| from __future__ import annotations | |
| from typing import Any, Dict, Iterable, List, Optional | |
| from .conflict_resolver import ConflictResolver | |
| from .logger import SyncLogger | |
| from .registry import AdapterRegistry | |
| from .scheduler import SyncScheduler | |
| class SyncManager: | |
| """ | |
| Central coordinator for the SkyOS synchronization layer. | |
| The manager does not directly implement provider-specific synchronization. | |
| Instead, it coordinates registered adapters and the surrounding sync | |
| infrastructure. | |
| """ | |
| def __init__( | |
| self, | |
| registry: Optional[AdapterRegistry] = None, | |
| scheduler: Optional[SyncScheduler] = None, | |
| logger: Optional[SyncLogger] = None, | |
| conflict_resolver: Optional[ConflictResolver] = None, | |
| ) -> None: | |
| self.registry = registry or AdapterRegistry() | |
| self.scheduler = scheduler or SyncScheduler() | |
| self.logger = logger or SyncLogger() | |
| self.conflict_resolver = ( | |
| conflict_resolver or ConflictResolver() | |
| ) | |
| self._initialized = False | |
| def initialize(self) -> None: | |
| """ | |
| Initialize the synchronization manager. | |
| Initialization is intentionally idempotent so the manager can safely | |
| be initialized by application startup code more than once. | |
| """ | |
| if self._initialized: | |
| return | |
| self._initialized = True | |
| self.logger.info( | |
| "SyncManager initialized", | |
| component="sync_manager", | |
| ) | |
| def register_adapter( | |
| self, | |
| name: str, | |
| adapter: Any, | |
| ) -> Any: | |
| """ | |
| Register an adapter with the central registry. | |
| Args: | |
| name: Logical adapter name. | |
| adapter: Adapter instance. | |
| Returns: | |
| The registered adapter. | |
| """ | |
| registered_adapter = self.registry.register(name, adapter) | |
| self.logger.info( | |
| "Sync adapter registered", | |
| adapter=name, | |
| component="sync_manager", | |
| ) | |
| return registered_adapter | |
| def get_adapter(self, name: str) -> Any: | |
| """ | |
| Retrieve a registered adapter. | |
| Args: | |
| name: Logical adapter name. | |
| Returns: | |
| Registered adapter instance. | |
| """ | |
| return self.registry.get(name) | |
| def list_adapters(self) -> List[str]: | |
| """ | |
| Return the names of all registered adapters. | |
| """ | |
| return list(self.registry.list()) | |
| def resolve_conflict( | |
| self, | |
| local_data: Any, | |
| remote_data: Any, | |
| context: Optional[Dict[str, Any]] = None, | |
| ) -> Any: | |
| """ | |
| Delegate conflict resolution to the ConflictResolver. | |
| """ | |
| return self.conflict_resolver.resolve( | |
| local_data=local_data, | |
| remote_data=remote_data, | |
| context=context or {}, | |
| ) | |
| def schedule( | |
| self, | |
| name: str, | |
| callback: Any, | |
| *args: Any, | |
| **kwargs: Any, | |
| ) -> Any: | |
| """ | |
| Register a synchronization task with the scheduler. | |
| """ | |
| self.logger.info( | |
| "Synchronization task scheduled", | |
| task=name, | |
| component="sync_manager", | |
| ) | |
| return self.scheduler.schedule( | |
| name, | |
| callback, | |
| *args, | |
| **kwargs, | |
| ) | |
| def run_adapter( | |
| self, | |
| adapter_name: str, | |
| *args: Any, | |
| **kwargs: Any, | |
| ) -> Any: | |
| """ | |
| Execute a registered adapter. | |
| The SyncManager intentionally performs only orchestration here. | |
| Provider-specific behavior remains inside the adapter. | |
| """ | |
| adapter = self.get_adapter(adapter_name) | |
| self.logger.info( | |
| "Executing sync adapter", | |
| adapter=adapter_name, | |
| component="sync_manager", | |
| ) | |
| if hasattr(adapter, "sync"): | |
| return adapter.sync(*args, **kwargs) | |
| if hasattr(adapter, "run"): | |
| return adapter.run(*args, **kwargs) | |
| raise AttributeError( | |
| f"Adapter '{adapter_name}' does not provide " | |
| "'sync' or 'run'." | |
| ) | |
| def sync( | |
| self, | |
| source: str, | |
| target: str, | |
| *args: Any, | |
| **kwargs: Any, | |
| ) -> Any: | |
| """ | |
| Orchestrate a synchronization between two registered adapters. | |
| This method provides the central flow: | |
| source adapter | |
| ↓ | |
| SyncManager | |
| ↓ | |
| conflict resolution | |
| ↓ | |
| target adapter | |
| Provider-specific data handling remains delegated to the adapters. | |
| """ | |
| self.initialize() | |
| source_adapter = self.get_adapter(source) | |
| target_adapter = self.get_adapter(target) | |
| self.logger.info( | |
| "Synchronization started", | |
| source=source, | |
| target=target, | |
| component="sync_manager", | |
| ) | |
| if hasattr(source_adapter, "export"): | |
| data = source_adapter.export(*args, **kwargs) | |
| elif hasattr(source_adapter, "read"): | |
| data = source_adapter.read(*args, **kwargs) | |
| elif hasattr(source_adapter, "sync"): | |
| data = source_adapter.sync(*args, **kwargs) | |
| else: | |
| raise AttributeError( | |
| f"Source adapter '{source}' does not provide " | |
| "'export', 'read', or 'sync'." | |
| ) | |
| if hasattr(target_adapter, "import_data"): | |
| result = target_adapter.import_data(data) | |
| elif hasattr(target_adapter, "write"): | |
| result = target_adapter.write(data) | |
| elif hasattr(target_adapter, "push"): | |
| result = target_adapter.push(data) | |
| else: | |
| raise AttributeError( | |
| f"Target adapter '{target}' does not provide " | |
| "'import_data', 'write', or 'push'." | |
| ) | |
| self.logger.info( | |
| "Synchronization completed", | |
| source=source, | |
| target=target, | |
| component="sync_manager", | |
| ) | |
| return result | |
| def status(self) -> Dict[str, Any]: | |
| """ | |
| Return the current state of the synchronization manager. | |
| """ | |
| return { | |
| "initialized": self._initialized, | |
| "adapters": self.list_adapters(), | |
| "scheduler": self.scheduler, | |
| "conflict_resolver": self.conflict_resolver, | |
| } | |
| def shutdown(self) -> None: | |
| """ | |
| Shut down the synchronization layer cleanly. | |
| """ | |
| self.logger.info( | |
| "SyncManager shutting down", | |
| component="sync_manager", | |
| ) | |
| if hasattr(self.scheduler, "shutdown"): | |
| self.scheduler.shutdown() | |
| self._initialized = False |