24
24
25
25
final class EventLoopBridge
26
26
{
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
+
27
35
private LoopInterface $ loop ;
28
36
29
37
private ?Metrics $ metrics = null ;
@@ -41,6 +49,11 @@ final class EventLoopBridge
41
49
42
50
private bool $ timerActive = FALSE_ ;
43
51
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
+
44
57
public function __construct (LoopInterface $ loop )
45
58
{
46
59
$ this ->loop = $ loop ;
@@ -96,8 +109,30 @@ private function startTimer(): void
96
109
$ this ->metrics ->timer ()->counter (new Label ('event ' , 'start ' ))->incr ();
97
110
}
98
111
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 {
101
136
$ items = 0 ;
102
137
103
138
try {
@@ -131,30 +166,37 @@ private function startTimer(): void
131
166
132
167
$ this ->stopTimer ();
133
168
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
+
134
193
if (! ($ this ->metrics instanceof Metrics)) {
135
194
return ;
136
195
}
137
196
138
197
$ this ->metrics ->timer ()->counter (new Label ('event ' , 'tick ' ))->incr ();
139
198
$ this ->metrics ->timerItems ()->counter (new Label ('count ' , (string ) $ items ))->incr ();
140
199
});
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 ();
158
200
}
159
201
160
202
private function handleReadEvent (Events \Event $ event ): void
0 commit comments