File size: 4,294 Bytes
24480a0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
"""
backend/api/extended_benchmark.py — Benchmark multi-scenario per l'intero sistema.
"""
import asyncio
import time
import random
from .execution_fabric import ExecutionFabric, DispatchRequest, ProviderKind, ProviderSpec, AlwaysOn, ProviderHealth
from .token_rotator import rotator

class ExtendedBenchmark:
    def __init__(self):
        self.fabric = ExecutionFabric()
        self.results = {}

    async def setup(self):
        # Configurazione flotta completa
        for i, char in enumerate(['A', 'B', 'C', 'D']):
            self.fabric._specs[f"sb-{char.lower()}"] = ProviderSpec(
                provider_id=f"sb-{char.lower()}", name=f"Supabase {char}", kind=ProviderKind.LOCAL,
                capabilities=["memory", "auth"], always_on=AlwaysOn.YES
            )
            self.fabric._states[f"sb-{char.lower()}"] = type('State', (), {"health": ProviderHealth.OK})()
        
        self.fabric._specs["oracle-core"] = ProviderSpec(
            provider_id="oracle-core", name="Oracle Core", kind=ProviderKind.ORACLE,
            capabilities=["compute", "sandbox"], always_on=AlwaysOn.YES, timeout=60.0
        )
        self.fabric._states["oracle-core"] = type('State', (), {"health": ProviderHealth.OK})()

        self.fabric._specs["railway-core"] = ProviderSpec(
            provider_id="railway-core", name="Railway Space E", kind=ProviderKind.RAILWAY,
            capabilities=["compute", "sandbox"], always_on=AlwaysOn.YES
        )
        self.fabric._states["railway-core"] = type('State', (), {"health": ProviderHealth.OK})()
        
        self.fabric._initialized = True

    async def scenario_normal_load(self):
        """Scenario 1: Carico normale, tutto funzionante."""
        async def mock_ok(spec, req): return {"status": "ok", "latency": random.uniform(50, 200)}
        self.fabric._call_provider = mock_ok
        
        t0 = time.time()
        tasks = [self.fabric.dispatch(DispatchRequest(capability="memory")) for _ in range(10)]
        results = await asyncio.gather(*tasks)
        duration = (time.time() - t0) * 1000
        self.results["normal_load"] = {"avg_latency": duration/10, "success_rate": 100.0}

    async def scenario_cascading_failure(self):
        """Scenario 2: Fallimento a catena Supabase A -> B -> C -> D."""
        failed_providers = set()
        async def mock_cascade(spec, req):
            if spec.provider_id in ["sb-a", "sb-b", "sb-c"]:
                failed_providers.add(spec.provider_id)
                return {"status_code": 429}
            return {"status": "ok", "provider": spec.name}
        
        self.fabric._call_provider = mock_cascade
        t0 = time.time()
        result = await self.fabric.dispatch(DispatchRequest(capability="memory"))
        duration = (time.time() - t0) * 1000
        self.results["cascading_failure"] = {
            "duration": duration,
            "final_provider": result.provider_name,
            "rotations": len(failed_providers)
        }

    async def scenario_oracle_stress(self):
        """Scenario 3: Oracle saturo, fallback immediato su Railway."""
        async def mock_oracle_down(spec, req):
            if spec.kind == ProviderKind.ORACLE:
                await asyncio.sleep(0.5) # Simula attesa timeout
                raise Exception("Oracle Overloaded")
            return {"status": "ok", "from": "railway"}
        
        self.fabric._call_provider = mock_oracle_down
        t0 = time.time()
        result = await self.fabric.dispatch(DispatchRequest(capability="compute", provider_hint="oracle-core"))
        duration = (time.time() - t0) * 1000
        self.results["oracle_fallback"] = {"duration": duration, "provider": result.provider_name}

    async def run_all(self):
        print("🚀 Avvio Benchmark Multi-Scenario...")
        await self.setup()
        await self.scenario_normal_load()
        await self.scenario_cascading_failure()
        await self.scenario_oracle_stress()
        
        print("\n--- REPORT FINALE ---")
        for name, data in self.results.items():
            print(f"[{name.upper()}]")
            for k, v in data.items():
                print(f"  - {k}: {v}")
        print("----------------------")

if __name__ == "__main__":
    asyncio.run(ExtendedBenchmark().run_all())