All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jetbrains.kotlin.daemon.common.experimental.CompileServiceClientSideImpl.kt Maven / Gradle / Ivy

There is a newer version: 2.1.0-Beta1
Show newest version
/*
 * 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 kotlinx.coroutines.*
import org.jetbrains.kotlin.cli.common.repl.ReplCheckResult
import org.jetbrains.kotlin.cli.common.repl.ReplCodeLine
import org.jetbrains.kotlin.cli.common.repl.ReplCompileResult
import org.jetbrains.kotlin.daemon.common.*
import org.jetbrains.kotlin.daemon.common.experimental.socketInfrastructure.*
import org.jetbrains.kotlin.daemon.common.CompileService
import org.jetbrains.kotlin.daemon.common.CompilerServicesFacadeBase
import java.io.File
import java.util.logging.Logger

class CompileServiceClientSideImpl(
    override val serverPort: Int,
    val serverHost: String,
    val serverFile: File
) : CompileServiceClientSide,
    Client by object : DefaultAuthorizableClient(
        serverPort,
        serverHost
    ) {

        private fun nowMillieconds() = System.currentTimeMillis()

        @Volatile
        private var lastUsedMilliSeconds: Long = nowMillieconds()

        private fun millisecondsSinceLastUsed() = nowMillieconds() - lastUsedMilliSeconds

        private fun keepAliveSuccess() = millisecondsSinceLastUsed() < KEEPALIVE_PERIOD

        override suspend fun authorizeOnServer(serverOutputChannel: ByteWriteChannelWrapper): Boolean =
            runWithTimeout {
                val signature = serverFile.inputStream().use(::readTokenKeyPairAndSign)
                sendSignature(serverOutputChannel, signature)
                true
            } ?: false

        override suspend fun clientHandshake(input: ByteReadChannelWrapper, output: ByteWriteChannelWrapper, log: Logger): Boolean {
            return trySendHandshakeMessage(output) && tryAcquireHandshakeMessage(input)
        }

        override fun startKeepAlives() {
            val keepAliveMessage = Server.KeepAliveMessage()
            @OptIn(ObsoleteCoroutinesApi::class)
            GlobalScope.async(newSingleThreadContext("keepAliveThread")) {
                delay(KEEPALIVE_PERIOD * 4)
                while (true) {
                    delay(KEEPALIVE_PERIOD)
                    while (keepAliveSuccess()) {
                        delay(KEEPALIVE_PERIOD - millisecondsSinceLastUsed())
                    }
                    val keepAliveAcknowledgement = runWithTimeout(timeout = KEEPALIVE_PERIOD / 2) {
                        val id = sendMessage(keepAliveMessage)
                        readMessage>(id)
                    }
                    if (keepAliveAcknowledgement == null && !keepAliveSuccess()) {
                        readActor.send(StopAllRequests())
                    }
                }
            }
        }

        override fun delayKeepAlives() {
            lastUsedMilliSeconds = nowMillieconds()
        }

    } {
    override suspend fun classesFqNamesByFiles(sessionId: Int, sourceFiles: Set): CompileService.CallResult> {
        val id = sendMessage(ClassesFqNamesByFilesMessage(sessionId, sourceFiles))
        return readMessage(id)
    }

    override suspend fun compile(
        sessionId: Int,
        compilerArguments: Array,
        compilationOptions: CompilationOptions,
        servicesFacade: CompilerServicesFacadeBaseAsync,
        compilationResults: CompilationResultsAsync?
    ): CompileService.CallResult {
        val id = sendMessage(CompileMessage(
            sessionId,
            compilerArguments,
            compilationOptions,
            servicesFacade,
            compilationResults
        ))
        return readMessage(id)
    }

    override suspend fun leaseReplSession(
        aliveFlagPath: String?,
        compilerArguments: Array,
        compilationOptions: CompilationOptions,
        servicesFacade: CompilerServicesFacadeBaseAsync,
        templateClasspath: List,
        templateClassName: String
    ): CompileService.CallResult {
        val id = sendMessage(
            LeaseReplSessionMessage(
                aliveFlagPath,
                compilerArguments,
                compilationOptions,
                servicesFacade,
                templateClasspath,
                templateClassName
            )
        )
        return readMessage(id)
    }

    // CompileService methods:

    override suspend fun checkCompilerId(expectedCompilerId: CompilerId): Boolean {
        val id = sendMessage(
            CheckCompilerIdMessage(
                expectedCompilerId
            )
        )
        return readMessage(id)
    }

    override suspend fun getUsedMemory(): CompileService.CallResult {
        val id = sendMessage(GetUsedMemoryMessage())
        return readMessage(id)
    }


    override suspend fun getDaemonOptions(): CompileService.CallResult {
        val id = sendMessage(GetDaemonOptionsMessage())
        return readMessage(id)
    }

    override suspend fun getDaemonInfo(): CompileService.CallResult {
        val id = sendMessage(GetDaemonInfoMessage())
        return readMessage(id)
    }

    override suspend fun getKotlinVersion(): CompileService.CallResult {
        val id = sendMessage(GetKotlinVersionMessage())
        return readMessage(id)
    }

    override suspend fun getDaemonJVMOptions(): CompileService.CallResult {
        val id = sendMessage(GetDaemonJVMOptionsMessage())
        val res = readMessage>(id)
        return res
    }

    override suspend fun registerClient(aliveFlagPath: String?): CompileService.CallResult {
        val id = sendMessage(RegisterClientMessage(aliveFlagPath))
        return readMessage(id)
    }

    override suspend fun getClients(): CompileService.CallResult> {
        val id = sendMessage(GetClientsMessage())
        return readMessage(id)
    }

    override suspend fun leaseCompileSession(aliveFlagPath: String?): CompileService.CallResult {
        val id = sendMessage(
            LeaseCompileSessionMessage(
                aliveFlagPath
            )
        )
        return readMessage(id)
    }

    override suspend fun releaseCompileSession(sessionId: Int): CompileService.CallResult {
        val id = sendMessage(
            ReleaseCompileSessionMessage(
                sessionId
            )
        )
        return readMessage(id)
    }

    override suspend fun shutdown(): CompileService.CallResult {
        val id = sendMessage(ShutdownMessage())
        val res = readMessage>(id)
        return res
    }

    override suspend fun scheduleShutdown(graceful: Boolean): CompileService.CallResult {
        val id = sendMessage(ScheduleShutdownMessage(graceful))
        return readMessage(id)
    }

    override suspend fun clearJarCache() {
        sendMessage(ClearJarCacheMessage())
    }

    override suspend fun releaseReplSession(sessionId: Int): CompileService.CallResult {
        val id = sendMessage(ReleaseReplSessionMessage(sessionId))
        return readMessage(id)
    }

    override suspend fun replCreateState(sessionId: Int): CompileService.CallResult {
        val id = sendMessage(ReplCreateStateMessage(sessionId))
        return readMessage(id)
    }

    override suspend fun replCheck(
        sessionId: Int,
        replStateId: Int,
        codeLine: ReplCodeLine
    ): CompileService.CallResult {
        val id = sendMessage(
            ReplCheckMessage(
                sessionId,
                replStateId,
                codeLine
            )
        )
        return readMessage(id)
    }

    override suspend fun replCompile(
        sessionId: Int,
        replStateId: Int,
        codeLine: ReplCodeLine
    ): CompileService.CallResult {
        val id = sendMessage(
            ReplCompileMessage(
                sessionId,
                replStateId,
                codeLine
            )
        )
        return readMessage(id)
    }

    // Query messages:

    class CheckCompilerIdMessage(val expectedCompilerId: CompilerId) : Server.Message() {
        override suspend fun processImpl(server: CompileServiceServerSide, sendReply: (Any?) -> Unit) =
            sendReply(server.checkCompilerId(expectedCompilerId))
    }

    class GetUsedMemoryMessage : Server.Message() {
        override suspend fun processImpl(server: CompileServiceServerSide, sendReply: (Any?) -> Unit) =
            sendReply(server.getUsedMemory())
    }

    class GetDaemonOptionsMessage : Server.Message() {
        override suspend fun processImpl(server: CompileServiceServerSide, sendReply: (Any?) -> Unit) =
            sendReply(server.getDaemonOptions())
    }

    class GetDaemonJVMOptionsMessage : Server.Message() {
        override suspend fun processImpl(server: CompileServiceServerSide, sendReply: (Any?) -> Unit) =
            sendReply(server.getDaemonJVMOptions())
    }

    class GetDaemonInfoMessage : Server.Message() {
        override suspend fun processImpl(server: CompileServiceServerSide, sendReply: (Any?) -> Unit) =
            sendReply(server.getDaemonInfo())
    }

    class GetKotlinVersionMessage : Server.Message() {
        override suspend fun processImpl(server: CompileServiceServerSide, sendReply: (Any?) -> Unit) =
            sendReply(server.getKotlinVersion())
    }

    class RegisterClientMessage(val aliveFlagPath: String?) : Server.Message() {
        override suspend fun processImpl(server: CompileServiceServerSide, sendReply: (Any?) -> Unit) =
            sendReply(server.registerClient(aliveFlagPath))
    }


    class GetClientsMessage : Server.Message() {
        override suspend fun processImpl(server: CompileServiceServerSide, sendReply: (Any?) -> Unit) =
            sendReply(server.getClients())
    }

    class LeaseCompileSessionMessage(val aliveFlagPath: String?) : Server.Message() {
        override suspend fun processImpl(server: CompileServiceServerSide, sendReply: (Any?) -> Unit) =
            sendReply(server.leaseCompileSession(aliveFlagPath))
    }

    class ReleaseCompileSessionMessage(val sessionId: Int) : Server.Message() {
        override suspend fun processImpl(server: CompileServiceServerSide, sendReply: (Any?) -> Unit) =
            sendReply(server.releaseCompileSession(sessionId))
    }

    class ShutdownMessage : Server.Message() {
        override suspend fun processImpl(server: CompileServiceServerSide, sendReply: (Any?) -> Unit) =
            sendReply(server.shutdown())
    }

    class ScheduleShutdownMessage(val graceful: Boolean) : Server.Message() {
        override suspend fun processImpl(server: CompileServiceServerSide, sendReply: (Any?) -> Unit) =
            sendReply(server.scheduleShutdown(graceful))
    }

    class CompileMessage(
        val sessionId: Int,
        val compilerArguments: Array,
        val compilationOptions: CompilationOptions,
        val servicesFacade: CompilerServicesFacadeBaseAsync,
        val compilationResults: CompilationResultsAsync?
    ) : Server.Message() {
        override suspend fun processImpl(server: CompileServiceServerSide, sendReply: (Any?) -> Unit) =
            sendReply(
                server.compile(
                    sessionId,
                    compilerArguments,
                    compilationOptions,
                    servicesFacade,
                    compilationResults
                )
            )
    }

    class ClassesFqNamesByFilesMessage(
        val sessionId: Int,
        val sourceFiles: Set
    ) : Server.Message() {
        override suspend fun processImpl(server: CompileServiceServerSide, sendReply: (Any?) -> Unit) =
            sendReply(
                server.classesFqNamesByFiles(sessionId, sourceFiles)
            )
    }

    class ClearJarCacheMessage : Server.Message() {
        override suspend fun processImpl(server: CompileServiceServerSide, sendReply: (Any?) -> Unit) =
            server.clearJarCache()
    }

    class LeaseReplSessionMessage(
        val aliveFlagPath: String?,
        val compilerArguments: Array,
        val compilationOptions: CompilationOptions,
        val servicesFacade: CompilerServicesFacadeBaseAsync,
        val templateClasspath: List,
        val templateClassName: String
    ) : Server.Message() {
        override suspend fun processImpl(server: CompileServiceServerSide, sendReply: (Any?) -> Unit) =
            sendReply(
                server.leaseReplSession(
                    aliveFlagPath,
                    compilerArguments,
                    compilationOptions,
                    servicesFacade,
                    templateClasspath,
                    templateClassName
                )
            )
    }

    class ReleaseReplSessionMessage(val sessionId: Int) : Server.Message() {
        override suspend fun processImpl(server: CompileServiceServerSide, sendReply: (Any?) -> Unit) =
            sendReply(server.releaseReplSession(sessionId))
    }

    class LeaseReplSession_Short_Message(
        val aliveFlagPath: String?,
        val compilerArguments: Array,
        val compilationOptions: CompilationOptions,
        val servicesFacade: CompilerServicesFacadeBase,
        val templateClasspath: List,
        val templateClassName: String
    ) : Server.Message() {
        override suspend fun processImpl(server: CompileServiceServerSide, sendReply: (Any?) -> Unit) =
            sendReply(
                server.leaseReplSession(
                    aliveFlagPath,
                    compilerArguments,
                    compilationOptions,
                    servicesFacade.toClient(),
                    templateClasspath,
                    templateClassName
                )
            )
    }

    class ReplCreateStateMessage(val sessionId: Int) : Server.Message() {
        override suspend fun processImpl(server: CompileServiceServerSide, sendReply: (Any?) -> Unit) =
            sendReply(server.replCreateState(sessionId))
    }

    class ReplCheckMessage(
        val sessionId: Int,
        val replStateId: Int,
        val codeLine: ReplCodeLine
    ) : Server.Message() {
        override suspend fun processImpl(server: CompileServiceServerSide, sendReply: (Any?) -> Unit) =
            sendReply(server.replCheck(sessionId, replStateId, codeLine))
    }

    class ReplCompileMessage(
        val sessionId: Int,
        val replStateId: Int,
        val codeLine: ReplCodeLine
    ) : Server.Message() {
        override suspend fun processImpl(server: CompileServiceServerSide, sendReply: (Any?) -> Unit) =
            sendReply(server.replCompile(sessionId, replStateId, codeLine))
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy