Rudimentary impl of dogpile caching - #3011
Merged
Merged
Conversation
- Add dogpile-cache to pyproject.toml - Set up a basic, redis-backed, dogpile cache region with `distributed_lock` turned on and `thread_local_lock` turned off to play nicely in a threaded environment - Implement a custom cache-key generation strategy to try and match our current cache key patterns - Implement dogpile cached version of `dao_fetch_service_by_id` - Invalidate cache whenever a service's settings are updated
jimleroyer
reviewed
Aug 18, 2026
jimleroyer
reviewed
Aug 18, 2026
Instead of implementing per-model/per-dao method invalidation strategies, implement a broader strategy to allow us to, for example, invalidate all service related keys when a service is updated.
jimleroyer
reviewed
Aug 20, 2026
- Implemented basic json serializer / deserializer instead of pickling/unpickling values - Updates the key structure to reduce redundancy and logically group keys by entity - Updated tests
6 tasks
Contributor
There was a problem hiding this comment.
Pull request overview
Introduces a new dogpile.cache-based caching layer (Redis-backed) behind a feature flag, adds custom cache key generation and JSON encoding/decoding helpers, and wires the cached service fetch + invalidation into the service REST endpoints.
Changes:
- Add
dogpile-cachedependency and lockfile updates. - Add
app.cachingmodule with a configured dogpile region, key generator, serializer/deserializer, and grouped-key invalidation helper. - Add feature-flagged use of a cached
dao_fetch_service_by_idpath and invalidate service-related cache keys on service update.
Reviewed changes
Copilot reviewed 7 out of 8 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/app/test_dogpile_caching.py | Adds unit tests for dogpile eviction/invalidation patterns, cache key generation, and JSON (de)serialization helpers. |
| pyproject.toml | Adds dogpile-cache dependency (with Redis extra). |
| poetry.lock | Updates lockfile for dogpile-cache and its transitive dependencies. |
| app/service/rest.py | Feature-flagged use of cached service fetch; adds cache invalidation after service updates. |
| app/dao/services_dao.py | Adds a dogpile-cached variant of dao_fetch_service_by_id. |
| app/config.py | Adds FF_USE_DOGPILE_CACHING and dogpile cache config defaults. |
| app/caching.py | New dogpile cache region + key generator + JSON serializer/deserializer + grouped-key invalidation. |
| app/init.py | Initializes the dogpile cache region during app startup. |
Suppressed comments (1)
app/dao/services_dao.py:209
- This cached DAO returns a SQLAlchemy
Serviceinstance, butdogpile_regionis configured with a JSON serializer/deserializer. Serializing a model object viajson.dumps(..., default=str)will store a lossy string representation and subsequent reads will return a string (or wrong shape), breakingservice_schema.dumpand potentially corrupting cache contents.
query = Service.query.filter_by(id=service_id).options(joinedload("users"))
if only_active:
query = query.filter(Service.active)
return query.one()
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
- Remove explicit expiration time from annotations, let region configuration propagate - Ensure tests use the json serializer/deserializer - Removed explicit call to `invalidate_group_keys` for now - Default the cache config's REDIS_URL to localhost if not set
5 tasks
jimleroyer
approved these changes
Aug 31, 2026
jimleroyer
left a comment
Member
There was a problem hiding this comment.
LGTM - this is good to test and go forward. We likely need to experiment on the best setup and get app's team feedback on this. cc @andrewleith
23 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary | Résumé
This PR implements the basics required to enable dogpile caching in our system. In essence dogpile caches DB responses resulting from DAO method calls; similar to how we cache API responses in Admin, just at the DAO level.
Current progress
distributed_lockturned on andthread_local_lockturned off to play nicely in a threaded environmentdao_fetch_service_by_idInvalidate cache whenever a service's settings are updatedWill settle on an invalidation implementation after evaluating the viability of ORM-event hooks vs manually invoking custom invalidation methods. I may be a hybrid of both approaches.TODO
EncodeProxyto support JSON encoding of cache values (it defaults to pickling)Test instructions | Instructions pour tester la modification
FF_USE_DOGPILE_CACHING=truein your .envNote: If the cache key didn't appear, you may need to check redis for an
service-<id>key and delete it then access that service again to trigger the DB call + dogpile caching.Release Instructions | Instructions pour le déploiement
None.
Reviewer checklist | Liste de vérification du réviseur