Skip to content

Detect re-entrant self-cycle via direct pod reference (issue #5) + v1.1.3#7

Merged
robert-northmind merged 2 commits into
mainfrom
fix/reentrant-self-cycle-detection
Mar 31, 2026
Merged

Detect re-entrant self-cycle via direct pod reference (issue #5) + v1.1.3#7
robert-northmind merged 2 commits into
mainfrom
fix/reentrant-self-cycle-detection

Conversation

@robert-northmind

Copy link
Copy Markdown
Owner

$(cat <<'EOF'

Summary

Closes #5.

  • Self-cycle detection: a provider whose builder calls pod.resolve() on itself via a direct pod reference is now detected as a cyclic dependency and reported via cyclicDependencyHandler, instead of causing infinite recursion and a stack overflow.
  • How: InternalProviderResolver now accepts optional onBuildStart/onBuildEnd callbacks that fire around every provider.build(...) call. SwiftiePod maintains a Set<ObjectIdentifier> (currentlyBuildingProviders) via these callbacks, and checks it in the re-entrant fast-path before proceeding.
  • Version bump: 1.1.21.1.3 (podspec + CHANGELOG).

Performance impact

Negligible — the callbacks only fire on cache misses. Singleton providers pay the cost once ever; AlwaysCreateNewScope providers pay two closure calls + two O(1) Set operations per resolve, which is dwarfed by the builder execution and dispatchQueue.sync overhead.

Test plan

  • testReentrantSelfCycleIsDetected — new test in ReentrantResolveTests: verifies that a self-referential re-entrant provider triggers cyclicDependencyHandler with the expected message
  • All existing tests continue to pass (callbacks default to nil, so no existing behaviour changes)
  • CI: swift test, ExampleApp build, iOS simulator build + tests
    EOF
    )

claude added 2 commits March 31, 2026 19:40
When a provider's builder calls pod.resolve() on itself (via a captured
global pod reference), the fix from issue #4 prevented a deadlock but
left an infinite recursion / stack overflow unhandled.

Fix: track which providers have an actively-running builder in a
Set<ObjectIdentifier> on SwiftiePod (currentlyBuildingProviders). This
set is maintained via onBuildStart/onBuildEnd callbacks threaded through
InternalProviderResolver and called around every provider.build() call.
The re-entrant fast-path in SwiftiePod.resolve checks this set and
calls cyclicDependencyHandler if the same provider is already building.

Adds testReentrantSelfCycleIsDetected to ReentrantResolveTests,
following the same thread-blocking pattern used by the existing
cyclic dependency test.

https://claude.ai/code/session_017ztecAXmWm6cLm5rmPuAX2
@robert-northmind
robert-northmind merged commit 9dd4fba into main Mar 31, 2026
2 checks passed
@robert-northmind
robert-northmind deleted the fix/reentrant-self-cycle-detection branch March 31, 2026 19:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Detect re-entrant self-cycle via direct pod reference

2 participants