Remove the queue parameter from Connection.send

We don’t actually care about the queue that we receive the reply on anymore since we migrated everything™ to actors/async/await.
This commit is contained in:
Alex Hoppen
2023-10-06 07:11:59 -07:00
parent 203d585b77
commit 4495256b35
6 changed files with 21 additions and 41 deletions

View File

@@ -88,7 +88,6 @@ public final class TestClient: MessageHandler {
self.server = server
}
public var replyQueue: DispatchQueue = DispatchQueue(label: "testclient-reply-queue")
var oneShotNotificationHandlers: [((Any) -> Void)] = []
var oneShotRequestHandlers: [((Any) -> Void)] = []
@@ -157,13 +156,8 @@ extension TestClient: Connection {
}
/// Send a request to the language server and (asynchronously) receive a reply.
public func send<Request>(_ request: Request, queue: DispatchQueue, reply: @escaping (LSPResult<Request.Response>) -> Void) -> RequestID where Request: RequestType {
return server.send(request, queue: queue, reply: reply)
}
/// Convenience method to get reply on replyQueue.
public func send<Request>(_ request: Request, reply: @escaping (LSPResult<Request.Response>) -> Void) -> RequestID where Request: RequestType {
return send(request, queue: replyQueue, reply: reply)
return server.send(request, reply: reply)
}

View File

