Add cached impression writer for batching database writes#1168
Draft
ericholscher wants to merge 3 commits intomainfrom
Draft
Add cached impression writer for batching database writes#1168ericholscher wants to merge 3 commits intomainfrom
ericholscher wants to merge 3 commits intomainfrom
Conversation
Buffer impression increments (views, clicks, offers, decisions) in Django's cache instead of writing directly to the database on every ad request. A periodic Celery task flushes the accumulated counts to the AdImpression table in batch, reducing database write pressure. - Add CachedImpressionWriter in adserver/impression_cache.py - Gate the feature behind ADSERVER_IMPRESSION_CACHE_ENABLED setting (default off) - Modify Advertisement.incr() to use the cache when enabled - Add flush_impression_cache Celery task - Add 16 tests covering cache operations, flush behavior, and integration https://claude.ai/code/session_01Cpd47jJhFJ9MEkfobuzKSj
- Add flush_impression_cache to CELERY_BEAT_SCHEDULE in both production (every minute) and development settings so the task actually runs. - Fix race condition where increments arriving during a flush window were lost: use cache.decr() to subtract only the snapshotted amount instead of deleting keys outright, preserving any concurrent increments. - Fix race condition in dirty key tracking: add per-counter marker keys so concurrent _add_dirty_key calls don't clobber each other via read-modify-write on the shared set. - Re-read the dirty key set before pruning fully-flushed keys so new entries added during the flush are not discarded. - Add test_increments_during_flush_are_preserved to verify concurrent increment safety using mock-injected increments during cache.decr(). https://claude.ai/code/session_01Cpd47jJhFJ9MEkfobuzKSj
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
Implement a caching layer for ad impression tracking to reduce database load by batching writes. Instead of writing to the database on every impression event (offer, view, click), impressions are now accumulated in Django's cache and periodically flushed to the database in batch.
Key Changes
New
CachedImpressionWriterclass (impression_cache.py): Buffers impression increments in Django's cache with deterministic cache keys based on ad, publisher, date, and impression type. Providesincrement()to add to cached counters andflush()to batch-write to the database.Updated
Advertisement.incr()method (models.py): Added conditional logic to use the cached writer whenADSERVER_IMPRESSION_CACHE_ENABLEDis True, falling back to direct database writes when disabled.New periodic task (
tasks.py): Addedflush_impression_cache()Celery task to periodically flush cached impressions to the database.Configuration setting (
settings/base.py): AddedADSERVER_IMPRESSION_CACHE_ENABLEDenvironment variable (defaults to False) to control whether impression caching is active.Comprehensive test suite (
test_cached_impressions.py): 20 tests covering cache key generation, increment accumulation, dirty key tracking, database flushing, handling of existing records, multiple ads/impression types, null advertisements, concurrent safety, and integration with theAdvertisement.incr()method.Implementation Details
impression_cache:{ad_id}:{publisher_id}:{date}:{impression_type}https://claude.ai/code/session_01Cpd47jJhFJ9MEkfobuzKSj