Skip to content

fix: make session store fcntl import cross-platform compatible#1544

Merged
MervinPraison merged 2 commits into
mainfrom
claude/issue-1540-20260424-0947
Apr 24, 2026
Merged

fix: make session store fcntl import cross-platform compatible#1544
MervinPraison merged 2 commits into
mainfrom
claude/issue-1540-20260424-0947

Conversation

@praisonai-triage-agent

@praisonai-triage-agent praisonai-triage-agent Bot commented Apr 24, 2026

Copy link
Copy Markdown
Contributor

Fixes #1540

Summary

  • Fixes Windows test collection failure due to Unix-only fcntl import in session store
  • Applies the same cross-platform pattern already used in file_memory.py

Changes

  • Add conditional fcntl import using platform detection
  • Use _HAS_FCNTL flag to safely call fcntl functions only on Unix platforms
  • Windows continues to use msvcrt for file locking as before
  • Unix platforms use fcntl when available, fall back gracefully when not

Testing

  • Python syntax validation passes
  • Cross-platform import pattern matches existing file_memory.py
  • Should fix pytest src/praisonai-agents/tests -q collection on Windows

Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Improved session storage file locking to work correctly across Windows and Unix-based operating systems. This update prevents platform-specific locking conflicts, ensuring reliable and stable session persistence when managing user sessions across different systems and environments.

…1540)

- Add conditional fcntl import like file_memory.py already has
- Use _HAS_FCNTL flag to check fcntl availability before usage
- Windows uses msvcrt for locking, Unix uses fcntl when available
- Fixes Windows test collection failure due to missing fcntl module

Co-authored-by: praisonai-triage-agent[bot] <praisonai-triage-agent[bot]@users.noreply.github.com>
@MervinPraison

Copy link
Copy Markdown
Owner

@coderabbitai review

@MervinPraison

Copy link
Copy Markdown
Owner

/review

@coderabbitai

coderabbitai Bot commented Apr 24, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Apr 24, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Bot user detected.

To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5b544be9-48f1-4d6e-8a04-d47b34e7677a

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The change adds platform-aware file locking to the session store by conditionally importing and using fcntl only on Unix systems. Windows builds now use msvcrt locking without import failures, preventing test collection failures on Windows.

Changes

Cohort / File(s) Summary
Platform-Aware File Locking
src/praisonai-agents/praisonaiagents/session/store.py
Added conditional fcntl availability detection via _HAS_FCNTL flag. Wrapped Unix-specific fcntl.flock calls to only execute on non-Windows platforms. Windows locking via msvcrt remains unchanged. Prevents ModuleNotFoundError on Windows during test collection.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

Possibly related PRs

Poem

🐰 Hops across the Windows bridge,
No more fcntl's import ridge,
Unix locks when present found,
Cross-platform tested, safe and sound!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately and specifically describes the main change: making the fcntl import cross-platform compatible to fix Windows compatibility.
Linked Issues check ✅ Passed The PR successfully addresses all coding requirements from issue #1540: guards fcntl import with platform detection, retains Windows msvcrt behavior, uses _HAS_FCNTL flag pattern, and mirrors file_memory.py implementation.
Out of Scope Changes check ✅ Passed All changes are directly scoped to resolving issue #1540; modifications only affect the session store file locking logic with platform-aware guards.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/issue-1540-20260424-0947

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@MervinPraison

Copy link
Copy Markdown
Owner

@copilot Do a thorough review of this PR. Read ALL existing reviewer comments above from Qodo, Coderabbit, and Gemini first — incorporate their findings.

Review areas:

  1. Bloat check: Are changes minimal and focused? Any unnecessary code or scope creep?
  2. Security: Any hardcoded secrets, unsafe eval/exec, missing input validation?
  3. Performance: Any module-level heavy imports? Hot-path regressions?
  4. Tests: Are tests included? Do they cover the changes adequately?
  5. Backward compat: Any public API changes without deprecation?
  6. Code quality: DRY violations, naming conventions, error handling?
  7. Address reviewer feedback: If Qodo, Coderabbit, or Gemini flagged valid issues, include them in your review
  8. Suggest specific improvements with code examples where possible

@greptile-apps

greptile-apps Bot commented Apr 24, 2026

Copy link
Copy Markdown

Greptile Summary

