1+ """
2+ definition of the class representing the rqs generator
3+ that will be passed as a process in the simpy simulation
4+ """
5+
6+ from __future__ import annotations
7+
8+ from typing import Generator , TYPE_CHECKING
9+
10+ import simpy
11+
12+ from app .config .constants import Distribution
13+ from app .config .rqs_state import RequestState
14+ from app .core .event_samplers .gaussian_poisson import gaussian_poisson_sampling
15+ from app .core .event_samplers .poisson_poisson import poisson_poisson_sampling
16+
17+ if TYPE_CHECKING :
18+ from collections .abc import Generator
19+
20+ import numpy as np
21+
22+ from app .schemas .requests_generator_input import RqsGeneratorInput
23+ from app .schemas .simulation_settings_input import SimulationSettings
24+
25+
26+ class RqsGeneratorRuntime ():
27+ """
28+ A “node” that produces request contexts at stochastic inter‐arrival times
29+ and immediately pushes them down the pipeline via an EdgeRuntime.
30+ """
31+ def __init__ (
32+ self ,
33+ env : simpy .Environment ,
34+ state : RequestState ,
35+ rqs_generator_data : RqsGeneratorInput ,
36+ sim_settings : SimulationSettings ,
37+ * ,
38+ rng : np .random .Generator | None = None
39+ ):
40+
41+ self .rqs_generator_data = rqs_generator_data
42+ self .sim_settings = sim_settings
43+ self .rng = rng or np .random .default_rng ()
44+ self .state = state
45+ self .env = env
46+
47+
48+ def _requests_generator (self ) -> Generator [float , None , None ]:
49+ """
50+ Return an iterator of inter-arrival gaps (seconds) according to the model
51+ chosen in *input_data*.
52+
53+ Notes
54+ -----
55+ * If ``avg_active_users.distribution`` is ``"gaussian"`` or ``"normal"``,
56+ the Gaussian-Poisson sampler is used.
57+ * Otherwise the default Poisson-Poisson sampler is returned.
58+
59+ """
60+ dist = self .rqs_generator_data .avg_active_users .distribution .lower ()
61+
62+ if dist == Distribution .NORMAL :
63+ #Gaussian-Poisson model
64+ return gaussian_poisson_sampling (
65+ input_data = self .rqs_generator_data ,
66+ sim_settings = self .sim_settings ,
67+ rng = self .rng ,
68+
69+ )
70+
71+ # Poisson + Poisson
72+ return poisson_poisson_sampling (
73+ input_data = self .rqs_generator_data ,
74+ sim_settings = self .sim_settings ,
75+ rng = self .rng ,
76+ )
77+
78+ def _event_arrival (self ) -> Generator [simpy .Event , None , None ]:
79+ """simulating the process of event generation"""
80+ time_gaps = self ._requests_generator ()
81+
82+ for gap in time_gaps :
83+ yield self .env .timeout (gap )
84+
85+ def run (self ) -> simpy .Process :
86+ """passing the structure as a simpy process"""
87+ return self .env .process (self ._event_arrival ())
0 commit comments