Skip to content

RDBC-1035 RDBC-1036 Add aggressive caching context managers and store-level session events#277

Open
redknightlois wants to merge 1 commit intoravendb:v7.2from
redknightlois:RDBC-1035
Open

RDBC-1035 RDBC-1036 Add aggressive caching context managers and store-level session events#277
redknightlois wants to merge 1 commit intoravendb:v7.2from
redknightlois:RDBC-1035

Conversation

@redknightlois
Copy link
Copy Markdown
Member

Issue link

https://issues.hibernatingrhinos.com/issue/RDBC-1035
https://issues.hibernatingrhinos.com/issue/RDBC-1036

Additional description

RDBC-1035 – Adds aggressive caching support to the Python client. store.aggressively_cache_for(duration) and store.disable_aggressive_caching() are context managers that enable/disable serving GET responses directly from the local HTTP cache without a server round-trip. Cache options are thread-local, matching the C# AsyncLocal<T> semantics. The cache is automatically invalidated when document or index change notifications arrive.

RDBC-1036 – Adds store-level session event hooks: add_before_store, add_after_save_changes, add_before_delete, and add_before_query (with corresponding remove_* variants). Handlers registered on the store are automatically wired into every new session, eliminating the need to re-register on each open_session call.

Type of change

  • Bug fix
  • Regression bug fix
  • Optimization
  • New feature

How risky is the change?

  • Low
  • Moderate
  • High
  • Not relevant

Backward compatibility

  • Non breaking change
  • Ensured. Please explain how has it been implemented?
  • Breaking change
  • Not relevant

Is it platform specific issue?

  • Yes. Please list the affected platforms.
  • No

Documentation update

  • This change requires a documentation update. Please mark the issue on YouTrack using Documentation Required tag.
  • No documentation update is needed

Testing by Contributor

  • Tests have been added that prove the fix is effective or that the feature works
  • Internal classes added to the test class (e.g. entity or index definition classes) have the lowest possible access modifier (preferable private)
  • It has been verified by manual testing
  • Existing tests verify the correct behavior

Testing by RavenDB QA team

  • This change requires a special QA testing due to possible performance or resources usage implications (CPU, memory, IO). Please mark the issue on YouTrack using QA Required tag.
  • No special testing by RavenDB QA team is needed

Is there any existing behavior change of other features due to this change?

  • Yes. Please list the affected features/subsystems and provide appropriate explanation
  • No

UI work

  • It requires further work in the Studio. Please mark the issue on YouTrack using Studio Required tag.
  • No UI work is needed

@redknightlois redknightlois force-pushed the RDBC-1035 branch 4 times, most recently from 2d83c6c to b59cf08 Compare March 6, 2026 19:39
@redknightlois redknightlois changed the base branch from v7.1 to v7.2 March 6, 2026 21:11
@poissoncorp
Copy link
Copy Markdown
Contributor

please bump PR to run checks

# build an eviction object, but only one will be stored; the loser is
# discarded via close().
eviction = DocumentStore._AggressiveCacheEviction(self, database)
with self.__add_change_lock:
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.

let's replace the giant comment above with "this lock is here to achieve ConcurrentDict-like behavior" - will increase readability by far

@redknightlois
Copy link
Copy Markdown
Member Author

Let me run the cross gap analysis workflow again. This used a much older version (the first draft).

event()

# todo: evict items from cache based on changes
for eviction in list(self.__aggressive_cache_changes.values()):
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.

should also change var name here when the class name is improved

@redknightlois redknightlois force-pushed the RDBC-1035 branch 2 times, most recently from 72c7a7d to 6ce68fb Compare April 10, 2026 14:27

# --- aggressive cache ---

def test_get_from_cache_returns_empty_release_cache_item_for_non_cacheable_command(self):
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.

can we add happy-path tests proving aggressive cache works? if it's there, correct me please - there's a lot of tests that cover different corner cases

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

added

…evel events

- Add add/remove_before_store, add/remove_after_save_changes,
  add/remove_before_delete, add/remove_before_query to DocumentStoreBase;
  register_events_for_session wires them into every new session
- Add aggressively_cache_for(duration, mode) and disable_aggressive_caching()
  context managers on DocumentStore; AggressiveCacheOptions is thread-local
  via threading.local(), mirroring C# AsyncLocal<T>
- Add _AggressiveCacheEviction inner class: subscribes to Changes() feed and
  increments HttpCache.generation on DocumentChange / IndexChange events
- Fix _listen_to_changes_and_update_cache: construct _AggressiveCacheEviction
  outside __add_change_lock to prevent deadlock when store.changes() (which
  acquires the same lock) is called during construction
- Remove dead HttpCache.ReleaseCacheItem inner class; fix _get_from_cache
  to import and return the module-level ReleaseCacheItem for non-cacheable
  command paths (was AttributeError at runtime)
- Fix before_delete event timing for key-based session.delete(): move
  BeforeDeleteEventArgs dispatch from delete() into prepare_for_save_changes()
  via __prepare_for_key_deletes, matching C# PrepareForEntitiesDeletion timing
  and making both delete paths (key vs entity) consistent
- Fix session-level remove_before_query: was appending instead of removing,
  making it impossible to unregister a query event handler on an open session
- Rename session-level remove_before_delete_entity to remove_before_delete,
  matching the naming convention of all other remove methods and the store-level API
- Add no_caching guard to _check_aggressive_cache_guard test helper so it
  exactly mirrors the condition in execute(); add test for no_caching bypass
- Add integration tests verifying event args contents: args.entity identity
  in OnBeforeStore and args.key in OnBeforeDelete (per C# Events.cs spec)
- Remove test for unreachable RAW-command cache-hit path: _get_from_cache
  never returns a populated item for non-OBJECT commands, so the scenario
  the test described could not occur in production
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.

2 participants