Skip to content

Commit

Permalink
feat(jb): observe ports status and send notification
Browse files Browse the repository at this point in the history
  • Loading branch information
Andrea Falzetti committed May 24, 2022
1 parent 6972cd5 commit d1b64dc
Showing 1 changed file with 107 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

package io.gitpod.jetbrains.remote

import com.intellij.ide.BrowserUtil
import com.intellij.ide.plugins.PluginManagerCore
import com.intellij.notification.NotificationAction
import com.intellij.notification.NotificationGroupManager
Expand All @@ -23,6 +24,10 @@ import io.gitpod.jetbrains.remote.utils.Retrier.retry
import io.gitpod.supervisor.api.*
import io.gitpod.supervisor.api.Info.WorkspaceInfoResponse
import io.gitpod.supervisor.api.Notification.*
import io.gitpod.supervisor.api.Status.OnPortExposedAction
import io.gitpod.supervisor.api.Status.PortsStatus
import io.gitpod.supervisor.api.Status.PortsStatusRequest
import io.gitpod.supervisor.api.Status.PortsStatusResponse
import io.grpc.ManagedChannel
import io.grpc.ManagedChannelBuilder
import io.grpc.stub.ClientCallStreamObserver
Expand All @@ -46,6 +51,7 @@ import java.util.concurrent.CancellationException
import java.util.concurrent.CompletableFuture
import javax.websocket.DeploymentException


@Service
class GitpodManager : Disposable {

Expand Down Expand Up @@ -199,6 +205,107 @@ class GitpodManager : Disposable {
}
}

private val portsObserveJob = GlobalScope.launch {
if (application.isHeadlessEnvironment) {
return@launch
}

val ignorePorts = listOf(5990, 6942)
val portsStatus = hashMapOf<Int, PortsStatus>()

val status = StatusServiceGrpc.newStub(supervisorChannel)
//while (isActive) {
try {
val f = CompletableFuture<Void>()
status.portsStatus(
PortsStatusRequest.newBuilder().setObserve(true).build(),
object : ClientResponseObserver<PortsStatusRequest, PortsStatusResponse> {
override fun beforeStart(requestStream: ClientCallStreamObserver<PortsStatusRequest>) {
println("[Andrea]: beforeStart")
// TODO(ak): actually should be bound to cancellation of notifications job
lifetime.onTerminationOrNow {
requestStream.cancel(null, null)
}
}

override fun onNext(ps: PortsStatusResponse) {
for (port in ps.portsList) {
if (ignorePorts.contains(port.localPort)) {
continue
}

if (!portsStatus.containsKey(port.localPort)) {
portsStatus[port.localPort] = port
continue
}

println("DEBUG[${port.localPort}] -> before hasExposed(${portsStatus[port.localPort]?.hasExposed().toString()}) -> now hasExposed(${port.hasExposed()})")

if (!portsStatus[port.localPort]?.hasExposed()!! && port.hasExposed()) {
if (port.exposed.onExposed.number == OnPortExposedAction.ignore_VALUE) {
continue
}

if (port.exposed.onExposed.number == OnPortExposedAction.open_browser_VALUE) {
BrowserUtil.browse(port.exposed.url)
continue
}

if (port.exposed.onExposed.number == OnPortExposedAction.open_preview_VALUE) {
BrowserUtil.browse(port.exposed.url)
continue
}

if (port.served && !port.exposed.url.isNullOrEmpty()) {
println("Show port notification‼️‼️ ${port.localPort}")
val message =
"Your application running on port " + port.localPort + " is available."
println(message)
val notification =
notificationGroup.createNotification(message, NotificationType.INFORMATION)
// TODO(andreafalzetti): add analytics event
val lambda = { BrowserUtil.browse(port.exposed.url) }
val action = NotificationAction.createSimpleExpiring("Open in browser", lambda)
notification.addAction(action)
notification.notify(null)
}
//
}

}

}

override fun onError(t: Throwable) {
println("[Andrea]: onError")
println(t)
f.completeExceptionally(t)
}

override fun onCompleted() {
f.complete(null)
}
})
} catch (t: Throwable) {
if (t is CancellationException) {
throw t
}
thisLogger().error("gitpod: failed to stream ports status: ", t)
}
//println("**** DEBUG **** ${portsStatus.size}")
//portsStatus.forEach { ps ->
// println("${ps.key} : ${ps.value.exposed.url}")
//}
// println("***************")
// delay(1000)
//}
}
init {
lifetime.onTerminationOrNow {
portsObserveJob.cancel()
}
}

val pendingInfo = CompletableFuture<WorkspaceInfoResponse>()
private val infoJob = GlobalScope.launch {
if (application.isHeadlessEnvironment) {
Expand Down

0 comments on commit d1b64dc

Please sign in to comment.