This PR fixes a Windows import-time crash by moving import fcntl behind a sys.platform != 'win32' guard, mirroring the pattern in file_memory.py. The change is minimal, correct, and scoped to the one file that was broken; FileLock.acquire and release are updated consistently to check _HAS_FCNTL before calling any fcntl API.

Confidence Score: 5/5

Safe to merge — the fix is correct, narrowly scoped, and all remaining findings are P2 or lower.

The root cause (unconditional import fcntl at module level breaking Windows test collection) is properly fixed. The previously flagged dead-code fallback path (_HAS_FCNTL False on non-Windows) is already captured in an existing thread; no new P0/P1 issues were found. Score is 5 per the guidance that all-P2 PRs should default to 5.

No files require special attention.

Important Files Changed

Filename Overview
src/praisonai-agents/praisonaiagents/session/store.py Replaces top-level import fcntl with a conditional sys.platform != 'win32' guard and adds _HAS_FCNTL flag; FileLock.acquire/release updated to check the flag before calling fcntl. Fix is logically correct and resolves the Windows import-time crash.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Module Import] --> B{sys.platform win32?}
    B -- Yes --> C[_HAS_FCNTL = False\nfcntl not imported]
    B -- No --> D[import fcntl\n_HAS_FCNTL = True]
    C --> E[FileLock.acquire]
    D --> E
    E --> F{sys.platform win32?}
    F -- Yes --> G[msvcrt.locking LK_NBLCK]
    F -- No --> H{_HAS_FCNTL?}
    H -- True --> I[fcntl.flock LOCK_EX+NB]
    H -- False --> J[Log warning once\nReturn True without lock]
    G --> K{Success?}
    I --> K
    J --> K
    K -- Yes --> L[return True]
    K -- No --> M{Timeout?}
    M -- No --> N[sleep 50ms and Retry]
    M -- Yes --> O[Log warning\nreturn False]
    N --> E
Loading

Reviews (2): Last reviewed commit: "fix: add one-time warning for degraded f..." | Re-trigger Greptile

Comment thread src/praisonai-agents/praisonaiagents/session/store.py

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/praisonai-agents/praisonaiagents/session/store.py`:
- Around line 157-161: The acquire()/release() path silently no-ops when
_HAS_FCNTL is False, so add a one-time warning when entering acquire() or
release() and _HAS_FCNTL is False (and os.name != "nt") to alert operators that
inter-process locking is degraded; implement this by adding a module-level
sentinel (e.g., _WARNED_NO_FCNTL) and, when first detected in methods acquire()
and release() (which reference self._lock_file and call fcntl.flock with
LOCK_EX/LOCK_UN), emit a warning via the existing logger (or the logging module)
that clearly states file locking is unavailable and may risk concurrent writes,
then set the sentinel so the warning only logs once.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: cef47fd0-7c66-4eba-bfd7-1c17f390ece0

📥 Commits

Reviewing files that changed from the base of the PR and between 0634923 and 281adcf.

📒 Files selected for processing (1)
  • src/praisonai-agents/praisonaiagents/session/store.py

Comment on lines 157 to 161
else:
# Unix locking
fcntl.flock(self._lock_file.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB)
if _HAS_FCNTL:
fcntl.flock(self._lock_file.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB)
return True

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Silent no-op locking when _HAS_FCNTL is False on a non-Windows platform.

If _HAS_FCNTL ends up False on a non-Windows platform (possible today only in the hardened variant above, but still worth guarding), acquire() skips the flock call and immediately returns True, giving callers the illusion of a successful inter-process lock while no locking actually occurs. This can silently corrupt session JSON under concurrent writers. At minimum, log a one-time warning so operators are aware locking is degraded; the same applies symmetrically to release() at Lines 181–182.

🪵 Suggested one-time warning
             else:
                 # Unix locking
                 if _HAS_FCNTL:
                     fcntl.flock(self._lock_file.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB)
+                elif not getattr(FileLock, "_warned_no_lock", False):
+                    logger.warning(
+                        "File locking unavailable on this platform (no fcntl/msvcrt); "
+                        "concurrent writers may corrupt session files."
+                    )
+                    FileLock._warned_no_lock = True
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
else:
# Unix locking
fcntl.flock(self._lock_file.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB)
if _HAS_FCNTL:
fcntl.flock(self._lock_file.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB)
return True
else:
# Unix locking
if _HAS_FCNTL:
fcntl.flock(self._lock_file.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB)
elif not getattr(FileLock, "_warned_no_lock", False):
logger.warning(
"File locking unavailable on this platform (no fcntl/msvcrt); "
"concurrent writers may corrupt session files."
)
FileLock._warned_no_lock = True
return True
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/praisonai-agents/praisonaiagents/session/store.py` around lines 157 -
161, The acquire()/release() path silently no-ops when _HAS_FCNTL is False, so
add a one-time warning when entering acquire() or release() and _HAS_FCNTL is
False (and os.name != "nt") to alert operators that inter-process locking is
degraded; implement this by adding a module-level sentinel (e.g.,
_WARNED_NO_FCNTL) and, when first detected in methods acquire() and release()
(which reference self._lock_file and call fcntl.flock with LOCK_EX/LOCK_UN),
emit a warning via the existing logger (or the logging module) that clearly
states file locking is unavailable and may risk concurrent writes, then set the
sentinel so the warning only logs once.

