Skip to content

Commit 9a0c6c0

Browse files
committed
Add recompute button to bypass cache for analysis
- Add force_recompute param to compute_similar_talks/compute_topic_clusters - Add ?recompute=1 query param support to compute-analysis endpoint - Show "Recompute (ignore cache)" button after initial results load - Replace globals with functools.cache, simplify _get_submission_languages - Remove unused language mappings, keep only English and Italian
1 parent 24d0bc2 commit 9a0c6c0

3 files changed

Lines changed: 47 additions & 19 deletions

File tree

backend/reviews/admin.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -447,13 +447,20 @@ def review_recap_compute_analysis_view(self, request, review_session_id):
447447

448448
conference = review_session.conference
449449
accepted_submissions = self._get_accepted_submissions(conference)
450+
force_recompute = request.GET.get("recompute") == "1"
450451

451452
similar_talks = compute_similar_talks(
452-
accepted_submissions, top_n=5, conference_id=conference.id
453+
accepted_submissions,
454+
top_n=5,
455+
conference_id=conference.id,
456+
force_recompute=force_recompute,
453457
)
454458

455459
topic_clusters = compute_topic_clusters(
456-
accepted_submissions, min_topic_size=3, conference_id=conference.id
460+
accepted_submissions,
461+
min_topic_size=3,
462+
conference_id=conference.id,
463+
force_recompute=force_recompute,
457464
)
458465

459466
# Build submissions list with similar talks, sorted by highest similarity

backend/reviews/similar_talks.py

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -253,14 +253,17 @@ def _get_cache_key(prefix: str, conference_id: int, submissions) -> str:
253253
return f"{prefix}:conf_{conference_id}:{content_hash.hexdigest()}"
254254

255255

256-
def compute_similar_talks(submissions, top_n=5, conference_id=None):
256+
def compute_similar_talks(
257+
submissions, top_n=5, conference_id=None, force_recompute=False
258+
):
257259
"""
258260
Compute similar talks for each submission based on embeddings.
259261
260262
Args:
261263
submissions: A list of Submission objects
262264
top_n: Number of similar talks to return for each submission
263265
conference_id: Optional conference ID for cache key
266+
force_recompute: Skip cache and recompute fresh results
264267
265268
Returns:
266269
A dictionary mapping submission IDs to lists of similar submission IDs
@@ -276,9 +279,10 @@ def compute_similar_talks(submissions, top_n=5, conference_id=None):
276279
cache_key = None
277280
if conference_id:
278281
cache_key = _get_cache_key("similar_talks", conference_id, submissions_list)
279-
cached_result = cache.get(cache_key)
280-
if cached_result is not None:
281-
return cached_result
282+
if not force_recompute:
283+
cached_result = cache.get(cache_key)
284+
if cached_result is not None:
285+
return cached_result
282286

283287
model = get_embedding_model()
284288

@@ -309,14 +313,17 @@ def compute_similar_talks(submissions, top_n=5, conference_id=None):
309313
return similar_talks
310314

311315

312-
def compute_topic_clusters(submissions, min_topic_size=3, conference_id=None):
316+
def compute_topic_clusters(
317+
submissions, min_topic_size=3, conference_id=None, force_recompute=False
318+
):
313319
"""
314320
Compute topic clusters for submissions using BERTopic.
315321
316322
Args:
317323
submissions: A list of Submission objects
318324
min_topic_size: Minimum number of talks per cluster
319325
conference_id: Optional conference ID for cache key
326+
force_recompute: Skip cache and recompute fresh results
320327
321328
Returns:
322329
A dictionary with:
@@ -334,9 +341,10 @@ def compute_topic_clusters(submissions, min_topic_size=3, conference_id=None):
334341
cache_key = None
335342
if conference_id:
336343
cache_key = _get_cache_key("topic_clusters_v4", conference_id, submissions_list)
337-
cached_result = cache.get(cache_key)
338-
if cached_result is not None:
339-
return cached_result
344+
if not force_recompute:
345+
cached_result = cache.get(cache_key)
346+
if cached_result is not None:
347+
return cached_result
340348

