Syntrex Claude Sonnet 4.6 commited on
Commit
28a1d5a
·
1 Parent(s): 7b21bf1

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 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 = 40
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: