exonware-xwlazy 0.1.0.22__py3-none-any.whl → 1.0.1.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- exonware/__init__.py +86 -16
- exonware/xwlazy/version.py +5 -5
- exonware/xwlazy.py +2546 -0
- exonware/xwlazy_external_libs.toml +716 -0
- {exonware_xwlazy-0.1.0.22.dist-info → exonware_xwlazy-1.0.1.2.dist-info}/METADATA +6 -6
- exonware_xwlazy-1.0.1.2.dist-info/RECORD +8 -0
- exonware/xwlazy/__init__.py +0 -367
- exonware/xwlazy/common/__init__.py +0 -47
- exonware/xwlazy/common/base.py +0 -56
- exonware/xwlazy/common/cache.py +0 -504
- exonware/xwlazy/common/logger.py +0 -257
- exonware/xwlazy/common/services/__init__.py +0 -72
- exonware/xwlazy/common/services/dependency_mapper.py +0 -232
- exonware/xwlazy/common/services/install_async_utils.py +0 -165
- exonware/xwlazy/common/services/install_cache_utils.py +0 -245
- exonware/xwlazy/common/services/keyword_detection.py +0 -283
- exonware/xwlazy/common/services/spec_cache.py +0 -165
- exonware/xwlazy/common/services/state_manager.py +0 -84
- exonware/xwlazy/common/strategies/__init__.py +0 -28
- exonware/xwlazy/common/strategies/caching_dict.py +0 -44
- exonware/xwlazy/common/strategies/caching_installation.py +0 -88
- exonware/xwlazy/common/strategies/caching_lfu.py +0 -66
- exonware/xwlazy/common/strategies/caching_lru.py +0 -63
- exonware/xwlazy/common/strategies/caching_multitier.py +0 -59
- exonware/xwlazy/common/strategies/caching_ttl.py +0 -59
- exonware/xwlazy/config.py +0 -193
- exonware/xwlazy/contracts.py +0 -1396
- exonware/xwlazy/defs.py +0 -378
- exonware/xwlazy/errors.py +0 -276
- exonware/xwlazy/facade.py +0 -991
- exonware/xwlazy/module/__init__.py +0 -18
- exonware/xwlazy/module/base.py +0 -565
- exonware/xwlazy/module/data.py +0 -17
- exonware/xwlazy/module/facade.py +0 -246
- exonware/xwlazy/module/importer_engine.py +0 -2117
- exonware/xwlazy/module/strategies/__init__.py +0 -22
- exonware/xwlazy/module/strategies/module_helper_lazy.py +0 -93
- exonware/xwlazy/module/strategies/module_helper_simple.py +0 -65
- exonware/xwlazy/module/strategies/module_manager_advanced.py +0 -111
- exonware/xwlazy/module/strategies/module_manager_simple.py +0 -95
- exonware/xwlazy/package/__init__.py +0 -18
- exonware/xwlazy/package/base.py +0 -798
- exonware/xwlazy/package/conf.py +0 -324
- exonware/xwlazy/package/data.py +0 -17
- exonware/xwlazy/package/facade.py +0 -480
- exonware/xwlazy/package/services/__init__.py +0 -84
- exonware/xwlazy/package/services/async_install_handle.py +0 -87
- exonware/xwlazy/package/services/config_manager.py +0 -245
- exonware/xwlazy/package/services/discovery.py +0 -370
- exonware/xwlazy/package/services/host_packages.py +0 -145
- exonware/xwlazy/package/services/install_async.py +0 -277
- exonware/xwlazy/package/services/install_cache.py +0 -145
- exonware/xwlazy/package/services/install_interactive.py +0 -59
- exonware/xwlazy/package/services/install_policy.py +0 -156
- exonware/xwlazy/package/services/install_registry.py +0 -54
- exonware/xwlazy/package/services/install_result.py +0 -17
- exonware/xwlazy/package/services/install_sbom.py +0 -153
- exonware/xwlazy/package/services/install_utils.py +0 -79
- exonware/xwlazy/package/services/installer_engine.py +0 -406
- exonware/xwlazy/package/services/lazy_installer.py +0 -718
- exonware/xwlazy/package/services/manifest.py +0 -496
- exonware/xwlazy/package/services/strategy_registry.py +0 -186
- exonware/xwlazy/package/strategies/__init__.py +0 -57
- exonware/xwlazy/package/strategies/package_discovery_file.py +0 -129
- exonware/xwlazy/package/strategies/package_discovery_hybrid.py +0 -84
- exonware/xwlazy/package/strategies/package_discovery_manifest.py +0 -101
- exonware/xwlazy/package/strategies/package_execution_async.py +0 -113
- exonware/xwlazy/package/strategies/package_execution_cached.py +0 -90
- exonware/xwlazy/package/strategies/package_execution_pip.py +0 -99
- exonware/xwlazy/package/strategies/package_execution_wheel.py +0 -106
- exonware/xwlazy/package/strategies/package_mapping_discovery_first.py +0 -100
- exonware/xwlazy/package/strategies/package_mapping_hybrid.py +0 -105
- exonware/xwlazy/package/strategies/package_mapping_manifest_first.py +0 -100
- exonware/xwlazy/package/strategies/package_policy_allow_list.py +0 -57
- exonware/xwlazy/package/strategies/package_policy_deny_list.py +0 -57
- exonware/xwlazy/package/strategies/package_policy_permissive.py +0 -46
- exonware/xwlazy/package/strategies/package_timing_clean.py +0 -67
- exonware/xwlazy/package/strategies/package_timing_full.py +0 -66
- exonware/xwlazy/package/strategies/package_timing_smart.py +0 -68
- exonware/xwlazy/package/strategies/package_timing_temporary.py +0 -66
- exonware/xwlazy/runtime/__init__.py +0 -18
- exonware/xwlazy/runtime/adaptive_learner.py +0 -129
- exonware/xwlazy/runtime/base.py +0 -274
- exonware/xwlazy/runtime/facade.py +0 -94
- exonware/xwlazy/runtime/intelligent_selector.py +0 -170
- exonware/xwlazy/runtime/metrics.py +0 -60
- exonware/xwlazy/runtime/performance.py +0 -37
- exonware_xwlazy-0.1.0.22.dist-info/RECORD +0 -87
- {exonware_xwlazy-0.1.0.22.dist-info → exonware_xwlazy-1.0.1.2.dist-info}/WHEEL +0 -0
- {exonware_xwlazy-0.1.0.22.dist-info → exonware_xwlazy-1.0.1.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Full Timing Strategy
|
|
3
|
-
|
|
4
|
-
Company: eXonware.com
|
|
5
|
-
Author: Eng. Muhammad AlShehri
|
|
6
|
-
Email: connect@exonware.com
|
|
7
|
-
|
|
8
|
-
Generation Date: 15-Nov-2025
|
|
9
|
-
|
|
10
|
-
Full timing - install all dependencies upfront.
|
|
11
|
-
"""
|
|
12
|
-
|
|
13
|
-
from typing import List, Any
|
|
14
|
-
from ...package.base import AInstallTimingStrategy
|
|
15
|
-
|
|
16
|
-
class FullTiming(AInstallTimingStrategy):
|
|
17
|
-
"""
|
|
18
|
-
Full timing strategy - installs all packages upfront (LazyInstallMode.FULL).
|
|
19
|
-
|
|
20
|
-
Batch installs all dependencies in parallel on initialization.
|
|
21
|
-
"""
|
|
22
|
-
|
|
23
|
-
def should_install_now(self, package_name: str, context: Any) -> bool:
|
|
24
|
-
"""
|
|
25
|
-
Determine if package should be installed now.
|
|
26
|
-
|
|
27
|
-
Full mode: Install all upfront.
|
|
28
|
-
|
|
29
|
-
Args:
|
|
30
|
-
package_name: Package name to check
|
|
31
|
-
context: Context information (ignored in full mode)
|
|
32
|
-
|
|
33
|
-
Returns:
|
|
34
|
-
True (always install upfront)
|
|
35
|
-
"""
|
|
36
|
-
return True
|
|
37
|
-
|
|
38
|
-
def should_uninstall_after(self, package_name: str, context: Any) -> bool:
|
|
39
|
-
"""
|
|
40
|
-
Determine if package should be uninstalled after use.
|
|
41
|
-
|
|
42
|
-
Full mode: Keep installed after use.
|
|
43
|
-
|
|
44
|
-
Args:
|
|
45
|
-
package_name: Package name to check
|
|
46
|
-
context: Context information
|
|
47
|
-
|
|
48
|
-
Returns:
|
|
49
|
-
False (keep installed)
|
|
50
|
-
"""
|
|
51
|
-
return False
|
|
52
|
-
|
|
53
|
-
def get_install_priority(self, packages: List[str]) -> List[str]:
|
|
54
|
-
"""
|
|
55
|
-
Get priority order for installing packages.
|
|
56
|
-
|
|
57
|
-
Full mode: Install all in parallel (no specific order).
|
|
58
|
-
|
|
59
|
-
Args:
|
|
60
|
-
packages: List of package names
|
|
61
|
-
|
|
62
|
-
Returns:
|
|
63
|
-
Priority-ordered list (original order)
|
|
64
|
-
"""
|
|
65
|
-
return packages
|
|
66
|
-
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Smart Timing Strategy
|
|
3
|
-
|
|
4
|
-
Company: eXonware.com
|
|
5
|
-
Author: Eng. Muhammad AlShehri
|
|
6
|
-
Email: connect@exonware.com
|
|
7
|
-
|
|
8
|
-
Generation Date: 15-Nov-2025
|
|
9
|
-
|
|
10
|
-
Smart timing - install on first usage (on-demand).
|
|
11
|
-
"""
|
|
12
|
-
|
|
13
|
-
from typing import List, Any
|
|
14
|
-
from ...package.base import AInstallTimingStrategy
|
|
15
|
-
from ...defs import LazyInstallMode
|
|
16
|
-
|
|
17
|
-
class SmartTiming(AInstallTimingStrategy):
|
|
18
|
-
"""
|
|
19
|
-
Smart timing strategy - installs packages on-demand (LazyInstallMode.SMART).
|
|
20
|
-
|
|
21
|
-
Installs package when first needed, then caches the result.
|
|
22
|
-
"""
|
|
23
|
-
|
|
24
|
-
def should_install_now(self, package_name: str, context: Any) -> bool:
|
|
25
|
-
"""
|
|
26
|
-
Determine if package should be installed now.
|
|
27
|
-
|
|
28
|
-
Smart mode: Install when first needed.
|
|
29
|
-
|
|
30
|
-
Args:
|
|
31
|
-
package_name: Package name to check
|
|
32
|
-
context: Context information (e.g., import error)
|
|
33
|
-
|
|
34
|
-
Returns:
|
|
35
|
-
True if should install now
|
|
36
|
-
"""
|
|
37
|
-
# In smart mode, install when first needed (context indicates need)
|
|
38
|
-
return context is not None
|
|
39
|
-
|
|
40
|
-
def should_uninstall_after(self, package_name: str, context: Any) -> bool:
|
|
41
|
-
"""
|
|
42
|
-
Determine if package should be uninstalled after use.
|
|
43
|
-
|
|
44
|
-
Smart mode: Keep installed after use.
|
|
45
|
-
|
|
46
|
-
Args:
|
|
47
|
-
package_name: Package name to check
|
|
48
|
-
context: Context information
|
|
49
|
-
|
|
50
|
-
Returns:
|
|
51
|
-
False (keep installed)
|
|
52
|
-
"""
|
|
53
|
-
return False
|
|
54
|
-
|
|
55
|
-
def get_install_priority(self, packages: List[str]) -> List[str]:
|
|
56
|
-
"""
|
|
57
|
-
Get priority order for installing packages.
|
|
58
|
-
|
|
59
|
-
Smart mode: Install in order requested.
|
|
60
|
-
|
|
61
|
-
Args:
|
|
62
|
-
packages: List of package names
|
|
63
|
-
|
|
64
|
-
Returns:
|
|
65
|
-
Priority-ordered list
|
|
66
|
-
"""
|
|
67
|
-
return packages
|
|
68
|
-
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Temporary Timing Strategy
|
|
3
|
-
|
|
4
|
-
Company: eXonware.com
|
|
5
|
-
Author: Eng. Muhammad AlShehri
|
|
6
|
-
Email: connect@exonware.com
|
|
7
|
-
|
|
8
|
-
Generation Date: 15-Nov-2025
|
|
9
|
-
|
|
10
|
-
Temporary timing - always uninstall after use (more aggressive than CLEAN).
|
|
11
|
-
"""
|
|
12
|
-
|
|
13
|
-
from typing import List, Any
|
|
14
|
-
from ...package.base import AInstallTimingStrategy
|
|
15
|
-
|
|
16
|
-
class TemporaryTiming(AInstallTimingStrategy):
|
|
17
|
-
"""
|
|
18
|
-
Temporary timing strategy - always uninstalls after use (LazyInstallMode.TEMPORARY).
|
|
19
|
-
|
|
20
|
-
More aggressive than CLEAN - always uninstalls packages after use.
|
|
21
|
-
"""
|
|
22
|
-
|
|
23
|
-
def should_install_now(self, package_name: str, context: Any) -> bool:
|
|
24
|
-
"""
|
|
25
|
-
Determine if package should be installed now.
|
|
26
|
-
|
|
27
|
-
Temporary mode: Install when first needed.
|
|
28
|
-
|
|
29
|
-
Args:
|
|
30
|
-
package_name: Package name to check
|
|
31
|
-
context: Context information (e.g., import error)
|
|
32
|
-
|
|
33
|
-
Returns:
|
|
34
|
-
True if should install now
|
|
35
|
-
"""
|
|
36
|
-
return context is not None
|
|
37
|
-
|
|
38
|
-
def should_uninstall_after(self, package_name: str, context: Any) -> bool:
|
|
39
|
-
"""
|
|
40
|
-
Determine if package should be uninstalled after use.
|
|
41
|
-
|
|
42
|
-
Temporary mode: Always uninstall after use.
|
|
43
|
-
|
|
44
|
-
Args:
|
|
45
|
-
package_name: Package name to check
|
|
46
|
-
context: Context information (ignored)
|
|
47
|
-
|
|
48
|
-
Returns:
|
|
49
|
-
True (always uninstall)
|
|
50
|
-
"""
|
|
51
|
-
return True
|
|
52
|
-
|
|
53
|
-
def get_install_priority(self, packages: List[str]) -> List[str]:
|
|
54
|
-
"""
|
|
55
|
-
Get priority order for installing packages.
|
|
56
|
-
|
|
57
|
-
Temporary mode: Install in order requested.
|
|
58
|
-
|
|
59
|
-
Args:
|
|
60
|
-
packages: List of package names
|
|
61
|
-
|
|
62
|
-
Returns:
|
|
63
|
-
Priority-ordered list
|
|
64
|
-
"""
|
|
65
|
-
return packages
|
|
66
|
-
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Runtime Services Module
|
|
3
|
-
|
|
4
|
-
This module provides concrete implementations for runtime services.
|
|
5
|
-
Main facade: XWRuntimeHelper extends ARuntimeHelper
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
# Lazy imports to avoid circular dependencies
|
|
9
|
-
def __getattr__(name: str):
|
|
10
|
-
if name == 'XWRuntimeHelper':
|
|
11
|
-
from .facade import XWRuntimeHelper
|
|
12
|
-
return XWRuntimeHelper
|
|
13
|
-
if name == 'XWRuntime': # Backward compatibility alias
|
|
14
|
-
from .facade import XWRuntimeHelper
|
|
15
|
-
return XWRuntimeHelper
|
|
16
|
-
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
|
17
|
-
|
|
18
|
-
__all__ = ['XWRuntimeHelper', 'XWRuntime'] # XWRuntime is backward compatibility alias
|
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
#exonware/xwlazy/src/exonware/xwlazy/loading/adaptive_utils.py
|
|
3
|
-
|
|
4
|
-
Adaptive learning utilities for pattern-based optimization.
|
|
5
|
-
|
|
6
|
-
Company: eXonware.com
|
|
7
|
-
Author: Eng. Muhammad AlShehri
|
|
8
|
-
Email: connect@exonware.com
|
|
9
|
-
|
|
10
|
-
Generation Date: 19-Nov-2025
|
|
11
|
-
|
|
12
|
-
This module provides adaptive learning for ADAPTIVE mode.
|
|
13
|
-
"""
|
|
14
|
-
|
|
15
|
-
import time
|
|
16
|
-
import threading
|
|
17
|
-
from typing import Dict, List, Tuple, Optional
|
|
18
|
-
from collections import defaultdict, deque
|
|
19
|
-
|
|
20
|
-
# Logger not used in this module, removed to avoid circular dependency
|
|
21
|
-
|
|
22
|
-
class AdaptiveLearner:
|
|
23
|
-
"""Learns import patterns and optimizes loading strategy."""
|
|
24
|
-
|
|
25
|
-
def __init__(self, learning_window: int = 100, prediction_depth: int = 3):
|
|
26
|
-
"""
|
|
27
|
-
Initialize adaptive learner.
|
|
28
|
-
|
|
29
|
-
Args:
|
|
30
|
-
learning_window: Number of imports to track for learning
|
|
31
|
-
prediction_depth: Depth of sequence predictions
|
|
32
|
-
"""
|
|
33
|
-
self._learning_window = learning_window
|
|
34
|
-
self._prediction_depth = prediction_depth
|
|
35
|
-
self._import_sequences: deque = deque(maxlen=learning_window)
|
|
36
|
-
self._access_times: Dict[str, List[float]] = defaultdict(list)
|
|
37
|
-
self._import_chains: Dict[str, Dict[str, int]] = defaultdict(lambda: defaultdict(int))
|
|
38
|
-
self._module_scores: Dict[str, float] = {}
|
|
39
|
-
self._lock = threading.RLock()
|
|
40
|
-
|
|
41
|
-
def record_import(self, module_name: str, import_time: float) -> None:
|
|
42
|
-
"""Record an import event."""
|
|
43
|
-
current_time = time.time()
|
|
44
|
-
|
|
45
|
-
# Lock-free append to deque (thread-safe for appends)
|
|
46
|
-
self._import_sequences.append((module_name, current_time, import_time))
|
|
47
|
-
|
|
48
|
-
with self._lock:
|
|
49
|
-
self._access_times[module_name].append(current_time)
|
|
50
|
-
|
|
51
|
-
# Update import chains (what imports after what)
|
|
52
|
-
if len(self._import_sequences) > 1:
|
|
53
|
-
prev_name, _, _ = self._import_sequences[-2]
|
|
54
|
-
self._import_chains[prev_name][module_name] += 1
|
|
55
|
-
|
|
56
|
-
# Update module score (frequency * recency) - defer heavy computation
|
|
57
|
-
if len(self._access_times[module_name]) % 5 == 0: # Update every 5th access
|
|
58
|
-
self._update_module_score(module_name)
|
|
59
|
-
|
|
60
|
-
def _update_module_score(self, module_name: str) -> None:
|
|
61
|
-
"""Update module priority score."""
|
|
62
|
-
with self._lock:
|
|
63
|
-
accesses = self._access_times[module_name]
|
|
64
|
-
if not accesses:
|
|
65
|
-
return
|
|
66
|
-
|
|
67
|
-
# Frequency component
|
|
68
|
-
recent_accesses = [t for t in accesses if time.time() - t < 3600] # Last hour
|
|
69
|
-
frequency = len(recent_accesses)
|
|
70
|
-
|
|
71
|
-
# Recency component (more recent = higher score)
|
|
72
|
-
if accesses:
|
|
73
|
-
last_access = accesses[-1]
|
|
74
|
-
recency = 1.0 / (time.time() - last_access + 1.0)
|
|
75
|
-
else:
|
|
76
|
-
recency = 0.0
|
|
77
|
-
|
|
78
|
-
# Chain component (if often imported after another module)
|
|
79
|
-
chain_weight = sum(self._import_chains.get(prev, {}).get(module_name, 0)
|
|
80
|
-
for prev in self._access_times.keys()) / max(len(self._import_sequences), 1)
|
|
81
|
-
|
|
82
|
-
# Combined score
|
|
83
|
-
self._module_scores[module_name] = frequency * 0.4 + recency * 1000 * 0.4 + chain_weight * 0.2
|
|
84
|
-
|
|
85
|
-
def predict_next_imports(self, current_module: Optional[str] = None, limit: int = 5) -> List[str]:
|
|
86
|
-
"""Predict likely next imports based on patterns."""
|
|
87
|
-
# Lock-free check first
|
|
88
|
-
if not self._import_sequences:
|
|
89
|
-
return []
|
|
90
|
-
|
|
91
|
-
with self._lock:
|
|
92
|
-
candidates: Dict[str, float] = {}
|
|
93
|
-
|
|
94
|
-
# Predict based on current module chain (lock-free read of dict)
|
|
95
|
-
if current_module:
|
|
96
|
-
chain_candidates = self._import_chains.get(current_module, {})
|
|
97
|
-
for module, count in chain_candidates.items():
|
|
98
|
-
candidates[module] = candidates.get(module, 0.0) + count * 2.0
|
|
99
|
-
|
|
100
|
-
# Add high-scoring modules (lock-free read of dict)
|
|
101
|
-
for module, score in self._module_scores.items():
|
|
102
|
-
candidates[module] = candidates.get(module, 0.0) + score * 0.5
|
|
103
|
-
|
|
104
|
-
# Sort by score
|
|
105
|
-
sorted_candidates = sorted(candidates.items(), key=lambda x: x[1], reverse=True)
|
|
106
|
-
return [module for module, _ in sorted_candidates[:limit]]
|
|
107
|
-
|
|
108
|
-
def get_priority_modules(self, limit: int = 10) -> List[str]:
|
|
109
|
-
"""Get modules that should be preloaded based on scores."""
|
|
110
|
-
with self._lock:
|
|
111
|
-
sorted_modules = sorted(
|
|
112
|
-
self._module_scores.items(),
|
|
113
|
-
key=lambda x: x[1],
|
|
114
|
-
reverse=True
|
|
115
|
-
)
|
|
116
|
-
return [module for module, _ in sorted_modules[:limit]]
|
|
117
|
-
|
|
118
|
-
def get_stats(self) -> Dict:
|
|
119
|
-
"""Get learning statistics."""
|
|
120
|
-
with self._lock:
|
|
121
|
-
return {
|
|
122
|
-
'sequences_tracked': len(self._import_sequences),
|
|
123
|
-
'unique_modules': len(self._access_times),
|
|
124
|
-
'chains_tracked': sum(len(chains) for chains in self._import_chains.values()),
|
|
125
|
-
'top_modules': self.get_priority_modules(5),
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
__all__ = ['AdaptiveLearner']
|
|
129
|
-
|
exonware/xwlazy/runtime/base.py
DELETED
|
@@ -1,274 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
#exonware/xwlazy/src/exonware/xwlazy/runtime/base.py
|
|
3
|
-
|
|
4
|
-
Company: eXonware.com
|
|
5
|
-
Author: Eng. Muhammad AlShehri
|
|
6
|
-
Email: connect@exonware.com
|
|
7
|
-
|
|
8
|
-
Generation Date: 10-Oct-2025
|
|
9
|
-
|
|
10
|
-
Abstract Base Class for Runtime Services
|
|
11
|
-
|
|
12
|
-
This module defines the abstract base class for runtime services.
|
|
13
|
-
"""
|
|
14
|
-
|
|
15
|
-
import threading
|
|
16
|
-
from abc import ABC, abstractmethod
|
|
17
|
-
from typing import Dict, List, Optional, Any, Tuple
|
|
18
|
-
|
|
19
|
-
from ..contracts import (
|
|
20
|
-
IRuntime,
|
|
21
|
-
)
|
|
22
|
-
|
|
23
|
-
# =============================================================================
|
|
24
|
-
# ABSTRACT RUNTIME (Unified - Merges all runtime services)
|
|
25
|
-
# =============================================================================
|
|
26
|
-
|
|
27
|
-
class ARuntimeHelper(IRuntime, ABC):
|
|
28
|
-
"""
|
|
29
|
-
Unified abstract base for runtime services.
|
|
30
|
-
|
|
31
|
-
Merges functionality from all runtime service interfaces.
|
|
32
|
-
Provides runtime services for state management, learning, monitoring, and caching.
|
|
33
|
-
|
|
34
|
-
This abstract class combines:
|
|
35
|
-
- State management (persistent state for lazy installation)
|
|
36
|
-
- Adaptive learning (learning import patterns and optimizing loading)
|
|
37
|
-
- Intelligent selection (selecting optimal modes based on load characteristics)
|
|
38
|
-
- Metrics collection (collecting and aggregating performance metrics)
|
|
39
|
-
- Performance monitoring (monitoring lazy loading performance)
|
|
40
|
-
- Multi-tier caching (L1/L2/L3 caching)
|
|
41
|
-
- Registry (managing instances by key)
|
|
42
|
-
"""
|
|
43
|
-
|
|
44
|
-
__slots__ = (
|
|
45
|
-
# From IStateManager
|
|
46
|
-
'_manual_state', '_auto_state',
|
|
47
|
-
# From IMetricsCollector
|
|
48
|
-
'_metrics',
|
|
49
|
-
# From IPerformanceMonitor
|
|
50
|
-
'_load_times', '_access_counts',
|
|
51
|
-
# From IMultiTierCache
|
|
52
|
-
'_l1_cache', '_l2_cache', '_l3_cache',
|
|
53
|
-
# From IRegistry
|
|
54
|
-
'_registry',
|
|
55
|
-
# Common
|
|
56
|
-
'_lock'
|
|
57
|
-
)
|
|
58
|
-
|
|
59
|
-
def __init__(self):
|
|
60
|
-
"""Initialize unified runtime services."""
|
|
61
|
-
# From IStateManager
|
|
62
|
-
self._manual_state: Optional[bool] = None
|
|
63
|
-
self._auto_state: Optional[bool] = None
|
|
64
|
-
|
|
65
|
-
# From IMetricsCollector
|
|
66
|
-
self._metrics: Dict[str, List[float]] = {}
|
|
67
|
-
|
|
68
|
-
# From IPerformanceMonitor
|
|
69
|
-
self._load_times: Dict[str, List[float]] = {}
|
|
70
|
-
self._access_counts: Dict[str, int] = {}
|
|
71
|
-
|
|
72
|
-
# From IMultiTierCache
|
|
73
|
-
self._l1_cache: Dict[str, Any] = {}
|
|
74
|
-
self._l2_cache: Dict[str, Any] = {}
|
|
75
|
-
self._l3_cache: Dict[str, Any] = {}
|
|
76
|
-
|
|
77
|
-
# From IRegistry
|
|
78
|
-
self._registry: Dict[str, Any] = {}
|
|
79
|
-
|
|
80
|
-
# Common
|
|
81
|
-
self._lock = threading.RLock()
|
|
82
|
-
|
|
83
|
-
# ========================================================================
|
|
84
|
-
# State Management Methods (from IStateManager)
|
|
85
|
-
# ========================================================================
|
|
86
|
-
|
|
87
|
-
def get_manual_state(self) -> Optional[bool]:
|
|
88
|
-
"""Get manual state override (from IStateManager)."""
|
|
89
|
-
return self._manual_state
|
|
90
|
-
|
|
91
|
-
def set_manual_state(self, value: Optional[bool]) -> None:
|
|
92
|
-
"""Set manual state override (from IStateManager)."""
|
|
93
|
-
with self._lock:
|
|
94
|
-
self._manual_state = value
|
|
95
|
-
|
|
96
|
-
def get_cached_auto_state(self) -> Optional[bool]:
|
|
97
|
-
"""Get cached auto-detected state (from IStateManager)."""
|
|
98
|
-
return self._auto_state
|
|
99
|
-
|
|
100
|
-
def set_auto_state(self, value: Optional[bool]) -> None:
|
|
101
|
-
"""Set cached auto-detected state (from IStateManager)."""
|
|
102
|
-
with self._lock:
|
|
103
|
-
self._auto_state = value
|
|
104
|
-
|
|
105
|
-
# ========================================================================
|
|
106
|
-
# Adaptive Learning Methods (from IAdaptiveLearner)
|
|
107
|
-
# ========================================================================
|
|
108
|
-
|
|
109
|
-
@abstractmethod
|
|
110
|
-
def record_import(self, module_name: str, import_time: float) -> None:
|
|
111
|
-
"""Record an import event (from IAdaptiveLearner)."""
|
|
112
|
-
pass
|
|
113
|
-
|
|
114
|
-
@abstractmethod
|
|
115
|
-
def predict_next_imports(self, current_module: str, count: int = 3) -> List[str]:
|
|
116
|
-
"""Predict next likely imports based on patterns (from IAdaptiveLearner)."""
|
|
117
|
-
pass
|
|
118
|
-
|
|
119
|
-
@abstractmethod
|
|
120
|
-
def get_module_score(self, module_name: str) -> float:
|
|
121
|
-
"""Get priority score for a module (from IAdaptiveLearner)."""
|
|
122
|
-
pass
|
|
123
|
-
|
|
124
|
-
# ========================================================================
|
|
125
|
-
# Intelligent Selection Methods (from IIntelligentSelector)
|
|
126
|
-
# ========================================================================
|
|
127
|
-
|
|
128
|
-
@abstractmethod
|
|
129
|
-
def detect_load_level(
|
|
130
|
-
self,
|
|
131
|
-
module_count: int = 0,
|
|
132
|
-
total_import_time: float = 0.0,
|
|
133
|
-
import_count: int = 0,
|
|
134
|
-
memory_usage_mb: float = 0.0
|
|
135
|
-
) -> Any:
|
|
136
|
-
"""Detect current load level (from IIntelligentSelector)."""
|
|
137
|
-
pass
|
|
138
|
-
|
|
139
|
-
@abstractmethod
|
|
140
|
-
def get_optimal_mode(self, load_level: Any) -> Tuple[Any, Any]:
|
|
141
|
-
"""Get optimal mode for a load level (from IIntelligentSelector)."""
|
|
142
|
-
pass
|
|
143
|
-
|
|
144
|
-
@abstractmethod
|
|
145
|
-
def update_mode_map(self, mode_map: Dict[Any, Tuple[Any, Any]]) -> None:
|
|
146
|
-
"""Update mode mapping with benchmark results (from IIntelligentSelector)."""
|
|
147
|
-
pass
|
|
148
|
-
|
|
149
|
-
# ========================================================================
|
|
150
|
-
# Metrics Collection Methods (from IMetricsCollector)
|
|
151
|
-
# ========================================================================
|
|
152
|
-
|
|
153
|
-
def record_metric(self, name: str, value: float, timestamp: Optional[Any] = None) -> None:
|
|
154
|
-
"""Record a metric value (from IMetricsCollector)."""
|
|
155
|
-
with self._lock:
|
|
156
|
-
if name not in self._metrics:
|
|
157
|
-
self._metrics[name] = []
|
|
158
|
-
self._metrics[name].append(value)
|
|
159
|
-
|
|
160
|
-
@abstractmethod
|
|
161
|
-
def get_metric_stats(self, name: str) -> Dict[str, Any]:
|
|
162
|
-
"""Get statistics for a metric (from IMetricsCollector)."""
|
|
163
|
-
pass
|
|
164
|
-
|
|
165
|
-
@abstractmethod
|
|
166
|
-
def get_all_stats(self) -> Dict[str, Dict[str, Any]]:
|
|
167
|
-
"""Get statistics for all metrics (from IMetricsCollector)."""
|
|
168
|
-
pass
|
|
169
|
-
|
|
170
|
-
def clear_metrics(self) -> None:
|
|
171
|
-
"""Clear all collected metrics (from IMetricsCollector)."""
|
|
172
|
-
with self._lock:
|
|
173
|
-
self._metrics.clear()
|
|
174
|
-
|
|
175
|
-
# ========================================================================
|
|
176
|
-
# Performance Monitoring Methods (from IPerformanceMonitor)
|
|
177
|
-
# ========================================================================
|
|
178
|
-
|
|
179
|
-
def record_load_time(self, module: str, load_time: float) -> None:
|
|
180
|
-
"""Record module load time (from IPerformanceMonitor)."""
|
|
181
|
-
with self._lock:
|
|
182
|
-
if module not in self._load_times:
|
|
183
|
-
self._load_times[module] = []
|
|
184
|
-
self._load_times[module].append(load_time)
|
|
185
|
-
|
|
186
|
-
def record_access(self, module: str) -> None:
|
|
187
|
-
"""Record module access (from IPerformanceMonitor)."""
|
|
188
|
-
with self._lock:
|
|
189
|
-
self._access_counts[module] = self._access_counts.get(module, 0) + 1
|
|
190
|
-
|
|
191
|
-
@abstractmethod
|
|
192
|
-
def get_performance_stats(self) -> Dict[str, Any]:
|
|
193
|
-
"""Get performance statistics (from IPerformanceMonitor)."""
|
|
194
|
-
pass
|
|
195
|
-
|
|
196
|
-
# ========================================================================
|
|
197
|
-
# Multi-Tier Cache Methods (from IMultiTierCache)
|
|
198
|
-
# ========================================================================
|
|
199
|
-
|
|
200
|
-
def get_multi_tier_cached(self, key: str) -> Optional[Any]:
|
|
201
|
-
"""Get value from cache (L1 -> L2 -> L3) (from IMultiTierCache)."""
|
|
202
|
-
with self._lock:
|
|
203
|
-
# Check L1 first
|
|
204
|
-
if key in self._l1_cache:
|
|
205
|
-
return self._l1_cache[key]
|
|
206
|
-
# Check L2
|
|
207
|
-
if key in self._l2_cache:
|
|
208
|
-
value = self._l2_cache[key]
|
|
209
|
-
# Promote to L1
|
|
210
|
-
self._l1_cache[key] = value
|
|
211
|
-
return value
|
|
212
|
-
# Check L3
|
|
213
|
-
if key in self._l3_cache:
|
|
214
|
-
value = self._l3_cache[key]
|
|
215
|
-
# Promote to L2
|
|
216
|
-
self._l2_cache[key] = value
|
|
217
|
-
return value
|
|
218
|
-
return None
|
|
219
|
-
|
|
220
|
-
def set_multi_tier_cached(self, key: str, value: Any) -> None:
|
|
221
|
-
"""Set value in cache (L1 and L2) (from IMultiTierCache)."""
|
|
222
|
-
with self._lock:
|
|
223
|
-
self._l1_cache[key] = value
|
|
224
|
-
self._l2_cache[key] = value
|
|
225
|
-
|
|
226
|
-
def clear_multi_tier_cache(self) -> None:
|
|
227
|
-
"""Clear all cache tiers (from IMultiTierCache)."""
|
|
228
|
-
with self._lock:
|
|
229
|
-
self._l1_cache.clear()
|
|
230
|
-
self._l2_cache.clear()
|
|
231
|
-
self._l3_cache.clear()
|
|
232
|
-
|
|
233
|
-
@abstractmethod
|
|
234
|
-
def shutdown_multi_tier_cache(self) -> None:
|
|
235
|
-
"""Shutdown cache (flush L2, cleanup threads) (from IMultiTierCache)."""
|
|
236
|
-
pass
|
|
237
|
-
|
|
238
|
-
# Alias method for backward compatibility
|
|
239
|
-
def shutdown_cache(self) -> None:
|
|
240
|
-
"""Alias for shutdown_multi_tier_cache (backward compatibility)."""
|
|
241
|
-
self.shutdown_multi_tier_cache()
|
|
242
|
-
|
|
243
|
-
# ========================================================================
|
|
244
|
-
# Registry Methods (from IRegistry)
|
|
245
|
-
# ========================================================================
|
|
246
|
-
|
|
247
|
-
def get_instance(self, key: str) -> Any:
|
|
248
|
-
"""Get instance by key (from IRegistry)."""
|
|
249
|
-
with self._lock:
|
|
250
|
-
return self._registry.get(key)
|
|
251
|
-
|
|
252
|
-
def register(self, key: str, instance: Any) -> None:
|
|
253
|
-
"""Register an instance (from IRegistry)."""
|
|
254
|
-
with self._lock:
|
|
255
|
-
self._registry[key] = instance
|
|
256
|
-
|
|
257
|
-
def unregister(self, key: str) -> None:
|
|
258
|
-
"""Unregister an instance (from IRegistry)."""
|
|
259
|
-
with self._lock:
|
|
260
|
-
self._registry.pop(key, None)
|
|
261
|
-
|
|
262
|
-
def has_key(self, key: str) -> bool:
|
|
263
|
-
"""Check if key is registered (from IRegistry)."""
|
|
264
|
-
with self._lock:
|
|
265
|
-
return key in self._registry
|
|
266
|
-
|
|
267
|
-
# =============================================================================
|
|
268
|
-
# EXPORT ALL
|
|
269
|
-
# =============================================================================
|
|
270
|
-
|
|
271
|
-
__all__ = [
|
|
272
|
-
'ARuntimeHelper',
|
|
273
|
-
]
|
|
274
|
-
|