@@ -19,6 +19,7 @@ import SwiftExtensions
1919
2020import struct TSCBasic. AbsolutePath
2121import class TSCBasic. Process
22+ import struct TSCBasic. ProcessResult
2223
2324private let updateIndexStoreIDForLogging = AtomicUInt32 ( initialValue: 1 )
2425
@@ -114,6 +115,11 @@ public struct UpdateIndexStoreTaskDescription: IndexTaskDescription {
114115 /// See `SemanticIndexManager.logMessageToIndexLog`.
115116 private let logMessageToIndexLog : @Sendable ( _ taskID: IndexTaskID , _ message: String ) -> Void
116117
118+ /// How long to wait until we cancel an update indexstore task. This timeout should be long enough that all
119+ /// `swift-frontend` tasks finish within it. It prevents us from blocking the index if the type checker gets stuck on
120+ /// an expression for a long time.
121+ private let timeout : Duration
122+
117123 /// Test hooks that should be called when the index task finishes.
118124 private let testHooks : IndexTestHooks
119125
@@ -140,13 +146,15 @@ public struct UpdateIndexStoreTaskDescription: IndexTaskDescription {
140146 index: UncheckedIndex ,
141147 indexStoreUpToDateTracker: UpToDateTracker < DocumentURI > ,
142148 logMessageToIndexLog: @escaping @Sendable ( _ taskID: IndexTaskID , _ message: String ) -> Void ,
149+ timeout: Duration ,
143150 testHooks: IndexTestHooks
144151 ) {
145152 self . filesToIndex = filesToIndex
146153 self . buildSystemManager = buildSystemManager
147154 self . index = index
148155 self . indexStoreUpToDateTracker = indexStoreUpToDateTracker
149156 self . logMessageToIndexLog = logMessageToIndexLog
157+ self . timeout = timeout
150158 self . testHooks = testHooks
151159 }
152160
@@ -356,19 +364,21 @@ public struct UpdateIndexStoreTaskDescription: IndexTaskDescription {
356364 let stdoutHandler = PipeAsStringHandler { logMessageToIndexLog ( logID, $0) }
357365 let stderrHandler = PipeAsStringHandler { logMessageToIndexLog ( logID, $0) }
358366
359- // Time out updating of the index store after 2 minutes. We don't expect any single file compilation to take longer
360- // than 2 minutes in practice, so this indicates that the compiler has entered a loop and we probably won't make any
361- // progress here. We will try indexing the file again when it is edited or when the project is re-opened.
362- // 2 minutes have been chosen arbitrarily.
363- let result = try await withTimeout ( . seconds( 120 ) ) {
364- try await Process . run (
365- arguments: processArguments,
366- workingDirectory: workingDirectory,
367- outputRedirection: . stream(
368- stdout: { stdoutHandler. handleDataFromPipe ( Data ( $0) ) } ,
369- stderr: { stderrHandler. handleDataFromPipe ( Data ( $0) ) }
367+ let result : ProcessResult
368+ do {
369+ result = try await withTimeout ( timeout) {
370+ try await Process . run (
371+ arguments: processArguments,
372+ workingDirectory: workingDirectory,
373+ outputRedirection: . stream(
374+ stdout: { stdoutHandler. handleDataFromPipe ( Data ( $0) ) } ,
375+ stderr: { stderrHandler. handleDataFromPipe ( Data ( $0) ) }
376+ )
370377 )
371- )
378+ }
379+ } catch {
380+ logMessageToIndexLog ( logID, " Finished error in \( start. duration ( to: . now) ) : \( error) " )
381+ throw error
372382 }
373383 let exitStatus = result. exitStatus. exhaustivelySwitchable
374384 logMessageToIndexLog ( logID, " Finished with \( exitStatus. description) in \( start. duration ( to: . now) ) " )
0 commit comments