-
-
Notifications
You must be signed in to change notification settings - Fork 107
fix: stabilize session actor fanout #2062
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
@claude Please review this PR |
|
Claude finished @sanity's task —— View job PR Review CompleteTasks
Review Feedback1. Resource Leak Analysis (Addressing @iduartgomez's concern at session_actor.rs:24)Verdict: CONFIRMED - There is a resource leak, but it's partially mitigated The Mitigations in place:
Potential leak scenarios:
Recommendations:
2. Code Quality & Best PracticesPositive aspects:
Issues identified: a) Potential race condition in RegisterTransaction (lines 107-119) if let Some(result_arc) = self.pending_results.get_mut(&tx).and_then(|pending| {
pending.touch();
if pending.delivered_clients.insert(client_id) {
Some(pending.result.clone())
} else {
None
}
}) {
let mut recipients = HashSet::new();
recipients.insert(client_id);
self.deliver_result_to_clients(tx, recipients, result_arc);
self.cleanup_transaction_entry(tx, client_id);
}This checks b) Inconsistent cleanup in handle_result_delivery_with_request_id (lines 305-317) if !self.pending_results.contains_key(&tx)
&& self.pending_results.len() >= MAX_PENDING_RESULTS
{
self.enforce_pending_capacity();
}
let entry = self
.pending_results
.entry(tx)
.or_insert_with(|| PendingResult::new(result.clone()));
entry.delivered_clients.insert(client_id);
entry.result = result.clone();
entry.touch();This caches the result AFTER delivery. In c) Missing cleanup for client_request_ids self.client_request_ids.retain(|(_, c), _| *c != client_id);However, when results are delivered in d) Potential double-insertion in pending_results (lines 227-238) let entry = self
.pending_results
.entry(tx)
.or_insert_with(|| PendingResult::new(result.clone()));
entry.result = result.clone(); // ← Why overwrite?
entry.touch();If the entry already exists, we clone the result twice (once in the condition check, once here). This is inefficient. 3. Performance Concernsa) prune_pending_results() called on every message (line 73)
Recommendation: Only run pruning periodically (e.g., every 100 messages or via a separate tokio task). b) Memory overhead from Arc Recommendation: Add a size limit in bytes, not just a count limit. 4. TestingStrong test coverage:
Missing test cases:
5. DocumentationThe module-level documentation is good, but some functions lack comments:
6. Integration with handler.rsThe changes in Minor issue: The session adapter registration is silent on failure: if let Err(e) = session_tx.try_send(msg) {
tracing::warn!("Failed to notify session actor: {}", e);
}If the session actor channel is full or closed, this could lead to clients never receiving results. Should this be a hard error? SummaryOverall assessment: The PR successfully addresses session actor race conditions and implements result caching for late subscribers. The code is generally well-structured and tested. Critical issues:
Recommendations before merge:
Nice to have:
|
|
Followed up on the cache feedback:
Tests: |
|
@claude does cache eviction work exclusively on lazy evaluation or is preemptive? |
|
Claude finished @iduartgomez's task —— View job Cache eviction strategy analysisTasks
AnswerCache eviction works exclusively on lazy evaluation - there is no preemptive/background cleanup task. How it worksEviction is triggered only when the session actor processes incoming messages:
Key characteristicsLazy evaluation means:
Implications:
Example scenarios
|
@claude document well the current limitations for future reference |
|
Claude finished @iduartgomez's task —— View job Documentation completeTasks
SummaryI've added comprehensive documentation to What was documented:Module-level documentation (lines 6-40):
Constant documentation (lines 51-62):
Function documentation:
Key points for future maintainers:
The documentation provides a clear foundation for anyone considering changes to the eviction strategy or investigating memory usage patterns in production. Commit: |
Add comprehensive documentation explaining the lazy evaluation approach used for cache cleanup in the session actor's pending_results cache: - Module-level documentation describing the eviction strategy - Detailed explanation of lazy evaluation vs preemptive cleanup - Tradeoffs: advantages (simplicity, amortized cost) and limitations (idle memory retention, temporary overflow, burst accumulation) - Future considerations for production monitoring and improvements - Function-level comments for prune_pending_results and enforce_pending_capacity - Constant documentation explaining TTL and capacity limits This addresses the need for future maintainers to understand the design decision to use lazy evaluation and its implications for memory usage during idle periods. Co-authored-by: nacho.d.g <iduartgomez@users.noreply.github.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be changed to preemptive cache eviction in the future but let's merge for now.
There seems to be some flakiness in tests but idk if is related to the changes in the PR.
https://github.com/freenet/freenet-core/actions/runs/19207910362/job/54905769302
Summary
Testing