Skip to content

Commit 77deaec

Browse files
committed
monitors loader: add get monitors to load function
1 parent eadde7f commit 77deaec

File tree

2 files changed

+80
-0
lines changed

2 files changed

+80
-0
lines changed

src/components/monitors_loader/monitors_loader.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,32 @@ async def _disable_monitors_without_code_modules() -> None:
212212
await do_concurrently(*[_disable_monitor(monitor) for monitor in monitors_to_disable])
213213

214214

215+
async def _get_monitors_to_load(
216+
last_load_time: datetime | None,
217+
) -> tuple[dict[int, Monitor], list[CodeModule]]:
218+
"""Get all the monitors that need to be loaded"""
219+
# Get all enabled monitors
220+
loaded_monitors = await Monitor.get_all(Monitor.enabled.is_(True))
221+
monitors = {monitor.id: monitor for monitor in loaded_monitors}
222+
223+
# Get all code modules that were updated since the last load time
224+
# Add a time delta to have some room for code modules that updated right before the last load
225+
updated_code_modules = await CodeModule.get_updated_code_modules(
226+
monitors_ids=list(monitors.keys()),
227+
reference_timestamp=last_load_time,
228+
time_delta=timedelta(seconds=15),
229+
)
230+
code_modules = [code_module for code_module in updated_code_modules]
231+
232+
# Add monitors that are enabled but aren't in the registry
233+
registry_monitors_ids = set(registry.get_monitors_ids())
234+
pending_monitors = registry_monitors_ids - set(monitors.keys())
235+
if len(pending_monitors) > 0:
236+
code_modules.extend(await CodeModule.get_all(CodeModule.monitor_id.in_(pending_monitors)))
237+
238+
return monitors, code_modules
239+
240+
215241
async def _load_monitors() -> None:
216242
"""Load all enabled monitors from the database and add them to the registry. If any of the
217243
monitor's modules fails to load, the monitor will not be added to the registry"""

tests/components/monitors_loader/test_monitors_loader.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,60 @@ async def test_disable_monitors_without_code_modules_no_monitors_to_disable(mock
594594
disable_monitor_spy.assert_not_called()
595595

596596

597+
async def test_get_monitors_to_load(clear_database):
598+
"""'_get_monitors_to_load' should return only the updated monitors"""
599+
await databases.execute_application(
600+
'insert into "Monitors"(id, name, enabled) values'
601+
"(9999123, 'monitor_1', true),"
602+
"(9999456, 'internal.monitor_2', true),"
603+
"(9999457, 'disabled_monitor', false);"
604+
)
605+
await databases.execute_application(
606+
'insert into "CodeModules"(monitor_id, code, registered_at) values'
607+
"(9999123, 'def get_value(): return 10', '2025-01-10 00:00'),"
608+
"(9999456, 'def get_value(): return 11', '2025-01-20 00:00'),"
609+
"(9999457, 'def get_value(): return 12', '2025-01-30 00:00');"
610+
)
611+
612+
monitors, code_modules = await monitors_loader._get_monitors_to_load(
613+
datetime(2025, 1, 15, tzinfo=timezone.utc)
614+
)
615+
616+
assert len(monitors) == 2
617+
assert monitors[9999123].name == "monitor_1"
618+
assert monitors[9999456].name == "internal.monitor_2"
619+
assert len(code_modules) == 1
620+
assert code_modules[0].monitor_id == 9999456
621+
622+
623+
async def test_get_monitors_to_load_enabled_not_in_registry(clear_database):
624+
"""'_get_monitors_to_load' should return enabled monitors that are not in the registry"""
625+
await databases.execute_application(
626+
'insert into "Monitors"(id, name, enabled) values'
627+
"(9999123, 'monitor_1', true),"
628+
"(9999456, 'internal.monitor_2', true),"
629+
"(9999457, 'disabled_monitor', false);"
630+
)
631+
await databases.execute_application(
632+
'insert into "CodeModules"(monitor_id, code) values'
633+
"(9999123, 'def get_value(): return 10', '2025-01-10 00:00'),"
634+
"(9999456, 'def get_value(): return 11', '2025-01-20 00:00'),"
635+
"(9999457, 'def get_value(): return 12', '2025-01-30 00:00');"
636+
)
637+
638+
registry._monitors = {9999456: {"module": ModuleType}}
639+
640+
monitors, code_modules = await monitors_loader._get_monitors_to_load(
641+
datetime(2025, 1, 15, tzinfo=timezone.utc)
642+
)
643+
644+
assert len(monitors) == 2
645+
assert monitors[9999123].name == "monitor_1"
646+
assert monitors[9999456].name == "internal.monitor_2"
647+
assert len(code_modules) == 2
648+
assert {code_module.monitor_id for code_module in code_modules} == {9999123, 9999456}
649+
650+
597651
async def test_load_monitors(clear_database):
598652
"""'_load_monitors' should load all enabled monitors from the database and add them to the
599653
registry"""

0 commit comments

Comments
 (0)