fix(planner): guard apply_payload and reset_to_defaults with a lock
Concurrent PUT requests could observe a half-updated planner between the four sequential global assignments. Added _planner_lock so the rebind is atomic; same lock wraps reset_to_defaults.
This commit is contained in:
@@ -20,6 +20,7 @@ persona outside its window is never considered.
|
||||
from __future__ import annotations
|
||||
|
||||
import secrets
|
||||
import threading
|
||||
from datetime import datetime
|
||||
from typing import Any, Optional, Sequence
|
||||
|
||||
@@ -74,6 +75,7 @@ _USER_CLASS_WEIGHTS: tuple[tuple[ContentClass, int], ...] = _DEFAULT_USER_CLASS_
|
||||
_SYSTEM_CLASS_WEIGHTS: tuple[tuple[ContentClass, int], ...] = _DEFAULT_SYSTEM_CLASS_WEIGHTS
|
||||
_CANARY_CLASS_WEIGHTS: tuple[tuple[ContentClass, int], ...] = _DEFAULT_CANARY_CLASS_WEIGHTS
|
||||
_CANARY_PROBABILITY: float = _DEFAULT_CANARY_PROBABILITY
|
||||
_planner_lock = threading.Lock()
|
||||
|
||||
|
||||
def _serialize_weights(
|
||||
@@ -185,6 +187,7 @@ def apply_payload(payload: dict[str, Any]) -> None:
|
||||
raise ValueError("canary_probability must be in [0.0, 1.0]")
|
||||
new_prob = float(prob)
|
||||
|
||||
with _planner_lock:
|
||||
_USER_CLASS_WEIGHTS = new_user
|
||||
_SYSTEM_CLASS_WEIGHTS = new_system
|
||||
_CANARY_CLASS_WEIGHTS = new_canary
|
||||
@@ -195,6 +198,7 @@ def reset_to_defaults() -> None:
|
||||
"""Restore hardcoded defaults. Used by tests and the API reset path."""
|
||||
global _USER_CLASS_WEIGHTS, _SYSTEM_CLASS_WEIGHTS
|
||||
global _CANARY_CLASS_WEIGHTS, _CANARY_PROBABILITY
|
||||
with _planner_lock:
|
||||
_USER_CLASS_WEIGHTS = _DEFAULT_USER_CLASS_WEIGHTS
|
||||
_SYSTEM_CLASS_WEIGHTS = _DEFAULT_SYSTEM_CLASS_WEIGHTS
|
||||
_CANARY_CLASS_WEIGHTS = _DEFAULT_CANARY_CLASS_WEIGHTS
|
||||
|
||||
Reference in New Issue
Block a user