🪣 Aeon::CacheWindow – 4 + 1 Architecture¶
Expands query windows so Aeon can think ahead.
1️⃣ Logical View¶
Purpose:
Aeon::CacheWindow defines the normalized temporal span used for caching.
It widens short queries (like a single week) into predictable overlapping buffers (e.g., month ± 2 weeks) to prevent cache thrash when users scroll.
Responsibilities
- Normalize arbitrary ranges into consistent cache buckets.
- Provide deterministic cache keys (aeon:cache:{type}:{period_hash}).
- Align overlapping windows to ensure smooth refresh transitions.
Configuration
Aeon::CacheWindow.config.buffer_weeks = 2
Aeon::CacheWindow.config.alignment = :month
2️⃣ Process View¶
- A
Periodis requested (e.g., Mar 27 – Apr 3). - CacheWindow expands it to Feb 15 – May 15 (
month.beginning_of_month.weeks_ago(2)…month.end_of_month.weeks_since(2)). - A cache key is generated from the resulting range.
CacheManageruses that key to fetch or store results.
3️⃣ Development View¶
File: app/services/aeon/cache_window.rb
class Aeon::CacheWindow
BUFFER = 2.weeks
def self.for(period)
start = period.starts_at.beginning_of_month.weeks_ago(2).beginning_of_day
stop = period.ends_at.end_of_month.weeks_since(2).end_of_day
Aeon::Period.new(starts_at: start, ends_at: stop)
end
def self.key_for(period, topic: "all")
digest = Digest::SHA1.hexdigest("#{period.starts_at.to_i}-#{period.ends_at.to_i}")
"aeon:cache:#{topic}:#{digest}"
end
end
4️⃣ Physical View¶
| Attribute | Description |
|---|---|
| Store | Redis (via CacheManager) |
| TTL Policy | 6 hours – 24 hours |
| Integration | Invoked by Timekeeper and Refresher |
➕ 1 Scenario View¶
Scenario A: Monthly Calendar¶
User opens March → Aeon::CacheWindow.for(march_period)
→ Window = Feb 15 – Apr 15, cache key =aeon:cache:calendar:7d83….
Scenario B: Week Navigation¶
Switching to Week 1/Week 2 stays within the same expanded window → instant render.
Observability:
Argus event → aeon.cachewindow.generated.