-
Notifications
You must be signed in to change notification settings - Fork 20
Description
What happened?
Some time ago we switched to using polling because inotify doesn't work very well under some circumstances (like inside containers). The problem is polling is also not the panacea, as it seems like updates can be also missed if they are very close in time (my guess is that watchfiles has only 1 second resolution.
What did you expect instead?
All updates should be picked up.
Affected version(s)
No response
Affected part(s)
Configuration management (part:config)
Extra information
At this point I think we should really consider a better system for notifying about config updates, trying to watch files keep bringing issues and it is very problematic for testing, but since this might be a major undertaking, I guess for now we can just do a regular complete read of the config file, every 10 seconds or so, compare to the last read, and trigger an update if it changed. So the watcher would just be an optimization to pick up the changes more quickly.
This tests fails most of the time (I think it succeeds very seldom, when the await in the task crosses the second boundary:
import asyncio
import pathlib
from datetime import timedelta
import pytest
from frequenz.channels.file_watcher import EventType, FileWatcher
@pytest.fixture
def config_file(tmp_path: pathlib.Path) -> pathlib.Path:
"""Create a temporary config file for testing."""
# config_file = tmp_path / "config.toml"
config_file = pathlib.Path("/tmp/watch/config.toml")
config_file.write_text(
"""
[test]
name = "test1"
value = 42
[logging.root_logger]
level = "DEBUG"
"""
)
return config_file
async def change_config_file(config_file: pathlib.Path) -> None:
await asyncio.sleep(0.2)
config_file.write_text(
"""
[test]
name = "test2"
value = 43
[logging.root_logger]
level = "INFO"
"""
)
async def test_full_config_flow(config_file: pathlib.Path) -> None:
"""Test the complete flow of configuration management."""
print(f"Watching {config_file}")
file_watcher = FileWatcher(
paths=[config_file.parent],
event_types=set(EventType),
force_polling=True,
polling_interval=timedelta(seconds=0.1),
)
task = asyncio.create_task(change_config_file(config_file))
async with asyncio.timeout(5):
event = await file_watcher.receive()
print(event)
await taskMetadata
Metadata
Assignees
Labels
Type
Projects
Status