Repository navigation
perf(gemini): replace disk-backed Files-API cache with thread-safe in-memory cache - #4154
Open
hpiclaranet wants to merge 1 commit into
Open
hpiclaranet wants to merge 1 commit into
hpiclaranet wants to merge 1 commit into
Conversation
This branch has not been deployed
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
Rebased onto current main (
b4df0da3, gemini 0.9.12) and bumped to 0.9.13, superseding the closed #3759 (closed by the maintainer due to merge conflicts; rebase + bump + new PR requested).Scope note: the previous #3759 bundled four performance changes. Since then, the main has merged the Gemini 4 Argon support (#4055), which reworked usage/streaming handling in the same files. Rebasing the old diff wholesale would have regressed that Argon behaviour, so this re-submission is scoped to the single change that is still missing from main and does not touch the Argon paths: replacing the disk-backed Files-API cache with a thread-safe in-memory cache. The remaining #3759 items (the
genai.Clientconnection-pool reuse and local token counting in the embedding splitter) are deliberately left out and tracked as follow-ups.What this PR does
models/gemini/models/llm/utils.py—FileCacheis now an in-memory, thread-safe cache (with lazy expiry-based eviction and a hard cap on live entries) instead of a disk-backed JSON file that was re-read and re-written on everyexists/get/setexcall with no locking (concurrent workers could lose updates or corrupt the file).Trade-offs (documented in code):
Release Notes
Change Type
Screenshots / Videos
Not applicable — no user-facing behaviour change (internal cache storage only; identical model outputs).
LLM Plugin Checklist
Areas affected by this change (check all that apply)
Version
versioninmanifest.yaml(not the one undermeta) — 0.9.12 → 0.9.13 (0.9.11/0.9.12 taken by feat(gemini): add Gemini 4 Argon support #4055/fix(deps): refresh security dependencies for 50 model plugins #4106)dify-plugin>=0.10.2,<0.11.0is declared inpyproject.tomland locked inuv.lock(satisfies the required>=0.3.0,<0.11.0range; dependencies unchanged from main)Testing
uvvenv matchingmanifest.yaml,pyproject.toml, anduv.lock(no Dify platform instance in this run; validation was the plugin suite in that venv): full gemini suite passes on the rebased head (mainb4df0da3) — 256 passed, 40 deselected (live-API tests, noGEMINI_API_KEYset; includes the Gemini 4 Argon tests from feat(gemini): add Gemini 4 Argon support #4055). Newmodels/tests/test_perf_caches.pycovers the in-memory cache: setex/get/expiry, 8-thread × 200-key concurrent writes with zero lost updates, eviction purging expired entries only, concurrent reads during writes, signature backwards compatibility, and the hard cap on live entries.ruff checkreports zero findings on the changed files.Known limitations:
exists()→get()sequence around the cache infile_parts.pyis not atomic — if an entry expires in that window,get()returnsNoneand the code can raiseAttributeError; this predates this PR and is unchanged by it.