Skip to content

Commit 6c03a20

Browse files
committed
Fix that the request may timeout too soon
1 parent b2bcfc7 commit 6c03a20

2 files changed

Lines changed: 42 additions & 19 deletions

File tree

Tool/Sources/GitHubCopilotService/LanguageServer/GitHubCopilotService.swift

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,21 +37,33 @@ public protocol GitHubCopilotSuggestionServiceType {
3737
}
3838

3939
protocol GitHubCopilotLSP {
40-
func sendRequest<E: GitHubCopilotRequestType>(_ endpoint: E) async throws -> E.Response
40+
func sendRequest<E: GitHubCopilotRequestType>(
41+
_ endpoint: E,
42+
timeout: TimeInterval?
43+
) async throws -> E.Response
4144
func sendNotification(_ notif: ClientNotification) async throws
4245
}
4346

47+
extension GitHubCopilotLSP {
48+
func sendRequest<E: GitHubCopilotRequestType>(_ endpoint: E) async throws -> E.Response {
49+
try await sendRequest(endpoint, timeout: nil)
50+
}
51+
}
52+
4453
enum GitHubCopilotError: Error, LocalizedError {
4554
case languageServerNotInstalled
4655
case languageServerError(ServerError)
4756
case failedToInstallStartScript
57+
case chatEndsWithError(String)
4858

4959
var errorDescription: String? {
5060
switch self {
5161
case .languageServerNotInstalled:
5262
return "Language server is not installed."
5363
case .failedToInstallStartScript:
5464
return "Failed to install start script."
65+
case let .chatEndsWithError(errorMessage):
66+
return "Chat ended with error message: \(errorMessage)"
5567
case let .languageServerError(error):
5668
switch error {
5769
case let .handlerUnavailable(handler):
@@ -578,8 +590,19 @@ public final class GitHubCopilotService: GitHubCopilotBaseService,
578590
}
579591

580592
extension InitializingServer: GitHubCopilotLSP {
581-
func sendRequest<E: GitHubCopilotRequestType>(_ endpoint: E) async throws -> E.Response {
582-
try await sendRequest(endpoint.request)
593+
func sendRequest<E: GitHubCopilotRequestType>(
594+
_ endpoint: E,
595+
timeout: TimeInterval? = nil
596+
) async throws -> E.Response {
597+
if let timeout {
598+
return try await withCheckedThrowingContinuation { continuation in
599+
self.sendRequest(endpoint.request, timeout: timeout) { result in
600+
continuation.resume(with: result)
601+
}
602+
}
603+
} else {
604+
return try await sendRequest(endpoint.request)
605+
}
583606
}
584607
}
585608

Tool/Sources/GitHubCopilotService/Services/GitHubCopilotChatService.swift

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,13 @@ public final class GitHubCopilotChatService: BuiltinExtensionChatServiceType {
4545
workspaceFolder: workspace.projectURL.path
4646
))
4747

48-
var cont: AsyncThrowingStream<String, Error>.Continuation? = nil
4948
let stream = AsyncThrowingStream<String, Error> { continuation in
50-
cont = continuation
5149
let startTimestamp = Date()
5250

51+
continuation.onTermination = { _ in
52+
Task { service.unregisterNotificationHandler(id: id) }
53+
}
54+
5355
service.registerNotificationHandler(id: id) { notification, data in
5456
// just incase the conversation is stuck, we will cancel it after timeout
5557
if Date().timeIntervalSince(startTimestamp) > 60 * 30 {
@@ -71,11 +73,9 @@ public final class GitHubCopilotChatService: BuiltinExtensionChatServiceType {
7173
if let error = progress.value.error,
7274
progress.value.cancellationReason == nil
7375
{
74-
continuation.finish(throwing: ServerError.serverError(
75-
code: 0,
76-
message: error,
77-
data: nil
78-
))
76+
continuation.finish(
77+
throwing: GitHubCopilotError.chatEndsWithError(error)
78+
)
7979
} else {
8080
continuation.finish()
8181
}
@@ -99,22 +99,22 @@ public final class GitHubCopilotChatService: BuiltinExtensionChatServiceType {
9999
return false
100100
}
101101
}
102-
}
103102

104-
do {
105-
let createResponse = try await service.server.sendRequest(request)
106-
cont?.onTermination = { _ in
107-
Task {
108-
service.unregisterNotificationHandler(id: id)
103+
Task {
104+
do {
105+
// this will return when the response is generated.
106+
let createResponse = try await service.server.sendRequest(request, timeout: 120)
109107
_ = try await service.server.sendRequest(
110108
GitHubCopilotRequest.ConversationDestroy(requestBody: .init(
111109
conversationId: createResponse.conversationId
112110
))
113111
)
112+
} catch let error as ServerError {
113+
continuation.finish(throwing: GitHubCopilotError.languageServerError(error))
114+
} catch {
115+
continuation.finish(throwing: error)
114116
}
115117
}
116-
} catch {
117-
cont?.finish(throwing: error)
118118
}
119119

120120
return stream
@@ -168,7 +168,7 @@ extension GitHubCopilotChatService {
168168
func createNewMessage(references: [RetrievedContent], message: String) -> String {
169169
return message
170170
}
171-
171+
172172
struct JSONRPC<Params: Decodable>: Decodable {
173173
var jsonrpc: String
174174
var method: String

0 commit comments

Comments
 (0)