Skip to content

fix: prevent stale ORM cache reads in load_policy / load_filtered_policy#30

Closed
Copilot wants to merge 2 commits intomasterfrom
copilot/investigate-multi-worker-behavior
Closed

fix: prevent stale ORM cache reads in load_policy / load_filtered_policy#30
Copilot wants to merge 2 commits intomasterfrom
copilot/investigate-multi-worker-behavior

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Feb 27, 2026

SQLAlchemy's ORM identity map can serve cached (stale) objects when a long-lived or external session is reused across multiple load_policy calls. Any rows whose primary keys are already in the identity map are returned from the in-process cache rather than re-read from the database — so rules committed by another worker or a direct DB write are silently invisible until the session is replaced.

Changes

  • adapter.py — add .execution_options(populate_existing=True) to the SELECT in both load_policy and load_filtered_policy. This forces SQLAlchemy to overwrite identity-map entries with the values returned by the query, guaranteeing fresh data on every call regardless of session lifetime. No-op for the default internal session (empty identity map each call).

  • tests/test_external_session.py — adds test_load_policy_returns_fresh_data_with_external_session: seeds data, performs an initial load (populating the identity map), commits a new rule via a separate session (simulating another worker), then asserts the reused external session sees the new rule after load_policy is called again.

# Before – second load may silently return stale objects from the identity map
stmt = select(self._db_class)

# After – always overwrites identity-map entries with current DB values
stmt = select(self._db_class).execution_options(populate_existing=True)
Original prompt

This section details on the original issue you should resolve

<issue_title>Multi-worker test cases?</issue_title>
<issue_description>How do PyCasbin + async SQLAlchemy Adapter behave in multi-worker environment? I'm particularly interested in the scenario of reloading policies from DB.

  1. I manually add a rule in CasbinRule table.
  2. Via REST API, I initiate reload on worker A => I can confirm the new rule is loaded (on the same worker A).
  3. Some time passes...
  4. On Worker B, the newly added rule (in DB) might be not loaded in the objects in RAM?..

From my perspective, all the requests to Casbin should go its real storage. In our case, in CasinRule table. And, if needed, a developer would implement caching on top of it.</issue_description>

Comments on the Issue (you are @copilot in this section)


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

…cy to prevent stale ORM cache reads

Co-authored-by: hsluoyz <3787410+hsluoyz@users.noreply.github.com>
Copilot AI changed the title [WIP] Investigate multi-worker behavior with PyCasbin and async SQLAlchemy fix: prevent stale ORM cache reads in load_policy / load_filtered_policy Feb 27, 2026
@hsluoyz hsluoyz marked this pull request as ready for review February 27, 2026 15:01
@hsluoyz hsluoyz closed this Feb 27, 2026
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.

Multi-worker test cases?

2 participants