Skip to content

Commit 2a877ee

Browse files
authored
Merge pull request #269 from hamishknight/timedout
Merge `timedOut` with `softTimeout`
2 parents 9ab2a70 + cd0ff83 commit 2a877ee

File tree

3 files changed

+16
-65
lines changed

3 files changed

+16
-65
lines changed

SourceKitStressTester/Sources/Common/Message.swift

Lines changed: 11 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,6 @@ public struct SourceKitResponseData: Codable {
3939
public enum SourceKitError: Error {
4040
case crashed(request: RequestInfo)
4141
case timedOut(request: RequestInfo)
42-
/// Thrown if a request was close to the time out that triggers a timedOut
43-
/// error.
44-
/// If it was counted how many instructions SourceKit took to fulfill the
45-
/// request, `instructions` contains that number. Otherwise it's `nil`.
46-
case softTimeout(request: RequestInfo, duration: TimeInterval, instructions: Int?)
4742
case failed(_ reason: SourceKitErrorReason, request: RequestInfo, response: String)
4843

4944
public var request: RequestInfo {
@@ -52,25 +47,26 @@ public enum SourceKitError: Error {
5247
return request
5348
case .timedOut(let request):
5449
return request
55-
case .softTimeout(let request, _, _):
56-
return request
5750
case .failed(_, let request, _):
5851
return request
5952
}
6053
}
6154

6255
/// Soft errors are allowed to match XFails, but don't fail the stress tester
6356
/// on their own.
64-
/// The current use case for soft errors are soft timeouts, where the request
65-
/// took more than half of the allowed time. If the issue is XFailed, we don't
66-
/// want to mark it as unexpectedly passed because the faster execution time
67-
/// might be due to noise. But we haven't surpassed the limit either, so it
68-
/// shouldn't be a hard error either.
57+
///
58+
/// The current use case for soft errors are timeouts, since it's possible
59+
/// that it hits a failure on a faster run, which can lead to non-determinism
60+
/// in matching XFAILs.
61+
///
62+
/// Timouts aren't considered errors on their own since they would be a major
63+
/// cause of stress tester failures, producing noise. We instead use
64+
/// instruction count measurements to keep track of performance.
6965
public var isSoft: Bool {
7066
switch self {
71-
case .crashed, .timedOut, .failed:
67+
case .crashed, .failed:
7268
return false
73-
case .softTimeout:
69+
case .timedOut:
7470
return true
7571
}
7672
}
@@ -210,7 +206,7 @@ extension SourceKitError: Codable {
210206
case error, kind, request, response, duration, instructions
211207
}
212208
enum BaseError: String, Codable {
213-
case crashed, failed, timedOut, softTimeout
209+
case crashed, failed, timedOut
214210
}
215211

216212
public init(from decoder: Decoder) throws {
@@ -222,11 +218,6 @@ extension SourceKitError: Codable {
222218
case .timedOut:
223219
let request = try container.decode(RequestInfo.self, forKey: .request)
224220
self = .timedOut(request: request)
225-
case .softTimeout:
226-
let request = try container.decode(RequestInfo.self, forKey: .request)
227-
let duration = try container.decode(Double.self, forKey: .duration)
228-
let instructions = try container.decodeIfPresent(Int.self, forKey: .instructions)
229-
self = .softTimeout(request: request, duration: duration, instructions: instructions)
230221
case .failed:
231222
let reason = try container.decode(SourceKitErrorReason.self, forKey: .kind)
232223
let request = try container.decode(RequestInfo.self, forKey: .request)
@@ -244,11 +235,6 @@ extension SourceKitError: Codable {
244235
case .timedOut(let request):
245236
try container.encode(BaseError.timedOut, forKey: .error)
246237
try container.encode(request, forKey: .request)
247-
case .softTimeout(let request, let duration, let instructions):
248-
try container.encode(BaseError.softTimeout, forKey: .error)
249-
try container.encode(request, forKey: .request)
250-
try container.encode(duration, forKey: .duration)
251-
try container.encodeIfPresent(instructions, forKey: .instructions)
252238
case .failed(let kind, let request, let response):
253239
try container.encode(BaseError.failed, forKey: .error)
254240
try container.encode(kind, forKey: .kind)
@@ -537,14 +523,6 @@ extension SourceKitError: CustomStringConvertible {
537523
\(markSourceLocation(of: request) ?? "<unmodified>")
538524
-- end file content ----------
539525
"""
540-
case .softTimeout(let request, let duration, let instructions):
541-
return """
542-
Request took \(duration) seconds (\(instructions.map(String.init) ?? "<unknown>") instructions) to execute. This is more than a tenth of the allowed time. This error will match XFails but won't count as an error by itself.
543-
request: \(request)
544-
-- begin file content --------
545-
\(markSourceLocation(of: request) ?? "<unmodified>")
546-
-- end file content ----------
547-
"""
548526
case .failed(let reason, let request, let response):
549527
return """
550528
\(reason)

SourceKitStressTester/Sources/StressTester/SourceKitDocument.swift

Lines changed: 4 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -492,26 +492,17 @@ class SourceKitDocument {
492492
}
493493
}
494494

495-
do {
496-
let response = try sendWithTimeout(request, info: info, validateResponse: validateResponse)
497-
return (response, try getInstructionCount())
498-
} catch SourceKitError.softTimeout(request: let request, duration: let duration, instructions: _) {
499-
throw SourceKitError.softTimeout(request: request, duration: duration, instructions: try getInstructionCount())
500-
} catch {
501-
throw error
502-
}
495+
let response = try sendWithTimeout(request, info: info, validateResponse: validateResponse)
496+
return (response, try getInstructionCount())
503497
}
504498

505499
/// Send the `request` synchronously, timing out after
506500
/// `SOURCEKIT_REQUEST_TIMEOUT`.
507501
/// An error is thrown if either the response is invalid (see `throwIfInvalid`)
508-
/// or `validateResponse` throws. If the request took longer than half the
509-
/// time allowed but no other error is thrown, a `SourceKitError.softTimeout`
510-
/// will be thrown.
502+
/// or `validateResponse` throws.
511503
private func sendWithTimeout(_ request: SourceKitdRequest, info: RequestInfo, validateResponse: (SourceKitdResponse) throws -> Void = { _ in }, reopenDocumentIfNeeded: Bool = true) throws -> SourceKitdResponse {
512504
var response: SourceKitdResponse? = nil
513505
let completed = DispatchSemaphore(value: 0)
514-
let startDate = Date()
515506
connection.send(request: request) {
516507
response = $0
517508
completed.signal()
@@ -523,23 +514,14 @@ class SourceKitDocument {
523514
fatalError("nil response without timout being hit?")
524515
}
525516

526-
let requestDuration = Date().timeIntervalSince(startDate)
527-
528517
if response.isError, response.description.contains("No associated Editor Document"), reopenDocumentIfNeeded {
529518
_ = try self.openOrUpdate(source: sourceState?.source)
530519
return try sendWithTimeout(request, info: info, validateResponse: validateResponse, reopenDocumentIfNeeded: false)
531520
} else {
532521
// Check if there was an error in the response
533522
try throwIfInvalid(response, request: info)
534523
try validateResponse(response)
535-
536-
if requestDuration > TimeInterval(SOURCEKIT_REQUEST_TIMEOUT) / 10 {
537-
// There was no error in the response, but the request took too long
538-
// throw a soft timeout.
539-
throw SourceKitError.softTimeout(request: info, duration: requestDuration, instructions: nil)
540-
} else {
541-
return response
542-
}
524+
return response
543525
}
544526
case .timedOut:
545527
/// We timed out waiting for the response. Any following requests would

SourceKitStressTester/Sources/StressTester/StressTester.swift

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -126,16 +126,7 @@ public class StressTester {
126126
try report(document.moduleInterfaceGen())
127127
}
128128
} catch {
129-
if case SourceKitError.softTimeout(request: let request, duration: _, instructions: let .some(instructions)) = error {
130-
reportPerformanceMeasurement(request: request, instructions: instructions, reusingASTContext: nil)
131-
}
132-
if case SourceKitError.timedOut = error {
133-
// Ignore timeout errors. In practice, we have always just added the timeouts to the XFails and keeping track
134-
// of these timeouts is the major cause of stress tester failures, producing noise.
135-
// We use instruction count measurements to keep track of performance.
136-
} else {
137-
errors.append(error)
138-
}
129+
errors.append(error)
139130
}
140131
}
141132

0 commit comments

Comments
 (0)