2424
2525final class EventLoopBridge
2626{
27+ private const DEFAULT_SCALE_RANGE = [
28+ 0.1 ,
29+ 0.01 ,
30+ 0.001 ,
31+ ];
32+
33+ private const DEFAULT_SCALE_POSITION = 2 ;
34+
2735 private LoopInterface $ loop ;
2836
2937 private ?Metrics $ metrics = null ;
@@ -41,6 +49,11 @@ final class EventLoopBridge
4149
4250 private bool $ timerActive = FALSE_ ;
4351
52+ /** @var array<float> */
53+ private array $ scaleRange = self ::DEFAULT_SCALE_RANGE ;
54+ private int $ scalePosition = self ::DEFAULT_SCALE_POSITION ;
55+ private int $ scaleNoItemsCount = 0 ;
56+
4457 public function __construct (LoopInterface $ loop )
4558 {
4659 $ this ->loop = $ loop ;
@@ -96,8 +109,30 @@ private function startTimer(): void
96109 $ this ->metrics ->timer ()->counter (new Label ('event ' , 'start ' ))->incr ();
97110 }
98111
99- // Call 1K times per second
100- $ this ->timer = $ this ->loop ->addPeriodicTimer (0.001 , function (): void {
112+ $ this ->runTimer ();
113+
114+ $ this ->timerActive = TRUE_ ;
115+ }
116+
117+ private function stopTimer (): void
118+ {
119+ if (count ($ this ->channels ) !== ZERO || count ($ this ->futures ) !== ZERO ) {
120+ return ;
121+ }
122+
123+ $ this ->loop ->cancelTimer ($ this ->timer );
124+ $ this ->timerActive = FALSE_ ;
125+
126+ if (! ($ this ->metrics instanceof Metrics)) {
127+ return ;
128+ }
129+
130+ $ this ->metrics ->timer ()->counter (new Label ('event ' , 'stop ' ))->incr ();
131+ }
132+
133+ private function runTimer (): void
134+ {
135+ $ this ->timer = $ this ->loop ->addPeriodicTimer ($ this ->scaleRange [$ this ->scalePosition ], function (): void {
101136 $ items = 0 ;
102137
103138 try {
@@ -131,30 +166,37 @@ private function startTimer(): void
131166
132167 $ this ->stopTimer ();
133168
169+ /** @phpstan-ignore-next-line */
170+ if ($ items > 0 && isset ($ this ->scaleRange [$ this ->scalePosition + 1 ])) {
171+ $ this ->loop ->cancelTimer ($ this ->timer );
172+
173+ $ this ->scalePosition ++;
174+ $ this ->runTimer ();
175+
176+ $ this ->scaleNoItemsCount = 0 ;
177+ }
178+
179+ if ($ items === 0 ) {
180+ $ this ->scaleNoItemsCount ++;
181+
182+ /** @phpstan-ignore-next-line */
183+ if ($ this ->scaleNoItemsCount > 10 && isset ($ this ->scaleRange [$ this ->scalePosition - 1 ])) {
184+ $ this ->loop ->cancelTimer ($ this ->timer );
185+
186+ $ this ->scalePosition --;
187+ $ this ->runTimer ();
188+
189+ $ this ->scaleNoItemsCount = 0 ;
190+ }
191+ }
192+
134193 if (! ($ this ->metrics instanceof Metrics)) {
135194 return ;
136195 }
137196
138197 $ this ->metrics ->timer ()->counter (new Label ('event ' , 'tick ' ))->incr ();
139198 $ this ->metrics ->timerItems ()->counter (new Label ('count ' , (string ) $ items ))->incr ();
140199 });
141- $ this ->timerActive = TRUE_ ;
142- }
143-
144- private function stopTimer (): void
145- {
146- if (count ($ this ->channels ) !== ZERO || count ($ this ->futures ) !== ZERO ) {
147- return ;
148- }
149-
150- $ this ->loop ->cancelTimer ($ this ->timer );
151- $ this ->timerActive = FALSE_ ;
152-
153- if (! ($ this ->metrics instanceof Metrics)) {
154- return ;
155- }
156-
157- $ this ->metrics ->timer ()->counter (new Label ('event ' , 'stop ' ))->incr ();
158200 }
159201
160202 private function handleReadEvent (Events \Event $ event ): void
0 commit comments