# Projet : Runtime de Signaux/Slots Haute Performance en Rust ## Objectif Créer un runtime événementiel inspiré de Qt Signals/Slots mais pensé pour : - haute fréquence, - multi-thread, - audio temps réel, - architecture modulaire, - runtime distribué par workers, - typage fort compile-time, - signaux async/sync, - performance extrême. Le runtime doit pouvoir servir de base à : - moteur événementiel, - runtime applicatif, - scheduler coopératif, - actor system, - infrastructure temps réel. IMPORTANT : Le runtime doit rester générique et indépendant du réseau. Aucune logique UDP/TCP/socket ne doit être implémentée automatiquement. L’intégration réseau sera réalisée manuellement plus tard par le développeur. --- # Vision Architecture ```text Application ↓ Signal Runtime ├── Worker 0 │ ├── Event Loop │ ├── Audio Systems │ ├── Metrics │ └── Channels │ ├── Worker 1 │ ├── Auth │ ├── Sessions │ └── Runtime Tasks │ └── Worker N PHASE 1 — Runtime Minimal Objectif Créer : runtime global, workers, queues, event loop, dispatch d’événements. A implémenter Runtime struct Runtime { workers: Vec, } Worker struct Worker { id: usize, sender: Sender, } Event Loop Boucle infinie : loop { let event = rx.recv().unwrap(); event.execute(); } Event Trait trait ExecutableEvent { fn execute(self: Box); } PHASE 2 — Système de Signaux Objectif Créer : Signal, connect(), emit(), subscribers, callbacks dynamiques. A implémenter Signal générique struct Signal { subscribers: Vec>, } Subscriber Contient : callback, target_worker, connection_type. Connection Types enum ConnectionType { Direct, Queued, } Emit Le signal : ne doit jamais exécuter directement un callback queued, doit créer un Event, envoyer vers le worker cible. PHASE 3 — Runtime Global Objectif Créer : runtime singleton, accès global, routing automatique. A implémenter OnceLock static RUNTIME: OnceLock; Dispatch global runtime.dispatch(worker_id, event); Routing intelligent Le runtime doit : choisir le bon worker, envoyer dans la bonne queue, éviter les locks globaux. PHASE 4 — Proc Macros Objectif Créer : #[derive(Signals)], auto-enregistrement, génération automatique de metadata. Crate séparée signals_derive/ Technologies syn quote proc_macro2 Features Détection automatique Détecter : Signal dans une struct. Génération Générer : impl AudioEngine { pub fn register_signals(...) } Support futur Prévoir : #[signal] metadata runtime, introspection légère. PHASE 5 — Thread Affinity Objectif Chaque objet appartient à un worker. A implémenter RuntimeObject struct RuntimeObject { worker_id: usize, } Règles les signaux queued doivent s’exécuter sur le worker cible, éviter les accès cross-thread directs. PHASE 6 — Weak References Objectif Reproduire l’auto-cleanup de Qt. A implémenter Utiliser : Arc Weak Comportement Si le receiver est détruit : la connexion devient invalide, le runtime l’ignore automatiquement. PHASE 7 — Event Bus Typé Objectif Permettre : runtime.emit(EventType) runtime.subscribe::() Contraintes typage compile-time, pas de string routing obligatoire, support Any/TypeId. PHASE 8 — Optimisation Performance Objectif Préparer haute fréquence. Optimisations attendues Eviter Mutex globaux, allocations fréquentes, Box inutiles, contention CPU. Ajouter queues lock-free, batching, event pooling, cache locality, sharding runtime. PHASE 9 — Runtime Sharding Objectif Eviter le bottleneck central. Architecture Shard 0 Shard 1 Shard 2 Chaque shard : possède ses subscribers, possède ses queues, possède ses workers. PHASE 10 — Intégration Applicative Générique Objectif Permettre à des systèmes externes de pousser des événements dans le runtime. IMPORTANT : Le runtime ne doit contenir aucune logique réseau native. Il doit uniquement exposer des APIs génériques permettant : d’émettre des événements, de s’abonner à des événements, de router les tâches. Les couches réseau, audio, fichiers, protocoles ou IO seront branchées manuellement par le développeur. Exemple attendu runtime.emit(MyCustomEvent { ... }); PHASE 11 — Scheduler Coopératif Objectif Fusionner : signaux, scheduler, tâches coopératives. Inspiré de Go runtime, Tokio, Erlang. Features spawn() spawn(async move {}) sleep() wakeup() channels() PHASE 12 — Async Runtime Integration Objectif Compatibilité : Tokio, async/await, futures. Support Async subscribers signal.connect(async move |event| { ... }); PHASE 13 — Monitoring & Introspection Objectif Observer : workers, queues, charge CPU, nombre d’événements, latence. Metrics events/sec, queue depth, dropped events, worker usage. PHASE 14 — API Finale Objectif API élégante type Qt. Exemple cible #[derive(Signals)] struct AudioEngine { packet_received: Signal, } audio.packet_received.connect(&decoder, |d, p| { d.decode(p); }); audio.packet_received.emit(packet); Contraintes Techniques Langage Rust stable uniquement au début. Dépendances possibles crossbeam flume parking_lot dashmap (optionnel) tokio (plus tard) Eviter au début async partout, macros trop complexes, ECS complet, reflection lourde. Objectif Long Terme Créer un runtime capable de : gérer des centaines de milliers/millions d’événements, servir de cœur à des applications temps réel, fournir un scheduler coopératif, remplacer une architecture classique callbacks/mutex.