Skip to content

Commit

Permalink
Fix connection problem (#9)
Browse files Browse the repository at this point in the history
* fix connection, quiet warnings for GlobalScope coroutines
  • Loading branch information
sam-dixon authored Dec 8, 2021
1 parent 241a37e commit 90fa750
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 28 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

# Serenade for IntelliJ platform Changelog

## [0.0.11] - 2021-12-07

### Fixed
- Issue with plugin not disconnecting and reconnecting from client properly

## [0.0.10] - 2021-08-02

### Added
Expand Down
9 changes: 6 additions & 3 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ repositories {
jcenter()
}
dependencies {
implementation(kotlin("stdlib", org.jetbrains.kotlin.config.KotlinCompilerVersion.VERSION))
implementation(kotlin("stdlib-jdk8"))
implementation(kotlin("stdlib", "1.5.0-M2"))
implementation(kotlin("stdlib-jdk8", "1.5.0-M2"))
implementation(kotlin("reflect", "1.5.0-M2"))
detektPlugins("io.gitlab.arturbosch.detekt:detekt-formatting:1.10.0")
implementation("io.ktor:ktor-client-websockets:$ktorVersion") {
Expand Down Expand Up @@ -97,7 +97,10 @@ tasks {
}
listOf("compileKotlin", "compileTestKotlin").forEach {
getByName<KotlinCompile>(it) {
kotlinOptions.jvmTarget = "1.8"
kotlinOptions {
jvmTarget = "1.8"
freeCompilerArgs += "-Xopt-in=kotlin.RequiresOptIn"
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

pluginGroup = ai.serenade.intellij
pluginName = Serenade
pluginVersion = 0.0.10
pluginVersion = 0.0.11
pluginSinceBuild = 203
pluginUntilBuild =

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import com.intellij.openapi.vfs.VfsUtil
import com.intellij.openapi.vfs.VirtualFile
import io.ktor.client.features.websocket.DefaultClientWebSocketSession
import io.ktor.http.cio.websocket.Frame
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.serialization.* // ktlint-disable no-wildcard-imports
Expand Down Expand Up @@ -146,6 +147,7 @@ class CommandHandler(private val project: Project) {
}

private fun sendCallback(callback: String, data: CallbackData?) {
@OptIn(DelicateCoroutinesApi::class)
GlobalScope.launch {
webSocketSession?.send(
Frame.Text(
Expand Down
45 changes: 21 additions & 24 deletions src/main/kotlin/ai/serenade/intellij/services/IpcService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import io.ktor.client.features.websocket.WebSockets
import io.ktor.client.features.websocket.ws
import io.ktor.http.cio.websocket.Frame
import io.ktor.http.cio.websocket.readText
import io.ktor.util.KtorExperimentalAPI
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
Expand All @@ -21,7 +23,7 @@ import java.util.UUID

const val RECONNECT_TIMEOUT_MS: Long = 3000

@io.ktor.util.KtorExperimentalAPI
@KtorExperimentalAPI
class IpcService(private val project: Project) {
private var notifier: Notifier = Notifier(project)
private var connectScope: Job? = null
Expand All @@ -42,6 +44,7 @@ class IpcService(private val project: Project) {
fun start() {
// ensure that reconnection loop is only started once
if (connectScope == null) {
@OptIn(DelicateCoroutinesApi::class)
connectScope = GlobalScope.launch {
while (true) {
// No-op if connected already
Expand All @@ -53,16 +56,14 @@ class IpcService(private val project: Project) {
}

// listen to focus, and update plugin active state
WindowManagerEx.getInstance().getFrame(project)
?.addWindowListener(
object : WindowAdapter() {
override fun windowActivated(e: WindowEvent?) {
GlobalScope.launch {
sendAppStatus("active")
}
}
WindowManagerEx.getInstance().getFrame(project)?.addWindowListener(
object : WindowAdapter() {
override fun windowActivated(e: WindowEvent?) {
@OptIn(DelicateCoroutinesApi::class)
GlobalScope.launch { sendAppStatus("active") }
}
)
}
)
}
}

Expand All @@ -76,12 +77,10 @@ class IpcService(private val project: Project) {
notifier.notify("Could not connect")
shouldNotify = false
}
heartbeatScope?.cancel()
toolWindow.setContent(false)
onClose()
} catch (e: Exception) {
notifier.notify("Could not connect: $e")
heartbeatScope?.cancel()
toolWindow.setContent(false)
onClose()
}
}

Expand All @@ -95,6 +94,7 @@ class IpcService(private val project: Project) {

// send a heartbeat in a separate coroutine
id = UUID.randomUUID().toString()
@OptIn(DelicateCoroutinesApi::class)
heartbeatScope = GlobalScope.launch {
while (isActive) {
sendAppStatus("heartbeat")
Expand All @@ -112,16 +112,8 @@ class IpcService(private val project: Project) {
}
}
}

// wait for the session to be closed by the client:
GlobalScope.launch {
webSocketSession?.closeReason?.await()
notifier.notify("Disconnected")
shouldNotify = true
heartbeatScope?.cancel()
toolWindow.setContent(false)
webSocketSession = null
}
notifier.notify("Disconnected")
webSocketSession = null
}

private suspend fun sendAppStatus(name: String) {
Expand Down Expand Up @@ -152,4 +144,9 @@ class IpcService(private val project: Project) {
notifier.notify(e.toString())
}
}

private fun onClose() {
heartbeatScope?.cancel()
toolWindow.setContent(false)
}
}
2 changes: 2 additions & 0 deletions src/main/kotlin/ai/serenade/intellij/services/Notifier.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package ai.serenade.intellij.services
import com.intellij.notification.NotificationGroupManager
import com.intellij.notification.NotificationType
import com.intellij.openapi.project.Project
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
Expand All @@ -16,6 +17,7 @@ class Notifier(private val project: Project) {
"Serenade: $message",
NotificationType.INFORMATION
)
@OptIn(DelicateCoroutinesApi::class)
GlobalScope.launch {
delay(5000)
notification.expire()
Expand Down

0 comments on commit 90fa750

Please sign in to comment.