Fix bug with throttling and add some debug

This commit is contained in:
Richard Frith-Macdonald 2020-10-14 15:48:55 +01:00
parent 020b2cef7e
commit 3bd03637ff

View file

@ -109,9 +109,11 @@ static unsigned throttleAt = 12;
} }
@end @end
#define MINUTES 60
@interface EcAlertThrottle : NSObject @interface EcAlertThrottle : NSObject
{ {
uint32_t counts[60]; uint32_t mins[MINUTES];
uint64_t base; uint64_t base;
BOOL throttled; BOOL throttled;
} }
@ -128,12 +130,16 @@ static unsigned throttleAt = 12;
- (NSString*) description - (NSString*) description
{ {
char buf[BUFSIZ]; char buf[BUFSIZ];
unsigned slot; unsigned minute;
unsigned i; unsigned i;
slot = (((uint64_t)[NSDate timeIntervalSinceReferenceDate]) - base) / 60; minute = (((uint64_t)[NSDate timeIntervalSinceReferenceDate]) - base) / 60;
if (minute >= MINUTES)
{
minute = MINUTES-1;
}
buf[0] = '\0'; buf[0] = '\0';
for (i = 0; i <= slot; i++) for (i = 0; i <= minute; i++)
{ {
if (i > 0) if (i > 0)
{ {
@ -146,7 +152,7 @@ static unsigned throttleAt = 12;
strcat(buf, ", "); strcat(buf, ", ");
} }
} }
sprintf(buf + strlen(buf), "%u", (unsigned)counts[i]); sprintf(buf + strlen(buf), "%u", (unsigned)mins[i]);
} }
return [[super description] stringByAppendingFormat: return [[super description] stringByAppendingFormat:
@"Base: %@, Throttled: %@, Counts:\n%s\n", @"Base: %@, Throttled: %@, Counts:\n%s\n",
@ -158,7 +164,7 @@ static unsigned throttleAt = 12;
{ {
uint64_t now = (uint64_t)[NSDate timeIntervalSinceReferenceDate]; uint64_t now = (uint64_t)[NSDate timeIntervalSinceReferenceDate];
uint32_t sum = 0; uint32_t sum = 0;
uint32_t slot; uint32_t minute;
uint32_t index; uint32_t index;
BOOL wasThrottled; BOOL wasThrottled;
@ -167,57 +173,57 @@ static unsigned throttleAt = 12;
base = now; // Starting throttling period. base = now; // Starting throttling period.
} }
/* The number of minutes sinse the base time gives us the slot /* The number of minutes since the base time gives us the minute
* into which we should be recording the new event. * into which we should be recording the new event.
*/ */
slot = (now - base) / 60; minute = (now - base) / 60;
if (slot >= 120) if (minute >= 2*MINUTES)
{ {
/* As it's at least an hour since the last event, we can simply /* As it's at least an hour since the last event, we can simply
* start a new recording period. * start a new recording period.
*/ */
base = now; base = now;
memset(counts, '\0', 60 * sizeof(*counts)); memset(mins, '\0', MINUTES * sizeof(*mins));
slot = 0; minute = 0;
} }
else if (slot > 59) else if (minute > (MINUTES-1))
{ {
int move = slot - 59; int move = minute - (MINUTES-1);
/* The recording period started over an hour ago, so we must adjust /* The recording period started over an hour ago, so we must adjust
* it forward so that the current time is in its 59th minute. * it forward so that the current time is in its 59th minute.
*/ */
memmove(counts, counts + (60 - move), move * sizeof(*counts)); memmove(mins, mins + move, (MINUTES - move) * sizeof(*mins));
memset(counts + move, '\0', (60 - move) * sizeof(*counts)); memset(mins + (MINUTES - move), '\0', move * sizeof(*mins));
base += move * 60; base += move * 60;
slot = 59; minute = (MINUTES-1);
} }
for (index = 0; index <= slot; index++) for (index = 0; index <= minute; index++)
{ {
sum += counts[index]; sum += mins[index];
} }
if (NO == (wasThrottled = throttled)) if (NO == (wasThrottled = throttled))
{ {
counts[slot]++; mins[minute]++;
sum++; sum++;
} }
if (sum >= throttleAt) if (sum >= throttleAt)
{ {
throttled = YES; throttled = YES;
/* The time at which unthrottling occurs is an hour after the /* The time at which unthrottling occurs is MINUTES after the
* first alert in the current recording period. * first alert in the current recording period.
*/ */
for (index = 0; index <= slot; index++) for (index = 0; index <= minute; index++)
{ {
if (counts[index] > 0) if (mins[index] > 0)
{ {
break; break;
} }
} }
*until = [NSDate dateWithTimeIntervalSinceReferenceDate: *until = [NSDate dateWithTimeIntervalSinceReferenceDate:
(NSTimeInterval)(base + 60*(index+1) + 3600)]; (NSTimeInterval)(base + 60*(index+1) + 60*MINUTES)];
} }
else else
{ {
@ -1306,6 +1312,8 @@ replaceFields(NSDictionary *fields, NSString *template)
{ {
EcAlertThrottle *t; EcAlertThrottle *t;
NSDate *until; NSDate *until;
BOOL throttled;
NSString *before = nil;
s = [s description]; s = [s description];
if (YES == event->isAlarm && NO == quiet) if (YES == event->isAlarm && NO == quiet)
@ -1322,7 +1330,17 @@ replaceFields(NSDictionary *fields, NSString *template)
[other setObject: t forKey: s]; [other setObject: t forKey: s];
RELEASE(t); RELEASE(t);
} }
if ([t shouldThrottle: &until]) if (debug)
{
before = [t description];
}
throttled = [t shouldThrottle: &until];
if (debug)
{
NSLog(@"Other destination: %@\nBefore %@\nAfter %@",
s, before, [t description]);
}
if (throttled)
{ {
failOther++; failOther++;
} }