perf(host_agent): the sensor judgment reads the week once, then only new hours (#5786)
On the live instance the hourly refresh took 3 min 8 s, averaging a week of raw temp_c samples each time. The hourly averages are now kept in memory. The first refresh after startup reads the whole window. Each later one reads raw samples from the start of the hour the last read ended in, so the hour that was still filling is read again whole. merge_hours folds the new rows in and drops hours older than the window. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -208,6 +208,16 @@ def test_sensors_are_judged_from_raw_hours_and_rollups_together(app):
|
||||
metric_name="temp_c", value=f(99), recorded_at=now))
|
||||
return await sensors.refresh(s, now)
|
||||
|
||||
sensors._hours.clear()
|
||||
sensors._read_from = None
|
||||
got = asyncio.run(_go())
|
||||
assert list(got[host]) == ["SYSTIN"]
|
||||
assert got[host]["SYSTIN"].startswith("falls as the CPU warms (r -1.00 over 100 h")
|
||||
|
||||
async def _again(): # the next hour reads only the hour it ended in
|
||||
async with app.db_sessionmaker() as s:
|
||||
return await sensors.refresh(s, now + timedelta(hours=1))
|
||||
|
||||
assert sensors._read_from == now.replace(minute=0)
|
||||
again = asyncio.run(_again())
|
||||
assert again[host]["SYSTIN"].startswith("falls as the CPU warms (r -1.00 over 100 h")
|
||||
|
||||
@@ -72,3 +72,13 @@ def test_a_judged_sensor_is_left_out_of_the_host_temperature_and_listed_with_why
|
||||
real, unwired = split_temps("util", {"temp3": 62.0, "Package id 0": 55.0})
|
||||
assert list(real) == ["Package id 0"]
|
||||
assert unwired == {"temp3": (62.0, "falls as the CPU warms (r -0.81 over 168 h)")}
|
||||
|
||||
|
||||
def test_a_later_read_replaces_the_hour_that_was_filling_and_old_hours_drop():
|
||||
hours = {"h:temp:a": {T0: 50.0, T0 + timedelta(hours=1): 51.0}}
|
||||
s.merge_hours(hours, [("h:temp:a", T0 + timedelta(hours=1), 55.0), # the hour, read whole
|
||||
("h:temp:a", T0 + timedelta(hours=2), 56.0),
|
||||
("h:temp:b", T0 + timedelta(hours=2), None)], since=T0 + timedelta(hours=1))
|
||||
assert hours == {"h:temp:a": {T0 + timedelta(hours=1): 55.0, T0 + timedelta(hours=2): 56.0}}
|
||||
s.merge_hours(hours, [], since=T0 + timedelta(hours=9)) # a sensor gone quiet
|
||||
assert hours == {}
|
||||
|
||||
Reference in New Issue
Block a user