@MervinPraison

Copy link
Copy Markdown
Owner

@claude You are the FINAL architecture reviewer. If the branch is under MervinPraison/PraisonAI (not a fork), you are able to make modifications to this branch and push directly. SCOPE: Focus ONLY on Python packages (praisonaiagents, praisonai). Do NOT modify praisonai-rust or praisonai-ts. Read ALL comments above from Gemini, Qodo, CodeRabbit, and Copilot carefully before responding.

Phase 1: Review per AGENTS.md

  1. Protocol-driven: check heavy implementations vs core SDK
  2. Backward compatible: ensure zero feature regressions
  3. Performance: no hot-path regressions

Phase 2: FIX Valid Issues
4. For any VALID bugs or architectural flaws found by Gemini, CodeRabbit, Qodo, Copilot, or any other reviewer: implement the fix
5. Push all code fixes directly to THIS branch (do NOT create a new PR)
6. Comment a summary of exact files modified and what you skipped

Phase 3: Final Verdict
7. If all issues are resolved, approve the PR / close the Issue
8. If blocking issues remain, request changes / leave clear action items

@praisonai-triage-agent

praisonai-triage-agent Bot commented Apr 24, 2026

Copy link
Copy Markdown
Contributor Author

Claude finished @MervinPraison's task —— View job


Final Architecture Review

Phase 1: Architecture Review per AGENTS.md

  • Read AGENTS.md for architecture rules
  • Review changed file against protocol-driven design
  • Check backward compatibility
  • Verify no performance regressions

Phase 2: Address Valid Reviewer Issues

  • Analyze feedback from CodeRabbit, Greptile, and other reviewers
  • Implement fixes for valid issues
  • Push changes to branch

Phase 3: Final Verdict

  • Provide approval or request changes
  • Summary of modifications made

Architecture Analysis

Protocol-driven design: The fix maintains proper layering - file locking is a low-level implementation detail in the session store, not core SDK concerns.

Backward compatibility: No public API changes. Existing code will continue to work exactly as before.

Performance: No hot-path regressions. The conditional import happens once at module load time and adds negligible overhead.

The fix correctly mirrors the pattern already established in file_memory.py:576-580 and follows the same cross-platform approach. The implementation is minimal and focused on the specific issue without scope creep.

Issues Addressed

Silent no-op locking warning: Added module-level _WARNED_NO_FCNTL sentinel and one-time warning in FileLock.acquire() when _HAS_FCNTL is False on non-Windows platforms. This addresses CodeRabbit's valid concern about degraded locking scenarios, following AGENTS.md §4.8 error handling principles.

Files Modified

  • praisonaiagents/session/store.py:32 - Added _WARNED_NO_FCNTL module sentinel
  • praisonaiagents/session/store.py:164-172 - Added one-time warning for degraded locking
  • praisonaiagents/session/store.py:195 - Added explanatory comment in release()

Testing

Syntax validation: Python compilation successful
Module import: Import test successful
Basic functionality: Session store operations working correctly

Final Verdict

✅ APPROVED - This PR successfully fixes the Windows compatibility issue with minimal, focused changes that align with the framework's architecture principles. The additional warning enhancement improves error visibility and code robustness. Ready to merge.


Addresses CodeRabbit feedback about silent no-op locking when fcntl
is unavailable on non-Windows platforms. Adds module-level sentinel
to emit warning only once, following AGENTS.md error handling principles.

Co-authored-by: Mervin Praison <MervinPraison@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Windows test collection fails due to Unix-only fcntl import in session store

1 participant