Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions changelogs/unreleased/ensure-agents-improvements.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
description: "Made various improvements to the AutostartedAgent._ensure_agents method"
sections:
bugfix: "Fixed a race condition where autostarted agents might become unresponsive for 30s when restarted"
issue-nr: 7612
change-type: patch
destination-branches:
- master
- iso7
- iso6

29 changes: 19 additions & 10 deletions src/inmanta/agent/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -977,16 +977,18 @@ async def _init_agent_map(self) -> None:
self.agent_map = dict(cfg.agent_map.get())

async def _init_endpoint_names(self) -> None:
if self.hostname is not None:
await self.add_end_point_name(self.hostname)
else:
# load agent names from the config file
agent_names = cfg.agent_names.get()
if agent_names is not None:
for name in agent_names:
if "$" in name:
name = name.replace("$node-name", self.node_name)
await self.add_end_point_name(name)
assert self.agent_map is not None
endpoints: Iterable[str] = (
[self.hostname]
if self.hostname is not None
else (
self.agent_map.keys()
if cfg.use_autostart_agent_map.get()
else (name if "$" not in name else name.replace("$node-name", self.node_name) for name in cfg.agent_names.get())
)
)
for endpoint in endpoints:
await self.add_end_point_name(endpoint)

async def stop(self) -> None:
await super().stop()
Expand Down Expand Up @@ -1069,6 +1071,13 @@ async def update_agent_map(self, agent_map: dict[str, str]) -> None:
await self._update_agent_map(agent_map)

async def _update_agent_map(self, agent_map: dict[str, str]) -> None:
if "internal" not in agent_map:
LOGGER.warning(
"Agent received an update_agent_map() trigger without internal agent in the agent_map %s",
agent_map,
)
agent_map = {"internal": "local:", **agent_map}

async with self._instances_lock:
self.agent_map = agent_map
# Add missing agents
Expand Down
10 changes: 6 additions & 4 deletions src/inmanta/data/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
import warnings
from abc import ABC, abstractmethod
from collections import abc, defaultdict
from collections.abc import Awaitable, Callable, Iterable, Sequence
from collections.abc import Awaitable, Callable, Iterable, Sequence, Set
from configparser import RawConfigParser
from contextlib import AbstractAsyncContextManager
from itertools import chain
Expand Down Expand Up @@ -1219,7 +1219,7 @@ def get_connection(
"""
if connection is not None:
return util.nullcontext(connection)
# Make pypi happy
# Make mypy happy
assert cls._connection_pool is not None
return cls._connection_pool.acquire()

Expand Down Expand Up @@ -3344,10 +3344,12 @@ def get_valid_field_names(cls) -> list[str]:
return super().get_valid_field_names() + ["process_name", "status"]

@classmethod
async def get_statuses(cls, env_id: uuid.UUID, agent_names: set[str]) -> dict[str, Optional[AgentStatus]]:
async def get_statuses(
cls, env_id: uuid.UUID, agent_names: Set[str], *, connection: Optional[asyncpg.connection.Connection] = None
) -> dict[str, Optional[AgentStatus]]:
result: dict[str, Optional[AgentStatus]] = {}
for agent_name in agent_names:
agent = await cls.get_one(environment=env_id, name=agent_name)
agent = await cls.get_one(environment=env_id, name=agent_name, connection=connection)
if agent:
result[agent_name] = agent.get_status()
else:
Expand Down
Loading