Add opt-in cache of rendered images (lib + server) - #55
Open
devin-ai-integration[bot] wants to merge 1 commit into
Open
devin-ai-integration[bot] wants to merge 1 commit into
devin-ai-integration[bot] wants to merge 1 commit into
Conversation
Refs #11 Co-Authored-By: Julian Perelli <jperelli@gmail.com>
Author
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
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
Refs #11. The only cache so far is the per-page tile network cache in
lib.js; every request still drives the headless browser. This adds an opt-in cache of the rendered images, keyed by a stable hash of the render-affecting options, so a map used as<img src="...">is rendered once and then served from memory/disk.src/cache.js(new, no new dependencies)cacheKey(normalizedOptions)— sha256 of a stable-stringified whitelist of render-affecting options (geojson,geojsonfile,width,height, ...,type,quality).timeout,haltOnConsoleError,renderToHtmland unknown params don't influence the key.RenderCache({ max = 100, ttl = 3600, dir })— in-memory LRU bounded bymaxentries with a TTL in seconds; whendiris set, entries are also written as<dir>/<key>.binand read back on a memory miss (expiry by file mtime, lazily unlinked).max: 0+dir= disk-only.clear()only removes*.binfiles indir.src/lib.jsThe defaults block moved into
normalizeOptions()so the same normalization backs both rendering andcacheKey(also coerceswidth/height/maxZoom/qualityto numbers and defaultstypeto'png', so?width=800and nowidthshare an entry). In the render path: on a key hit the cached buffer is resolved before touching the browser; each of the threeresolve(...)image exits stores throughstore()(fire-and-forget, errors logged to stderr).renderToHtmloutput andgeojsonfile: '-'(stdin) are never cached. Cache is off unlessconfigureCacheis called — default behaviour unchanged.src/server.js— when a cache is active and the response is an image:Cache-Control: public, max-age=<ttl>,ETag: "<key>",304viareq.freshonIf-None-Match(no render),X-Cache: HIT|MISS.handlernow receivesreq.src/cli.js—osmsm serve --cache-max <n>(default0= off),--cache-ttl <seconds>(default3600),--cache-dir <path>; env fallbacksCACHE_MAX/CACHE_TTL/CACHE_DIR(matching the existing unprefixedPORT/HEADER_CHECKstyle). LogsRender cache enabled: ...at startup.Also:
src/cache.jsadded to thefileswhitelist,lib.d.ts(CacheOptions,RenderCache, new exports), README "Caching" section, CHANGELOG "Unreleased" entry.Out of scope / possible follow-ups: redis/memcache backends, a client-controlled
cache_force_refreshparam (would let any client bypass the cache), eager sweeping of expired files indir, bounding the disk size.Tests
test/cache.test.js— key stability/normalization/exclusions, LRU eviction, TTL expiry (fake timers),max: 0, directory persistence across instances, mtime-based disk expiry,clear/deleteon disk.test/render-cache.test.js— real browser: second identical render makes zero tile requests and returns an identical buffer; different options re-render;renderToHtmlnot cached; serverX-CacheMISS→HIT,ETag/Cache-Control,304on matchingIf-None-Match, no headers when disabled,/dynamicnever cached.npm test: 36 passed (4 files) on Node 24. Manualosmsm serve --cache-max 5 --cache-dir /tmp/osmsm-cache+ two curls: MISS then HIT,.binwritten, identical bytes.Link to Devin session: https://app.devin.ai/sessions/d2cb73fa9fb948da9625b7f61d0103d1
Open in Devin Desktop: https://app.devin.ai/desktop/session/d2cb73fa9fb948da9625b7f61d0103d1?variant=devin
Requested by: @jperelli