Move daemon jar from compiler

This commit is contained in:
Vadim Brilyantov
2019-04-03 19:34:06 +03:00
parent ced973b707
commit 01a05a5495
67 changed files with 441 additions and 759 deletions
@@ -25,12 +25,12 @@ dependencies {
compile(project(":core:descriptors.jvm"))
compile(project(":compiler:util"))
compile(project(":compiler:cli-common"))
compileOnly(project(":compiler:daemon-common"))
compileOnly(project(":daemon-common"))
compile(kotlinStdlib())
compileOnly(project(":js:js.frontend"))
compileOnly(intellijCoreDep()) { includeJars("intellij-core") }
compileOnly(intellijDep()) { includeIntellijCoreJarDependencies(project) }
compile(commonDep("org.jetbrains.kotlinx", "kotlinx-coroutines-jdk8")) {
compile(commonDep("org.jetbrains.kotlinx", "kotlinx-coroutines-core")) {
isTransitive = false
}
compile(commonDep("io.ktor", "ktor-network")) {
@@ -99,9 +99,9 @@ private inline fun tryConnectToDaemonByRMI(port: Int, report: (DaemonReportCateg
val daemon = runBlocking {
runWithTimeout(2 * DAEMON_PERIODIC_CHECK_INTERVAL_MS) {
LocateRegistry.getRegistry(
LoopbackNetworkInterface.loopbackInetAddressName,
org.jetbrains.kotlin.daemon.common.LoopbackNetworkInterface.loopbackInetAddressName,
port,
LoopbackNetworkInterface.clientLoopbackSocketFactoryRMI
org.jetbrains.kotlin.daemon.common.LoopbackNetworkInterface.clientLoopbackSocketFactory
)?.lookup(COMPILER_SERVICE_RMI_NAME)
}
}
@@ -134,7 +134,7 @@ private suspend fun tryConnectToDaemonBySockets(
log.info("OK - daemon($port) connected to server!!!")
daemon
} catch (e: Throwable) {
report(DaemonReportCategory.INFO, "kcannot find or connect to socket")
report(DaemonReportCategory.INFO, "cannot find or connect to socket, exception:\n${e.javaClass.name}:${e.message}")
daemon.close()
null
}
@@ -6,7 +6,6 @@
package org.jetbrains.kotlin.daemon.common.experimental
import org.jetbrains.kotlin.daemon.common.IncrementalCompilerServicesFacade
import org.jetbrains.kotlin.daemon.common.SimpleDirtyData
import org.jetbrains.kotlin.daemon.common.experimental.socketInfrastructure.Client
import org.jetbrains.kotlin.daemon.common.experimental.socketInfrastructure.DefaultClientRMIWrapper
import java.io.File
@@ -6,8 +6,6 @@
package org.jetbrains.kotlin.daemon.common.experimental
import org.jetbrains.kotlin.daemon.common.IncrementalCompilerServicesFacadeAsync
import org.jetbrains.kotlin.daemon.common.SimpleDirtyData
import org.jetbrains.kotlin.daemon.common.experimental.IncrementalCompilerServicesFacadeServerSide.*
import org.jetbrains.kotlin.daemon.common.experimental.socketInfrastructure.Client
import org.jetbrains.kotlin.daemon.common.experimental.socketInfrastructure.DefaultClient
import java.io.File
@@ -7,8 +7,6 @@ package org.jetbrains.kotlin.daemon.common.experimental
import kotlinx.coroutines.runBlocking
import org.jetbrains.kotlin.daemon.common.IncrementalCompilerServicesFacade
import org.jetbrains.kotlin.daemon.common.SimpleDirtyData
import java.io.File
import java.io.Serializable
class IncrementalCompilerServicesFacadeRMIWrapper(val clientSide: IncrementalCompilerServicesFacadeClientSide) :
@@ -6,9 +6,6 @@
package org.jetbrains.kotlin.daemon.common.experimental
import org.jetbrains.kotlin.daemon.common.IncrementalCompilerServicesFacadeAsync
import org.jetbrains.kotlin.daemon.common.SimpleDirtyData
import org.jetbrains.kotlin.daemon.common.experimental.socketInfrastructure.Server
import java.io.File
interface IncrementalCompilerServicesFacadeServerSide : IncrementalCompilerServicesFacadeAsync, CompilerServicesFacadeBaseServerSide
@@ -18,58 +18,11 @@ import java.rmi.server.RMIServerSocketFactory
import java.util.*
// copyed from original(org.jetbrains.kotlin.daemon.common.NetworkUtils) TODO
// unique part :
// - AbstractClientLoopbackSocketFactory / ServerLoopbackSocketFactoryRMI / ServerLoopbackSocketFactoryKtor - Ktor-Sockets instead of java sockets
// - findPortAndCreateSocket
// TODO: get rid of copy-paste here
object LoopbackNetworkInterface {
const val IPV4_LOOPBACK_INET_ADDRESS = "127.0.0.1"
const val IPV6_LOOPBACK_INET_ADDRESS = "::1"
// size of the requests queue for daemon services, so far seems that we don't need any big numbers here
// but if we'll start getting "connection refused" errors, that could be the first place to try to fix it
val SERVER_SOCKET_BACKLOG_SIZE by lazy {
System.getProperty(DAEMON_RMI_SOCKET_BACKLOG_SIZE_PROPERTY)?.toIntOrNull() ?: DEFAULT_SERVER_SOCKET_BACKLOG_SIZE
}
val SOCKET_CONNECT_ATTEMPTS by lazy {
System.getProperty(DAEMON_RMI_SOCKET_CONNECT_ATTEMPTS_PROPERTY)?.toIntOrNull() ?: DEFAULT_SOCKET_CONNECT_ATTEMPTS
}
val SOCKET_CONNECT_INTERVAL_MS by lazy {
System.getProperty(DAEMON_RMI_SOCKET_CONNECT_INTERVAL_PROPERTY)?.toLongOrNull() ?: DEFAULT_SOCKET_CONNECT_INTERVAL_MS
}
val serverLoopbackSocketFactoryRMI by lazy { ServerLoopbackSocketFactoryRMI() }
val clientLoopbackSocketFactoryRMI by lazy { ClientLoopbackSocketFactoryRMI() }
object LoopbackNetworkInterfaceKtor {
val serverLoopbackSocketFactoryKtor by lazy { ServerLoopbackSocketFactoryKtor() }
val clientLoopbackSocketFactoryKtor by lazy { ClientLoopbackSocketFactoryKtor() }
// TODO switch to InetAddress.getLoopbackAddress on java 7+
val loopbackInetAddressName by lazy {
try {
if (InetAddress.getByName(null) is Inet6Address) IPV6_LOOPBACK_INET_ADDRESS else IPV4_LOOPBACK_INET_ADDRESS
} catch (e: IOException) {
// getLocalHost may fail for unknown reasons in some situations, the fallback is to assume IPv4 for now
// TODO consider some other ways to detect default to IPv6 addresses in this case
IPV4_LOOPBACK_INET_ADDRESS
}
}
// base socket factories by default don't implement equals properly (see e.g. http://stackoverflow.com/questions/21555710/rmi-and-jmx-socket-factories)
// so implementing it in derived classes using the fact that they are singletons
class ServerLoopbackSocketFactoryRMI : RMIServerSocketFactory, Serializable {
override fun equals(other: Any?): Boolean = other === this || super.equals(other)
override fun hashCode(): Int = super.hashCode()
@Throws(IOException::class)
override fun createServerSocket(port: Int): java.net.ServerSocket =
ServerSocket(port, SERVER_SOCKET_BACKLOG_SIZE, InetAddress.getByName(null))
}
val selectorMgr = ActorSelectorManager(Dispatchers.IO)
class ServerLoopbackSocketFactoryKtor : Serializable {
@@ -83,31 +36,7 @@ object LoopbackNetworkInterface {
.bind(InetSocketAddress(InetAddress.getByName(null), port)) // TODO : NO BACKLOG SIZE CHANGE =(
}
abstract class AbstractClientLoopbackSocketFactory<SocketType> : Serializable {
override fun equals(other: Any?): Boolean = other === this || super.equals(other)
override fun hashCode(): Int = super.hashCode()
abstract protected fun socketCreate(host: String, port: Int): SocketType
@Throws(IOException::class)
fun createSocket(host: String, port: Int): SocketType {
var attemptsLeft = SOCKET_CONNECT_ATTEMPTS
while (true) {
try {
return socketCreate(host, port)
} catch (e: ConnectException) {
if (--attemptsLeft <= 0) throw e
}
Thread.sleep(SOCKET_CONNECT_INTERVAL_MS)
}
}
}
class ClientLoopbackSocketFactoryRMI : AbstractClientLoopbackSocketFactory<java.net.Socket>(), RMIClientSocketFactory {
override fun socketCreate(host: String, port: Int): Socket = Socket(InetAddress.getByName(null), port)
}
class ClientLoopbackSocketFactoryKtor : AbstractClientLoopbackSocketFactory<io.ktor.network.sockets.Socket>() {
class ClientLoopbackSocketFactoryKtor : LoopbackNetworkInterface.AbstractClientLoopbackSocketFactory<io.ktor.network.sockets.Socket>() {
override fun socketCreate(host: String, port: Int): io.ktor.network.sockets.Socket =
runBlocking { aSocket(selectorMgr).tcp().connect(InetSocketAddress(host, port)) }
}
@@ -126,7 +55,7 @@ fun findPortForSocket(attempts: Int, portRangeStart: Int, portRangeEnd: Int): Se
try {
return ServerSocketWrapper(
port,
LoopbackNetworkInterface.serverLoopbackSocketFactoryKtor.createServerSocket(port)
LoopbackNetworkInterfaceKtor.serverLoopbackSocketFactoryKtor.createServerSocket(port)
)
} catch (e: Exception) {
// assuming that the socketPort is already taken
@@ -1,29 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.daemon.common.experimental
interface RemoteOutputStreamAsync {
/** closeStream() name is chosen since Clients are AutoClosable now
* and Client-implementations of RemoteOutputStreamAsync have conflict of 'close' name **/
suspend fun closeStream()
suspend fun write(data: ByteArray, offset: Int, length: Int)
suspend fun write(dataByte: Int)
}
interface RemoteInputStreamAsync {
/** closeStream() name is chosen since Clients are AutoClosable now
* and Client-implementations of RemoteInputStreamAsync have conflict of 'close' name **/
suspend fun closeStream()
suspend fun read(length: Int): ByteArray
suspend fun read(): Int
}
@@ -1,12 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.daemon.common.experimental
import org.jetbrains.kotlin.daemon.common.experimental.socketInfrastructure.Client
interface RemoteOutputStreamAsyncClientSide : RemoteOutputStreamAsync, Client<RemoteOutputStreamAsyncServerSide>
interface RemoteInputStreamClientSide : RemoteInputStreamAsync, Client<RemoteInputStreamServerSide>
@@ -1,43 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.daemon.common.experimental
import org.jetbrains.kotlin.daemon.common.experimental.socketInfrastructure.ByteWriteChannelWrapper
import org.jetbrains.kotlin.daemon.common.experimental.socketInfrastructure.Server
interface RemoteOutputStreamAsyncServerSide : RemoteOutputStreamAsync, Server<RemoteOutputStreamAsyncServerSide> {
// Query messages:
class CloseMessage : Server.Message<RemoteOutputStreamAsyncServerSide>() {
override suspend fun processImpl(server: RemoteOutputStreamAsyncServerSide, sendReply: (Any?) -> Unit) =
server.closeStream()
}
class WriteMessage(val data: ByteArray, val offset: Int = -1, val length: Int = -1) :
Server.Message<RemoteOutputStreamAsyncServerSide>() {
override suspend fun processImpl(server: RemoteOutputStreamAsyncServerSide, sendReply: (Any?) -> Unit) =
server.write(data, offset, length)
}
class WriteIntMessage(val dataByte: Int) : Server.Message<RemoteOutputStreamAsyncServerSide>() {
override suspend fun processImpl(server: RemoteOutputStreamAsyncServerSide, sendReply: (Any?) -> Unit) =
server.write(dataByte)
}
}
interface RemoteInputStreamServerSide : RemoteInputStreamAsync, Server<RemoteInputStreamServerSide> {
// Query messages:
class CloseMessage : Server.Message<RemoteInputStreamServerSide>() {
override suspend fun processImpl(server: RemoteInputStreamServerSide, sendReply: (Any?) -> Unit) =
server.closeStream()
}
class ReadMessage(val length: Int = -1) : Server.Message<RemoteInputStreamServerSide>() {
override suspend fun processImpl(server: RemoteInputStreamServerSide, sendReply: (Any?) -> Unit) =
sendReply(if (length == -1) server.read() else server.read(length))
}
}
@@ -1,41 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.daemon.common.experimental
import org.jetbrains.kotlin.daemon.common.RemoteInputStream
import org.jetbrains.kotlin.daemon.common.RemoteOutputStream
import org.jetbrains.kotlin.daemon.common.experimental.socketInfrastructure.Client
import org.jetbrains.kotlin.daemon.common.experimental.socketInfrastructure.DefaultClientRMIWrapper
class RemoteOutputStreamAsyncWrapper(val rmiOutput: RemoteOutputStream) : RemoteOutputStreamAsyncClientSide,
Client<RemoteOutputStreamAsyncServerSide> by DefaultClientRMIWrapper() {
override suspend fun closeStream() =
rmiOutput.close()
override suspend fun write(data: ByteArray, offset: Int, length: Int) =
rmiOutput.write(data, offset, length)
override suspend fun write(dataByte: Int) =
rmiOutput.write(dataByte)
}
class RemoteInputStreamAsyncWrapper(private val rmiInput: RemoteInputStream) : RemoteInputStreamClientSide,
Client<RemoteInputStreamServerSide> by DefaultClientRMIWrapper() {
override suspend fun closeStream() =
rmiInput.close()
override suspend fun read() =
rmiInput.read()
override suspend fun read(length: Int) =
rmiInput.read(length)
}
fun RemoteOutputStream.toClient() = RemoteOutputStreamAsyncWrapper(this)
fun RemoteInputStream.toClient() = RemoteInputStreamAsyncWrapper(this)
@@ -3,7 +3,8 @@ package org.jetbrains.kotlin.daemon.common.experimental.socketInfrastructure
import io.ktor.network.sockets.Socket
import kotlinx.coroutines.channels.*
import kotlinx.coroutines.*
import org.jetbrains.kotlin.daemon.common.experimental.LoopbackNetworkInterface
import org.jetbrains.kotlin.daemon.common.LoopbackNetworkInterface
import org.jetbrains.kotlin.daemon.common.experimental.LoopbackNetworkInterfaceKtor
import sun.net.ConnectionResetException
import java.beans.Transient
import java.io.IOException
@@ -198,7 +199,7 @@ abstract class DefaultAuthorizableClient<ServerType : ServerBase>(
try {
socket = LoopbackNetworkInterface.clientLoopbackSocketFactoryKtor.createSocket(
socket = LoopbackNetworkInterfaceKtor.clientLoopbackSocketFactoryKtor.createSocket(
serverHost,
serverPort
)