341349
model = get_embedding_model()
342350
texts = [get_embedding_text(s) for s in submissions_list]

backend/reviews/templates/reviews-recap.html

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -434,12 +434,15 @@ <h3>🏷️ Tags</h3>
434434
{% endfor %}
435435

436436
<!-- Compute Analysis Button -->
437-
<div class="recap-section" style="text-align: center;">
437+
<div id="analysis-controls" class="recap-section" style="text-align: center;">
438438
<button type="button" id="compute-analysis-btn" class="button" style="padding: 10px 30px; font-size: 16px; cursor: pointer;">
439439
Compute Topic Clusters &amp; Similar Talks
440440
</button>
441+
<button type="button" id="recompute-analysis-btn" class="button" style="padding: 10px 30px; font-size: 16px; cursor: pointer; display: none;">
442+
Recompute (ignore cache)
443+
</button>
441444
<div id="analysis-loading" style="display: none; margin-top: 15px;">
442-
<span style="color: var(--body-quiet-color, #666);">Computing analysis (this may take a moment on first run)...</span>
445+
<span style="color: var(--body-quiet-color, #666);">Computing analysis (this may take a moment)...</span>
443446
</div>
444447
<div id="analysis-error" style="display: none; margin-top: 15px; color: #c0392b;"></div>
445448
</div>
@@ -470,6 +473,7 @@ <h2 class="recap-section-title">🔗 Similar Talks</h2>
470473
<script>
471474
(function() {
472475
const btn = document.getElementById('compute-analysis-btn');
476+
const recomputeBtn = document.getElementById('recompute-analysis-btn');
473477
const loading = document.getElementById('analysis-loading');
474478
const errorDiv = document.getElementById('analysis-error');
475479
const computeUrl = '{{ compute_analysis_url }}';
@@ -566,13 +570,16 @@ <h2 class="recap-section-title">🔗 Similar Talks</h2>
566570
section.style.display = '';
567571
}
568572

569-
btn.addEventListener('click', function() {
570-
btn.disabled = true;
571-
btn.textContent = 'Computing...';
573+
function fetchAnalysis(recompute) {
574+
var url = recompute ? computeUrl + '?recompute=1' : computeUrl;
575+
var activeBtn = recompute ? recomputeBtn : btn;
576+
577+
activeBtn.disabled = true;
578+
activeBtn.textContent = recompute ? 'Recomputing...' : 'Computing...';
572579
loading.style.display = '';
573580
errorDiv.style.display = 'none';
574581

575-
fetch(computeUrl, {
582+
fetch(url, {
576583
headers: { 'X-Requested-With': 'XMLHttpRequest' }
577584
})
578585
.then(function(response) {
@@ -582,18 +589,24 @@ <h2 class="recap-section-title">🔗 Similar Talks</h2>
582589
.then(function(data) {
583590
loading.style.display = 'none';
584591
btn.style.display = 'none';
592+
recomputeBtn.style.display = '';
593+
recomputeBtn.disabled = false;
594+
recomputeBtn.textContent = 'Recompute (ignore cache)';
585595

586596
renderTopicClusters(data.topic_clusters);
587597
renderSimilarTalks(data.submissions_list);
588598
})
589599
.catch(function(err) {
590600
loading.style.display = 'none';
591-
btn.disabled = false;
592-
btn.textContent = 'Compute Topic Clusters & Similar Talks';
601+
activeBtn.disabled = false;
602+
activeBtn.textContent = recompute ? 'Recompute (ignore cache)' : 'Compute Topic Clusters & Similar Talks';
593603
errorDiv.textContent = 'Failed to compute analysis: ' + err.message;
594604
errorDiv.style.display = '';
595605
});
596-
});
606+
}
607+
608+
btn.addEventListener('click', function() { fetchAnalysis(false); });
609+
recomputeBtn.addEventListener('click', function() { fetchAnalysis(true); });
597610
})();
598611
</script>
599612
{% endblock %}

0 commit comments

Comments
 (0)