github-actions[bot] commited on
Commit
79cc755
·
1 Parent(s): 6465584

Deploy b0f223b

Browse files

Merge pull request #44 from WINTER4000/chore/stale-comments-and-log-timeout

Source: https://github.com/WINTER4000/turingDNA/commit/b0f223b1eb9559ffc79c72b484b7ff98e6dbdce5

Files changed (3) hide show
  1. dee/auth.py +6 -5
  2. dee/server.py +6 -4
  3. tests/conftest.py +26 -0
dee/auth.py CHANGED
@@ -660,8 +660,9 @@ def _next_month_start_iso() -> str:
660
  def increment_anon_runs_on_response(response: Response) -> Response:
661
  """Called from inside a /api/run handler that has decided to start a
662
  pipeline FOR an anonymous user. Stamps the first_at timestamp on the
663
- cookie if this is their first run; otherwise just bumps the
664
- informational run count without resetting the trial timer.
 
665
 
666
  Idempotent against being called twice on the same request — the
667
  response cookie just gets overwritten with the same data.
@@ -676,9 +677,9 @@ def increment_anon_runs_on_response(response: Response) -> Response:
676
  _set_anon_cookie(response, first_at, runs)
677
 
678
  # Also surface the trial state in a custom response header so the
679
- # frontend can read it without parsing the cookie itself. The frontend
680
- # uses this to start its own client-side countdown to the in-session
681
- # "sign in to keep going" modal.
682
  response.headers["X-TD-Trial-Runs-Left"] = str(max(0, ANON_FREE_RUNS - runs))
683
  response.headers["X-TD-Trial-Runs-Total"] = str(ANON_FREE_RUNS)
684
  # Kept for a client cached from before the switch: a stale auth.js still
 
660
  def increment_anon_runs_on_response(response: Response) -> Response:
661
  """Called from inside a /api/run handler that has decided to start a
662
  pipeline FOR an anonymous user. Stamps the first_at timestamp on the
663
+ cookie if this is their first run, and bumps the run count — which is
664
+ now the thing the gate actually reads, rather than an informational
665
+ counter beside a timer.
666
 
667
  Idempotent against being called twice on the same request — the
668
  response cookie just gets overwritten with the same data.
 
677
  _set_anon_cookie(response, first_at, runs)
678
 
679
  # Also surface the trial state in a custom response header so the
680
+ # frontend can read it without parsing the cookie itself. It shows the
681
+ # "sign in to keep going" modal when the count reaches zero. It used to
682
+ # arm a setTimeout here instead, which is what cut people off mid-read.
683
  response.headers["X-TD-Trial-Runs-Left"] = str(max(0, ANON_FREE_RUNS - runs))
684
  response.headers["X-TD-Trial-Runs-Total"] = str(ANON_FREE_RUNS)
685
  # Kept for a client cached from before the switch: a stale auth.js still
dee/server.py CHANGED
@@ -1299,10 +1299,12 @@ def create_app() -> Flask:
1299
 
1300
  @app.post("/api/run")
1301
  def start_run() -> Response:
1302
- # Auth-or-quota gate. Anonymous users get one free run; after
1303
- # that this returns a 402 with kind="auth_required" and the
1304
- # frontend pops the sign-up gate. Signed-in users (valid Supabase
1305
- # JWT in Authorization header) bypass entirely.
 
 
1306
  gate = _auth.require_auth_or_quota()
1307
  if gate is not None:
1308
  return gate
 
1299
 
1300
  @app.post("/api/run")
1301
  def start_run() -> Response:
1302
+ # Auth-or-quota gate. Anonymous visitors get ANON_FREE_RUNS of
1303
+ # them — runs, not minutes; see dee/auth.py for why the clock was
1304
+ # the wrong unit. After that this returns a 402 with
1305
+ # kind="auth_required" and the frontend pops the sign-up gate.
1306
+ # Signed-in users (valid Supabase JWT in Authorization header)
1307
+ # bypass entirely.
1308
  gate = _auth.require_auth_or_quota()
1309
  if gate is not None:
1310
  return gate
tests/conftest.py CHANGED
@@ -49,3 +49,29 @@ def _no_leaked_resolutions():
49
  _rc.clear()
50
  yield
51
  _rc.clear()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
  _rc.clear()
50
  yield
51
  _rc.clear()
52
+
53
+
54
+ @pytest.fixture(autouse=True)
55
+ def _no_leaked_scorers():
56
+ """Third instance of the same hazard, and the one that actually bit.
57
+
58
+ scoring._SCORER_CACHE is process-global on purpose: ESM-2 weights load
59
+ once and every caller reuses them. tests/test_scoring.py already cleared
60
+ it around each of its own tests — but an autouse fixture declared in a
61
+ test module covers only that module, so every other file ran unguarded.
62
+
63
+ test_model_choice.py::test_get_scorer_never_loads_a_gpu_model_in_process
64
+ installs a _FakeScorer and asserts a 'small' request constructs exactly
65
+ one. Run alone it passes; run after anything that has already warmed the
66
+ cache it gets the earlier scorer back, builds nothing, and fails
67
+ `assert len(built) == 1` with 0. The test is also the mirror image of the
68
+ problem — it leaves its _FakeScorer in the cache for whatever runs next.
69
+
70
+ An order-dependent failure in the suite that gates deploys is worse than
71
+ the bug it hides: it fails on an unrelated commit and gets re-run until
72
+ it passes.
73
+ """
74
+ from dee.core import scoring as _sc
75
+ _sc._SCORER_CACHE.clear()
76
+ yield
77
+ _sc._SCORER_CACHE.clear()