@@ -19,7 +19,7 @@ public protocol Connection: AnyObject {
func send<Notification>(_: Notification) where Notification: NotificationType
/// Send a request and (asynchronously) receive a reply.
func send<Request>(_: Request, queue: DispatchQueue, reply: @escaping (LSPResult<Request.Response>) -> Void) -> RequestID where Request: RequestType
func send<Request>(_: Request, reply: @escaping (LSPResult<Request.Response>) -> Void) -> RequestID where Request: RequestType
/// Send a request synchronously. **Use wisely**.
func sendSync<Request>(_: Request) throws -> Request.Response where Request: RequestType
@@ -29,7 +29,7 @@ extension Connection {
public func sendSync<Request>(_ request: Request) throws -> Request.Response where Request: RequestType {
var result: LSPResult<Request.Response>? = nil
let semaphore = DispatchSemaphore(value: 0)
_ = send(request, queue: DispatchQueue.global()) { _result in
_ = send(request) { _result in
result = _result
semaphore.signal()
}
@@ -119,23 +119,18 @@ extension LocalConnection: Connection {
public func send<Request: RequestType>(
_ request: Request,
queue: DispatchQueue,
reply: @escaping (LSPResult<Request.Response>) -> Void
) -> RequestID {
let id = nextRequestID()
guard let handler = self.handler else {
queue.async {
reply(.failure(.serverCancelled))
}
reply(.failure(.serverCancelled))
return id
}
precondition(self.state == .started)
handler.handle(request, id: id, from: ObjectIdentifier(self)) { result in
queue.async {
reply(result)
}
reply(result)
}
return id

View File

@@ -408,7 +408,7 @@ extension JSONRPCConnection: Connection {
}
}
public func send<Request>(_ request: Request, queue: DispatchQueue, reply: @escaping (LSPResult<Request.Response>) -> Void) -> RequestID where Request: RequestType {
public func send<Request>(_ request: Request, reply: @escaping (LSPResult<Request.Response>) -> Void) -> RequestID where Request: RequestType {
let id: RequestID = self.queue.sync {
let id = nextRequestID()
@@ -423,10 +423,9 @@ extension JSONRPCConnection: Connection {
responseType: Request.Response.self,
queue: queue,
replyHandler: { anyResult in
queue.async {
reply(anyResult.map { $0 as! Request.Response })
}
})
reply(anyResult.map { $0 as! Request.Response })
}
)
return id
}

View File

@@ -119,13 +119,13 @@ public actor BuildServerBuildSystem: MessageHandler {
deinit {
if let buildServer = self.buildServer {
_ = buildServer.send(ShutdownBuild(), queue: DispatchQueue.global(), reply: { result in
_ = buildServer.send(ShutdownBuild()) { result in
if let error = result.failure {
log("error shutting down build server: \(error)")
}
buildServer.send(ExitBuildNotification())
buildServer.close()
})
}
}
}
@@ -239,7 +239,7 @@ extension BuildServerBuildSystem: BuildSystem {
public func registerForChangeNotifications(for uri: DocumentURI, language: Language) {
let request = RegisterForChanges(uri: uri, action: .register)
_ = self.buildServer?.send(request, queue: requestQueue, reply: { result in
_ = self.buildServer?.send(request) { result in
Task {
if let error = result.failure {
log("error registering \(uri): \(error)", level: .error)
@@ -249,18 +249,18 @@ extension BuildServerBuildSystem: BuildSystem {
await self.buildSettingsChanged(for: uri, settings: nil)
}
}
})
}
}
/// Unregister the given file for build-system level change notifications, such as command
/// line flag changes, dependency changes, etc.
public func unregisterForChangeNotifications(for uri: DocumentURI) {
let request = RegisterForChanges(uri: uri, action: .unregister)
_ = self.buildServer?.send(request, queue: requestQueue, reply: { result in
_ = self.buildServer?.send(request) { result in
if let error = result.failure {
log("error unregistering \(uri): \(error)", level: .error)
}
})
}
}
public func filesDidChange(_ events: [FileEvent]) {}

View File

@@ -41,10 +41,6 @@ extension NSLock {
/// requests and notifications **from** clangd, not from the editor, and it will
/// forward these requests and notifications to the editor.
actor ClangLanguageServerShim: ToolchainLanguageServer, MessageHandler {
// FIXME: (async) Remove once `Connection.send` has been asyncified.
/// The queue on which clangd calls us back.
public let clangdCommunicationQueue: DispatchQueue = DispatchQueue(label: "language-server-queue", qos: .userInitiated)
/// The queue on which all messages that originate from clangd are handled.
///
/// These are requests and notifications sent *from* clangd, not replies from
@@ -314,7 +310,7 @@ actor ClangLanguageServerShim: ToolchainLanguageServer, MessageHandler {
/// The cancellation token from the original request is automatically linked to the forwarded
/// request such that cancelling the original request will cancel the forwarded request.
func forwardRequestToClangd<R>(_ request: Request<R>) {
let id = clangd.send(request.params, queue: clangdCommunicationQueue) { result in
let id = clangd.send(request.params) { result in
request.reply(result)
}
request.cancellationToken.addCancellationHandler {
@@ -331,7 +327,7 @@ actor ClangLanguageServerShim: ToolchainLanguageServer, MessageHandler {
/// The response of the request is returned asynchronously as the return value.
func forwardRequestToClangd<R: RequestType>(_ request: R) async throws -> R.Response {
try await withCheckedThrowingContinuation { continuation in
_ = clangd.send(request, queue: clangdCommunicationQueue) { result in
_ = clangd.send(request) { result in
switch result {
case .success(let response):
continuation.resume(returning: response)
@@ -423,7 +419,7 @@ extension ClangLanguageServerShim {
public func shutdown() async {
await withCheckedContinuation { continuation in
_ = clangd.send(ShutdownRequest(), queue: self.clangdCommunicationQueue) { [weak self] _ in
_ = clangd.send(ShutdownRequest()) { [weak self] _ in
guard let self else { return }
Task {
await self.clangd.send(ExitNotification())

View File

@@ -96,7 +96,7 @@ final actor WorkDoneProgressState {
if state == .noProgress {
state = .creating
// Discard the handle. We don't support cancellation of the creation of a work done progress.
_ = server.client.send(CreateWorkDoneProgressRequest(token: token), queue: server.clientCommunicationQueue) { result in
_ = server.client.send(CreateWorkDoneProgressRequest(token: token)) { result in
if result.success != nil {
if self.activeTasks == 0 {
// ActiveTasks might have been decreased while we created the `WorkDoneProgress`
@@ -133,10 +133,6 @@ final actor WorkDoneProgressState {
/// and cross-language support. Requests may be dispatched to language-specific services or handled
/// centrally, but this is transparent to the client.
public actor SourceKitServer {
// FIXME: (async) We can remove this if we migrate client.send to be async and it thus doesn't take a queue anymore.
/// The queue on which we communicate with the client.
public let clientCommunicationQueue: DispatchQueue = DispatchQueue(label: "language-server-queue", qos: .userInitiated)
/// The queue on which all messages (notifications, requests, responses) are
/// handled.
///
@@ -280,7 +276,7 @@ public actor SourceKitServer {
/// Send the given request to the editor.
public func sendRequestToClient<R: RequestType>(_ request: R) async throws -> R.Response {
try await withCheckedThrowingContinuation { continuation in
_ = client.send(request, queue: clientCommunicationQueue) { result in
_ = client.send(request) { result in
continuation.resume(with: result)
}
// FIXME: (async) Handle cancellation
@@ -902,7 +898,7 @@ extension SourceKitServer {
_ registry: CapabilityRegistry
) {
let req = RegisterCapabilityRequest(registrations: [registration])
let _ = client.send(req, queue: clientCommunicationQueue) { result in
let _ = client.send(req) { result in
if let error = result.failure {
log("Failed to dynamically register for \(registration.method): \(error)", level: .error)
registry.remove(registration: registration)