Spaces:
Sleeping
Sleeping
Fix props page hang: reduce build timeout to 5s, fix st.session_state in cache, async log
Browse files- Reduce _FALLBACK_BUILD_TIMEOUT_SECONDS from 40s to 5s: users now wait
max 5s before content appears (vs 40s which appeared as a hang)
- Move st.session_state write out of @st .cache_data to render_props():
prevents StreamlitAPIException on newer Streamlit; use setdefault to
avoid resetting the reload timer on reruns
- Wrap _maybe_log_props() in threading.Thread with join(timeout=5): prevents
DB insert hang from blocking the render pipeline; logs still written
synchronously within 5s or fire-and-forget if DB is slow
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- data/shared_baseline.py +1 -1
- visualization/props_page.py +5 -4
data/shared_baseline.py
CHANGED
|
@@ -26,7 +26,7 @@ _MAX_ROWS_PER_PLAYER = 420
|
|
| 26 |
_MIN_CURRENT_ROWS_WHEN_AVAILABLE = 20
|
| 27 |
_SNAPSHOT_VERSION = "shared_baseline_v1"
|
| 28 |
_DEFAULT_SNAPSHOT_MAX_AGE_SECONDS = 60 * 30
|
| 29 |
-
_FALLBACK_BUILD_TIMEOUT_SECONDS: int =
|
| 30 |
_PRIOR_SEASON_RECENCY_WEIGHTS = {
|
| 31 |
2025: 1.00,
|
| 32 |
2024: 0.85,
|
|
|
|
| 26 |
_MIN_CURRENT_ROWS_WHEN_AVAILABLE = 20
|
| 27 |
_SNAPSHOT_VERSION = "shared_baseline_v1"
|
| 28 |
_DEFAULT_SNAPSHOT_MAX_AGE_SECONDS = 60 * 30
|
| 29 |
+
_FALLBACK_BUILD_TIMEOUT_SECONDS: int = 5
|
| 30 |
_PRIOR_SEASON_RECENCY_WEIGHTS = {
|
| 31 |
2025: 1.00,
|
| 32 |
2024: 0.85,
|
visualization/props_page.py
CHANGED
|
@@ -679,9 +679,6 @@ def _load_props_prepared_bundle(
|
|
| 679 |
max_age_seconds=60 * 60,
|
| 680 |
persist_runtime_refresh=True,
|
| 681 |
)
|
| 682 |
-
if bundle.get("snapshot_source_status") in ("runtime_fallback_timeout", "patch_build_timeout"):
|
| 683 |
-
import time as _time
|
| 684 |
-
st.session_state["props_baseline_reload_at"] = _time.time() + 80
|
| 685 |
pitcher_statcast_df = bundle.get("blended_pitcher_df", pd.DataFrame())
|
| 686 |
starter_bundle = _load_props_starter_bundle(
|
| 687 |
raw=raw,
|
|
@@ -1991,6 +1988,8 @@ def render_props(
|
|
| 1991 |
probable_starters=probable_starters,
|
| 1992 |
)
|
| 1993 |
import time as _time
|
|
|
|
|
|
|
| 1994 |
_reload_at = st.session_state.get("props_baseline_reload_at")
|
| 1995 |
if _reload_at:
|
| 1996 |
if _time.time() < _reload_at:
|
|
@@ -2062,7 +2061,9 @@ def render_props(
|
|
| 2062 |
st.info("No mappable HR prop rows." if market_type == "hr" else "No props available.")
|
| 2063 |
return
|
| 2064 |
|
| 2065 |
-
_maybe_log_props(conn, mapped)
|
|
|
|
|
|
|
| 2066 |
|
| 2067 |
view_model = build_hr_props_view_model(mapped) if market_type == "hr" else None
|
| 2068 |
if view_model is not None:
|
|
|
|
| 679 |
max_age_seconds=60 * 60,
|
| 680 |
persist_runtime_refresh=True,
|
| 681 |
)
|
|
|
|
|
|
|
|
|
|
| 682 |
pitcher_statcast_df = bundle.get("blended_pitcher_df", pd.DataFrame())
|
| 683 |
starter_bundle = _load_props_starter_bundle(
|
| 684 |
raw=raw,
|
|
|
|
| 1988 |
probable_starters=probable_starters,
|
| 1989 |
)
|
| 1990 |
import time as _time
|
| 1991 |
+
if prepared_bundle.get("snapshot_source_status") in ("runtime_fallback_timeout", "patch_build_timeout"):
|
| 1992 |
+
st.session_state.setdefault("props_baseline_reload_at", _time.time() + 80)
|
| 1993 |
_reload_at = st.session_state.get("props_baseline_reload_at")
|
| 1994 |
if _reload_at:
|
| 1995 |
if _time.time() < _reload_at:
|
|
|
|
| 2061 |
st.info("No mappable HR prop rows." if market_type == "hr" else "No props available.")
|
| 2062 |
return
|
| 2063 |
|
| 2064 |
+
_log_t = threading.Thread(target=_maybe_log_props, args=(conn, mapped.copy()), daemon=True)
|
| 2065 |
+
_log_t.start()
|
| 2066 |
+
_log_t.join(timeout=5)
|
| 2067 |
|
| 2068 |
view_model = build_hr_props_view_model(mapped) if market_type == "hr" else None
|
| 2069 |
if view_model is not None:
|