Skip to content

SemanticIndex | Add deterministic IndexStoreDB cleanup on shutdown#2503

Draft
sean7218 wants to merge 3 commits into
swiftlang:mainfrom
sean7218:sean7218/indexStoreDB-closing-api
Draft

SemanticIndex | Add deterministic IndexStoreDB cleanup on shutdown#2503
sean7218 wants to merge 3 commits into
swiftlang:mainfrom
sean7218:sean7218/indexStoreDB-closing-api

Conversation

@sean7218
Copy link
Copy Markdown

Summary

Refactors UncheckedIndex to wrap IndexStoreDB in a ThreadSafeBox, enabling explicit lifecycle management. A new close() method sets the underlying instance to nil, triggering deterministic deinitialization rather than relying on ARC-driven deallocation.

Introduces a close() method on the MainFilesProvider protocol (with a default no-op) so BuildServerManager can tear down the index store without a circular dependency on SemanticIndex.
Calls mainFilesProvider.close() as the first step of BuildServerManager.shutdown(), ensuring the IndexStoreDB is released before the build server connection is torn down.

Motivation

Previously, the IndexStoreDB instance was only released when UncheckedIndex was deallocated, which depends on ARC timing and can lead to non-deterministic resource cleanup. In test scenarios this caused race conditions where the connection could be reported as a leak. This change gives the shutdown path explicit control over when the index store is closed.

Changes

  • CheckedIndex.swift — UncheckedIndex.underlyingIndexStoreDB is now a computed property backed by a ThreadSafeBox. Added close() to nil out the stored instance. Accessing the index after close triggers a preconditionFailure.

  • MainFilesProvider.swift — Added func close() async to the protocol with a default empty implementation.
    BuildServerManager.swift — shutdown() now calls await self.mainFilesProvider?.value?.close() before proceeding with build server teardown.

- Introduced UncheckedSendableOptionalIndexStoreDB to safely wrap IndexStoreDB in a thread-safe manner.
- Updated underlyingIndexStoreDB to utilize ThreadSafeBox, allowing for explicit closure and deinitialization of IndexStoreDB.
- Added a close() method to release the IndexStoreDB instance immediately.
…closure in BuildServerManager shutdown

- Added a close() method to the MainFilesProvider protocol to release underlying resources.
- Updated the shutdown method in BuildServerManager to explicitly close the index store before shutting down the build server.
- Updated Package.swift to include ToolchainRegistry and IndexStoreDB as dependencies.
- Added a new test in TaskSchedulerTests to verify the closing behavior of IndexStoreDB, ensuring proper resource management during asynchronous operations.
@ahoppen
Copy link
Copy Markdown
Member

ahoppen commented Feb 28, 2026

Maybe I missed something but does this contain anything that’s not also covered by #2483? I think the problem that #2455 (comment) mentioned was that if SourceKit-LSP is not idle, there may still be lingering references to the IndexStoreDB object, so really what we need is a proper close method inside the indexstore-db repository instead of relying on ref-counting there.

@sean7218
Copy link
Copy Markdown
Author

You are absolutely right! 😅 I misunderstood the problem. Let me fix it on the upstream side

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.

2 participants