[PR #60] fix(sessions): prevent RuntimeError in cleanup_expired_sessions under concurrency #97

Open
opened 2026-03-02 15:47:54 +03:00 by kerem · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/PegaProx/project-pegaprox/pull/60
Author: @ry-ops
Created: 2/21/2026
Status: 🔄 Open

Base: mainHead: fix/session-cleanup-race-condition


📝 Commits (1)

  • ecfc9d1 fix(sessions): prevent RuntimeError in cleanup_expired_sessions under concurrency

📊 Changes

1 file changed (+13 additions, -4 deletions)

View changed files

📝 pegaprox_multi_cluster.py (+13 -4)

📄 Description

Summary

Under concurrent load a request handler thread can add or remove an entry from active_sessions while cleanup_expired_sessions is iterating over it, causing:

RuntimeError: dictionary changed size during iteration

Additionally, if a session was already deleted by another thread between the list comprehension and the del call, a KeyError would be raised.

Changes:

  • Snapshot active_sessions.items() into a list() before filtering — iteration is over an immutable copy
  • Replace del active_sessions[sid] with active_sessions.pop(sid, None) — silently skips sessions already removed by another thread
  • Use .get('last_activity', 0) as a safe fallback in the expiry filter

Test plan

  • Verify session cleanup still removes expired sessions correctly
  • Under high concurrent load, no RuntimeError: dictionary changed size during iteration appears in logs

🤖 Generated with Claude Code


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/PegaProx/project-pegaprox/pull/60 **Author:** [@ry-ops](https://github.com/ry-ops) **Created:** 2/21/2026 **Status:** 🔄 Open **Base:** `main` ← **Head:** `fix/session-cleanup-race-condition` --- ### 📝 Commits (1) - [`ecfc9d1`](https://github.com/PegaProx/project-pegaprox/commit/ecfc9d1924f922658a08a1edde626f2ed9a3e62d) fix(sessions): prevent RuntimeError in cleanup_expired_sessions under concurrency ### 📊 Changes **1 file changed** (+13 additions, -4 deletions) <details> <summary>View changed files</summary> 📝 `pegaprox_multi_cluster.py` (+13 -4) </details> ### 📄 Description ## Summary Under concurrent load a request handler thread can add or remove an entry from `active_sessions` while `cleanup_expired_sessions` is iterating over it, causing: ``` RuntimeError: dictionary changed size during iteration ``` Additionally, if a session was already deleted by another thread between the list comprehension and the `del` call, a `KeyError` would be raised. **Changes:** - Snapshot `active_sessions.items()` into a `list()` before filtering — iteration is over an immutable copy - Replace `del active_sessions[sid]` with `active_sessions.pop(sid, None)` — silently skips sessions already removed by another thread - Use `.get('last_activity', 0)` as a safe fallback in the expiry filter ## Test plan - [ ] Verify session cleanup still removes expired sessions correctly - [ ] Under high concurrent load, no `RuntimeError: dictionary changed size during iteration` appears in logs 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/project-pegaprox-PegaProx#97
No description provided.