docs: add comprehensive docstrings and inline comments
Add docstrings to all handler functions in daemon/handlers/firewall.py, covering params, return values, and raised exceptions. Add inline comments to _config_apply() reconciliation steps and the request body merge order. Add docstrings across lib/ modules for emit helpers (_emit_str, _emit_int, etc.), volatile stripping logic, two-layer diff strategy, sync event dispatch, and all cross-subsystem sync subscribers (DnsToFirewall, WgToFirewall, FirewallToDhcp, NetworkToAllSync). Document WireGuard/networkd config parsers and key-value mappers in system_import.py. Add docstrings to _ep(), Registry.decorator, setup_logging, and _replace helper across daemon/ and lib/.
This commit is contained in:
+27
-11
@@ -277,16 +277,21 @@ def _strip_volatile(
|
||||
for k in pop_keys:
|
||||
stripped.pop(k, None)
|
||||
for vpath in volatile:
|
||||
# Determine if this is a list-of-dicts pattern
|
||||
# Determine if this path uses list-of-dicts pattern (e.g. "peers[].transfer").
|
||||
# The [] marker signals that the parent key holds a list of dicts, and we
|
||||
# must strip the volatile sub-key from each dict in the list.
|
||||
list_marker = vpath.index("[]") if "[]" in vpath else -1
|
||||
if list_marker != -1:
|
||||
# Split into prefix (before []), item keys (after [])
|
||||
# Split into prefix (path before []), item keys (path after []).
|
||||
# e.g. "status.peers[].transfer_received" → prefix=["status","peers"],
|
||||
# item_keys=["transfer_received"]
|
||||
prefix = vpath[:list_marker].split(".")
|
||||
item_keys = (
|
||||
vpath[list_marker + 3 :].split(".")
|
||||
if list_marker + 3 < len(vpath)
|
||||
else []
|
||||
)
|
||||
# Navigate to the list container via the prefix path
|
||||
parent = stripped
|
||||
for seg in prefix:
|
||||
if isinstance(parent, dict) and seg in parent:
|
||||
@@ -305,6 +310,7 @@ def _strip_volatile(
|
||||
continue
|
||||
|
||||
for item in items:
|
||||
# parent should now be a list; iterate each dict and strip sub-keys
|
||||
if isinstance(item, dict):
|
||||
curr = item
|
||||
for i, ik in enumerate(item_keys):
|
||||
@@ -316,7 +322,7 @@ def _strip_volatile(
|
||||
else:
|
||||
break
|
||||
else:
|
||||
# Scalar/dict path
|
||||
# Scalar/dict path: navigate via segments and set final key to None
|
||||
segments = vpath.split(".")
|
||||
parent = stripped
|
||||
for i, seg in enumerate(segments):
|
||||
@@ -338,26 +344,36 @@ def _diff_layers(
|
||||
) -> tuple[bool, bool]:
|
||||
"""Compare *old* and *new* state using two-layer diff.
|
||||
|
||||
Strips ``timestamp`` from both before comparing.
|
||||
The two-layer strategy distinguishes between:
|
||||
1. Structural changes (config, topology) → triggers full client re-fetch
|
||||
2. Volatile changes (byte counters, timestamps) → triggers lightweight tick
|
||||
|
||||
If structural data changed, volatile is suppressed (False) because the
|
||||
structural change already triggers a full re-fetch, making the volatile
|
||||
signal redundant.
|
||||
|
||||
Args:
|
||||
old: Previous state data, or ``None`` if not yet populated.
|
||||
new: New state data from collector.
|
||||
volatile: Frozenset of volatile field paths.
|
||||
|
||||
Returns:
|
||||
``(structural_changed, volatile_changed)`` —
|
||||
``True`` means that layer differs between old and new.
|
||||
|
||||
If structural data changed, volatile is always ``False``
|
||||
(the structural change already triggers a full re-fetch, so
|
||||
the volatile signal is suppressed).
|
||||
``(structural_changed, volatile_changed)``.
|
||||
"""
|
||||
if old is None:
|
||||
return (True, True)
|
||||
|
||||
# Structural diff: compare with volatile/timestamp fields zeroed
|
||||
# Structural diff: compare with volatile fields zeroed out, plus timestamp
|
||||
# removed. If these differ, the configuration or topology has changed.
|
||||
pop_keys = frozenset(("timestamp",))
|
||||
old_struct = _strip_volatile(old, volatile, pop_keys)
|
||||
new_struct = _strip_volatile(new, volatile, pop_keys)
|
||||
structural = old_struct != new_struct
|
||||
|
||||
# Volatile diff: compare without timestamp
|
||||
# Volatile diff: only relevant if structural is unchanged. Compare full
|
||||
# data (minus timestamp). If this differs, only volatile fields changed
|
||||
# (e.g. WireGuard transfer counters), and a lightweight tick suffices.
|
||||
volatile_changed = False
|
||||
if not structural:
|
||||
old_no_ts = {k: v for k, v in old.items() if k != "timestamp"}
|
||||
|
||||
Reference in New Issue
Block a user