[jsonrpc] Move close handler to start

Since the connection and message handler have a reciprocal need to know
about each other, move the closeHandler so that it has the opportunity
to call a method on the message handler if desired.
This commit is contained in:
Ben Langmuir
2019-11-20 08:56:54 -08:00
parent 6c66f8021c
commit dfe2a6bc76
3 changed files with 13 additions and 16 deletions

View File

@@ -52,17 +52,15 @@ public final class JSONRPCConection {
/// The set of currently outstanding outgoing requests along with information about how to decode and handle their responses.
var outstandingRequests: [RequestID: OutstandingRequest] = [:]
var closeHandler: () -> Void
var closeHandler: (() -> Void)! = nil
public init(
protocol messageRegistry: MessageRegistry,
inFD: Int32,
outFD: Int32,
syncRequests: Bool = false,
closeHandler: @escaping () -> Void = {})
syncRequests: Bool = false)
{
state = .created
self.closeHandler = closeHandler
self.messageRegistry = messageRegistry
self.syncRequests = syncRequests
@@ -93,10 +91,11 @@ public final class JSONRPCConection {
/// Start processing `inFD` and send messages to `receiveHandler`.
///
/// - parameter receiveHandler: The message handler to invoke for requests received on the `inFD`.
public func start(receiveHandler: MessageHandler) {
public func start(receiveHandler: MessageHandler, closeHandler: @escaping () -> Void = {}) {
precondition(state == .created)
state = .running
self.receiveHandler = receiveHandler
self.closeHandler = closeHandler
receiveIO.read(offset: 0, length: Int.max, queue: queue) { done, data, errorCode in
guard errorCode == 0 else {

View File

@@ -102,10 +102,7 @@ let clientConnection = JSONRPCConection(
protocol: MessageRegistry.lspProtocol,
inFD: STDIN_FILENO,
outFD: STDOUT_FILENO,
syncRequests: options.syncRequests,
closeHandler: {
exit(0)
})
syncRequests: options.syncRequests)
let installPath = AbsolutePath(Bundle.main.bundlePath)
ToolchainRegistry.shared = ToolchainRegistry(installPath: installPath, localFileSystem)
@@ -113,7 +110,9 @@ ToolchainRegistry.shared = ToolchainRegistry(installPath: installPath, localFile
let server = SourceKitServer(client: clientConnection, options: options.serverOptions, onExit: {
clientConnection.close()
})
clientConnection.start(receiveHandler: server)
clientConnection.start(receiveHandler: server, closeHandler: {
exit(0)
})
Logger.shared.addLogHandler { message, _ in
clientConnection.send(LogMessage(type: .log, message: message))

View File

@@ -213,18 +213,17 @@ class ConnectionTests: XCTestCase {
let conn = JSONRPCConection(
protocol: MessageRegistry(requests: [], notifications: []),
inFD: to.fileHandleForReading.fileDescriptor,
outFD: from.fileHandleForWriting.fileDescriptor,
closeHandler: {
// We get an error from XCTest if this is fulfilled more than once.
expectation.fulfill()
})
outFD: from.fileHandleForWriting.fileDescriptor)
final class DummyHandler: MessageHandler {
func handle<N: NotificationType>(_: N, from: ObjectIdentifier) {}
func handle<R: RequestType>(_: R, id: RequestID, from: ObjectIdentifier, reply: @escaping (LSPResult<R.Response>) -> Void) {}
}
conn.start(receiveHandler: DummyHandler())
conn.start(receiveHandler: DummyHandler(), closeHandler: {
// We get an error from XCTest if this is fulfilled more than once.
expectation.fulfill()
})
close(to.fileHandleForWriting.fileDescriptor)