Skip to content

Close path: concurrent close_async finalizes twice, and three untested guarantees #616

Closed

Description

@lesnik512

This was generated by AI during a third pre-4.0 audit of main at f6e343d.

One bug and three untested guarantees in the close path. Mutation testing changed each of items 2 to 4 in the code and all 989 tests still passed. TDD for each.

  1. Concurrent close_async() finalizes twice. Repro:
    async def fin(r: R) -> None:
        log.append("start"); await asyncio.sleep(0.01); log.append("end")
    class G(Group):
        r = Factory(R, cache=CacheSettings(finalizer=fin))
    c = Container(groups=[G]); c.resolve(R)
    await asyncio.gather(c.close_async(), c.close_async())
    # log == ['start', 'start', 'end', 'end']
    Fix: detach the creation order before the first await (or mark items finalized before awaiting), and state in design-decisions whether concurrent close is supported.
  2. Finalizer ownership. resolver_compiler.py:120 appends to target._creation_order. Changing it to container._creation_order passes the suite, yet then an APP singleton first resolved from a REQUEST child is finalized when the child closes and rebuilt afterwards, contradicting docs/providers/lifecycle.md:191. Test: resolve an APP item with a finalizer through a child, close the child, assert the finalizer did not run and the singleton is the same object.
  3. Order of leftover async finalizers. Removing remaining.reverse() in cache.py close_sync passes the suite. Test: two async finalizers, sync close, then async close, assert newest first.
  4. No double finalize on the async path. Removing cache_item.finalized = True in cache.py close_async passes the suite; test_cached_factory.py:69 covers only sync. Test the clear_cache=False case: close_async, reopen, close_async again.
  5. Small: test_cache.py:114 races threads without the thread_race marker, so the free-threaded stress run skips it. Make just test-race select -m thread_race over the whole suite instead of listing files.

Activity

  1. added this to the 4.0 milestone on Oct 7, 2026
  2. added
    bugSomething isn't working
    ready-for-agentFully specified, ready for an AFK agent
    on Oct 7, 2026
  3. lesnik512 commented on Oct 9, 2026

    @lesnik512
    MemberAuthor

    This was generated by AI.

    Item 1 is won't-fix: closing one container concurrently is a usage error, now documented as unsupported in design-decisions. Items 2 to 5 shipped in #621.

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

    bugSomething isn't workingready-for-agentFully specified, ready for an AFK agent

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions