Skip to content

Resolution caches are process-wide but depend on the per-thread context #33

Closed

Description

@trissim

All line numbers are at main 1fcdf12.

Problem

Two caches hold answers that depend on the active context but are owned by the module, not by the context:

  • _mro_resolution_cache in dual_axis_resolver.py:20
  • the extract_all_configs cache in context_manager.py

Consequences:

  1. config_context clears both on every entry and every exit (context_manager.py:241-243, :251-252). The context is per thread or task; the caches are process-wide. One thread entering a scope empties the cache another thread is using. Nested contexts clear it at every level, so inside a deep stack the cache is rebuilt repeatedly.
  2. The cache key uses id(config_instance) (dual_axis_resolver.py:162). An id is only unique while the object is alive. Correctness depends on every path that can drop a config instance also clearing the cache; invalidate_mro_cache_for_field removes entries by type and field name only.

Wanted

The cached answers belong to the context value they were computed from: stored on, or keyed by, the merged config object itself, so they disappear with it and no clear call is needed on entry or exit. Keys hold the object (or a weak reference), not its id.

Acceptance

config_context contains no cache-clearing calls. A test resolves a field in one thread, enters and exits a context in a second thread, and shows the first thread's cached entry is still used. No cache key contains id(...).

Activity

  1. trissim commented on Oct 12, 2026

    @trissim
    ContributorAuthor

    Fixed in 3.0.0 (#50, built on #49). Resolution answers now live on the context layer stack they were computed from; both process-wide caches are gone, config_context clears nothing, and no cache key contains id(...) (the third id-keyed cache, in live_context_resolver.py, was removed in the same release). The thread test from the acceptance section is in the suite.

    🤖 Generated with Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions