chore: round-4 polish + standardize on module-level loggers

Round-4 review (non-blocking) items:
- get_procrastinate_conninfo: warn on an empty connect_timeout= value (it falls
  back to the 10s default); preserve an explicit connect_timeout=0.
- Document the _doc_queueing_lock user_id invariant (NC rejects ':' in usernames).
- docs/configuration.md: note that `db downgrade` leaves procrastinate's tables
  in place and how to drop them on a full teardown.
- reclaim_stalled_ingest_jobs: debug heartbeat log when nothing is stalled.
- Drop the redundant list() wrap in the integration stalled-jobs assertion.

Logging pattern: define a module-level `logger = logging.getLogger(__name__)`
and use it instead of function-local or inline getLogger(__name__) calls
(config.py, config_validators.py, tests/.../test_scope_authorization.py). The
test file's dev-only `scripts.*` import gets a ty: ignore since it resolves via
sys.path at runtime, not as an installed package.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Chris Coutinho
2026-06-03 15:44:59 +02:00
co-authored by Claude Opus 4.8
parent b10ce15032
commit 704a537847
6 changed files with 44 additions and 34 deletions
+8 -6
View File
@@ -11,6 +11,8 @@ from typing import Any
from dynaconf import Dynaconf, Validator
logger = logging.getLogger(__name__)
# Sentinel for "key not in dynaconf at all" vs "explicitly set to None".
_UNSET = object()
@@ -734,7 +736,6 @@ class Settings:
def __post_init__(self):
"""Validate configuration and set defaults."""
logger = logging.getLogger(__name__)
# Validate SSL/TLS configuration
if not self.nextcloud_verify_ssl:
@@ -1064,8 +1065,6 @@ def _get_semantic_search_enabled() -> bool:
Returns:
True if semantic search should be enabled
"""
logger = logging.getLogger(__name__)
new_value = _dynaconf.get("ENABLE_SEMANTIC_SEARCH", False)
old_value = _dynaconf.get("VECTOR_SYNC_ENABLED", False)
@@ -1146,7 +1145,6 @@ def _log_bg_ops_advisories_once(
return
_bg_ops_advisories_logged = True
logger = logging.getLogger(__name__)
if explicit and legacy:
logger.warning(
"Both ENABLE_BACKGROUND_OPERATIONS and ENABLE_OFFLINE_ACCESS are set. "
@@ -1473,7 +1471,7 @@ def get_procrastinate_conninfo(database_url: str | None = None) -> str:
# query string is dropped with a warning.
dropped = sorted(k for k in url.query if k != "connect_timeout")
if dropped:
logging.getLogger(__name__).warning(
logger.warning(
"Dropping DATABASE_URL query parameters not forwarded to the "
"procrastinate connector: %s",
", ".join(dropped),
@@ -1492,10 +1490,14 @@ def get_procrastinate_conninfo(database_url: str | None = None) -> str:
params["password"] = url.password
# Honor an operator-supplied connect_timeout, else default to 10s. (make_url
# query values are str or a tuple of strs when repeated; take the last.)
# ``connect_timeout=0`` (disable) is preserved — only a missing/empty value
# falls back to the default, and an explicit-but-empty value is flagged.
_ct = url.query.get("connect_timeout")
if isinstance(_ct, (list, tuple)):
_ct = _ct[-1] if _ct else None
params["connect_timeout"] = str(_ct) if _ct else "10"
if _ct == "":
logger.warning("DATABASE_URL has an empty connect_timeout=; using default 10s")
params["connect_timeout"] = _ct if _ct else "10"
params.update(_pg_ssl_params())
return make_conninfo(**params)
@@ -187,8 +187,6 @@ def detect_auth_mode(settings: Settings) -> AuthMode:
ValueError: If explicit deployment_mode is unrecognised.
"""
logger = logging.getLogger(__name__)
# ADR-021: explicit deployment mode wins
if settings.deployment_mode:
mode_str = settings.deployment_mode.lower().strip()
@@ -136,6 +136,10 @@ async def reclaim_stalled_ingest_jobs(context: JobContext, timestamp: int) -> No
reclaimed += 1
if reclaimed:
logger.warning("ingest.reclaimed_stalled_jobs count=%d", reclaimed)
else:
# Visible heartbeat under verbose logging when debugging a suspected
# reclaim failure, without noising up production logs.
logger.debug("ingest.reclaim_check stalled=0")
async def _resolve_client(user_id: str) -> NextcloudClient:
@@ -293,11 +297,16 @@ def _doc_queueing_lock(task: DocumentTask) -> str:
"""Per-document enqueue-dedup key (partial-unique on ``status='todo'``).
Collision-safe with a raw ``:`` delimiter because the first two segments can
never themselves contain ``:``: ``user_id`` is a Nextcloud username/UID (no
colons) and ``doc_type`` is a controlled enum (``note``/``file``/
``deck_card``/``news_item``). The trailing ``doc_id`` may contain anything —
it's the final unambiguous segment. A future ``doc_type`` containing ``:``
would break this invariant, so keep doc_type colon-free.
never themselves contain ``:``:
- ``user_id`` — a Nextcloud username/UID; Nextcloud rejects ``:`` in
usernames (Web UI + provisioning validation), so it is colon-free.
- ``doc_type`` — a controlled enum (``note``/``file``/``deck_card``/
``news_item``); a future ``doc_type`` containing ``:`` would break this
invariant, so keep doc_type colon-free.
The trailing ``doc_id`` may contain anything — it's the final unambiguous
segment.
"""
return f"{task.user_id}:{task.doc_type}:{task.doc_id}"