@@ -67,7 +67,8 @@ private function handleError(Exception $e, Repository $repo, bool $update): stri
6767 $ this ->logger ->error ($ shortMessage );
6868 $ this ->logger ->debug ($ e ->getTraceAsString ());
6969 if ($ template !== '' ) {
70- if ($ repo ->isFunctional ()) {
70+ $ isNormal = true ;
71+ if ($ repo ->isFunctional () && $ isNormal = $ this ->isNormalErrorRate ($ repo )) {
7172 $ repo ->getEntity ()->setErrorCount ($ repo ->getEntity ()->getErrorCount () + 1 );
7273
7374 $ this ->emailService ->sendEmail (
@@ -79,7 +80,10 @@ private function handleError(Exception $e, Repository $repo, bool $update): stri
7980 $ errorMsg = $ shortMessage . "\n" . $ this ->emailService ->getLastMessage ();
8081 } else {
8182 //no mailing or storing of error needed
82- $ this ->logger ->debug ('No error mail sent, GitHub or GitLab is not functional ( ' . get_class ($ e ) . ') ' );
83+ $ message = $ isNormal ?
84+ 'No error mail sent, GitHub or GitLab is not functional '
85+ : 'No error mail sent, too high error rate (more than 5 per 8 min) ' ;
86+ $ this ->logger ->debug ($ message . ' ( ' . get_class ($ e ) . ') ' );
8387 return $ shortMessage ;
8488 }
8589
@@ -190,4 +194,58 @@ private function determineEmailTemplateUpdate(Exception $e): string
190194 }
191195 return '' ;
192196 }
197+
198+ /**
199+ * If error rate is too high (>counts within certain delta time) it returns false.
200+ * It extends it upto the point that no other error occur in the delta time.
201+ *
202+ * @param Repository $repo
203+ * @return bool
204+ */
205+ private function isNormalErrorRate (Repository $ repo ): bool
206+ {
207+ $ maxErrorCount = 5 ; //tool tries max 10 per run
208+ $ maxDeltaTime = 8 * 60 ; //tool tries every 5 min new run
209+
210+ //reset if too long ago
211+ [$ count , $ startTime ] = $ this ->getCounterData ($ repo );
212+ if (time () - $ startTime > $ maxDeltaTime ) {
213+ $ count = 0 ;
214+ }
215+
216+ //count is zero resets time as well
217+ if ($ count === 0 ) {
218+ $ startTime = time ();
219+ }
220+
221+ $ count ++;
222+
223+ $ isNormal = true ;
224+ // if too many in given delta time
225+ if ($ count > $ maxErrorCount ) {
226+ // if rate is too high, reset time to extend period
227+ // (occurs up to the point that the delta time becomes too large.)
228+ $ startTime = time ();
229+
230+ $ isNormal = false ;
231+ }
232+ $ this ->storeCounterData ($ repo , $ count , $ startTime );
233+ return $ isNormal ;
234+ }
235+
236+ private function getCounterData (Repository $ repo ): array
237+ {
238+ $ file = $ repo ->buildDataDirectoryPath () . 'errorcountertime ' ;
239+ if (file_exists ($ file )) {
240+ $ data = array_pad (explode ('# ' , file_get_contents ($ file )), 2 , 0 );
241+ return [(int )$ data [0 ], (int )$ data [1 ]];
242+ } else {
243+ return [0 , 0 ];
244+ }
245+ }
246+
247+ private function storeCounterData (Repository $ repo , $ count , $ startTime ): void
248+ {
249+ file_put_contents ($ repo ->buildDataDirectoryPath () . 'errorcountertime ' , $ count . '# ' . $ startTime );
250+ }
193251}
0 commit comments