fffiloni commited on
Commit
4e0880e
·
verified ·
1 Parent(s): de0693a

feat(cache): add in-memory caching for repo and community activity fetches

Browse files
Files changed (1) hide show
  1. app.py +48 -2
app.py CHANGED
@@ -41,6 +41,34 @@ rate_limiter = RateLimiter(calls_per_second=10)
41
  recent_activity_rate_limiter = RateLimiter(calls_per_second=1.0)
42
 
43
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
  # ============================================================
45
  # Public cache only
46
  # ============================================================
@@ -502,10 +530,16 @@ def fetch_all_community_activity(username: str, selected_year: int):
502
  username = (username or "").strip()
503
  selected_year = int(selected_year)
504
 
 
 
 
 
 
505
  if not username:
506
  state = empty_community_state(selected_year)
507
  state["fetched"] = True
508
  state["logs"] = "No username provided."
 
509
  return state
510
 
511
  pr_opened = fetch_user_discussion_activity(username, selected_year, "pr_opened")
@@ -522,7 +556,7 @@ def fetch_all_community_activity(username: str, selected_year: int):
522
  ]
523
  )
524
 
525
- return {
526
  "username": username,
527
  "selected_year": selected_year,
528
  "fetched": True,
@@ -533,6 +567,9 @@ def fetch_all_community_activity(username: str, selected_year: int):
533
  "logs": combined_logs,
534
  }
535
 
 
 
 
536
 
537
  # ============================================================
538
  # Contribution grid helpers
@@ -867,6 +904,12 @@ def build_app_state(
867
  "auth_text": "No username provided.",
868
  }
869
 
 
 
 
 
 
 
870
  if profile is not None and is_own_profile:
871
  auth_text = (
872
  f'Logged in as <b>{html.escape(viewer_username)}</b>. '
@@ -889,7 +932,7 @@ def build_app_state(
889
  token=token_for_fetch,
890
  )
891
 
892
- return {
893
  "username": username,
894
  "selected_year": selected_year,
895
  "viewer_username": viewer_username,
@@ -900,6 +943,9 @@ def build_app_state(
900
  "auth_text": auth_text,
901
  }
902
 
 
 
 
903
 
904
  def render_app_state(app_state: dict | None, visibility_mode: str | None):
905
  if not app_state or not app_state.get("username"):
 
41
  recent_activity_rate_limiter = RateLimiter(calls_per_second=1.0)
42
 
43
 
44
+ # ============================================================
45
+ # Simple in-memory cache
46
+ # ============================================================
47
+ CACHE = {}
48
+ CACHE_TTL = 60 * 10 # 10 minutes
49
+ CACHE_LOCK = threading.Lock()
50
+
51
+
52
+ def get_cache(key):
53
+ with CACHE_LOCK:
54
+ entry = CACHE.get(key)
55
+ if not entry:
56
+ return None
57
+
58
+ value, timestamp = entry
59
+ if time.time() - timestamp > CACHE_TTL:
60
+ del CACHE[key]
61
+ return None
62
+
63
+ print(f"[CACHE HIT] {key}")
64
+ return value
65
+
66
+
67
+ def set_cache(key, value):
68
+ with CACHE_LOCK:
69
+ CACHE[key] = (value, time.time())
70
+
71
+
72
  # ============================================================
73
  # Public cache only
74
  # ============================================================
 
530
  username = (username or "").strip()
531
  selected_year = int(selected_year)
532
 
533
+ cache_key = (username.lower(), selected_year, "community")
534
+ cached = get_cache(cache_key)
535
+ if cached:
536
+ return cached
537
+
538
  if not username:
539
  state = empty_community_state(selected_year)
540
  state["fetched"] = True
541
  state["logs"] = "No username provided."
542
+ set_cache(cache_key, state)
543
  return state
544
 
545
  pr_opened = fetch_user_discussion_activity(username, selected_year, "pr_opened")
 
556
  ]
557
  )
558
 
559
+ result = {
560
  "username": username,
561
  "selected_year": selected_year,
562
  "fetched": True,
 
567
  "logs": combined_logs,
568
  }
569
 
570
+ set_cache(cache_key, result)
571
+ return result
572
+
573
 
574
  # ============================================================
575
  # Contribution grid helpers
 
904
  "auth_text": "No username provided.",
905
  }
906
 
907
+ scope = "repo_private" if is_own_profile else "repo_public"
908
+ cache_key = (username.lower(), selected_year, scope)
909
+ cached = get_cache(cache_key)
910
+ if cached:
911
+ return cached
912
+
913
  if profile is not None and is_own_profile:
914
  auth_text = (
915
  f'Logged in as <b>{html.escape(viewer_username)}</b>. '
 
932
  token=token_for_fetch,
933
  )
934
 
935
+ result = {
936
  "username": username,
937
  "selected_year": selected_year,
938
  "viewer_username": viewer_username,
 
943
  "auth_text": auth_text,
944
  }
945
 
946
+ set_cache(cache_key, result)
947
+ return result
948
+
949
 
950
  def render_app_state(app_state: dict | None, visibility_mode: str | None):
951
  if not app_state or not app_state.get("username"):