Skip to content

Commit 7a2ec22

Browse files
authored
Fix current service timing out (#785)
* refactor: added logging * fix: trigger indicator stopped on guide mark removed * fix: added warning for no service refactor: return null on no service instead of throwing err ref: sourceplusplus/sourceplusplus#421 * refactor: remove unused code * fix: ensure live plugins closed before opening again
1 parent fcdc231 commit 7a2ec22

File tree

9 files changed

+61
-157
lines changed

9 files changed

+61
-157
lines changed

marker/src/main/kotlin/spp/jetbrains/marker/source/info/EndpointDetector.kt

+6-16
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@ package spp.jetbrains.marker.source.info
1818

1919
import io.vertx.core.Future
2020
import io.vertx.core.Vertx
21-
import io.vertx.core.eventbus.ReplyException
22-
import io.vertx.core.eventbus.ReplyFailure
2321
import io.vertx.kotlin.coroutines.await
2422
import org.slf4j.LoggerFactory
2523
import spp.jetbrains.marker.source.mark.api.key.SourceKey
@@ -105,20 +103,12 @@ abstract class EndpointDetector<T : EndpointDetector.EndpointNameDeterminer>(val
105103

106104
private suspend fun determineEndpointId(endpointName: String, sourceMark: MethodGuideMark) {
107105
log.trace("Determining endpoint id")
108-
try {
109-
val endpoint = EndpointBridge.searchExactEndpoint(endpointName, vertx)
110-
if (endpoint != null) {
111-
sourceMark.putUserData(ENDPOINT_ID, endpoint.getString("id"))
112-
log.trace("Detected endpoint id: ${endpoint.getString("id")}")
113-
} else {
114-
log.trace("Could not find endpoint id for: $endpointName")
115-
}
116-
} catch (ex: ReplyException) {
117-
if (ex.failureType() == ReplyFailure.TIMEOUT) {
118-
log.debug("Timed out looking for endpoint id for: $endpointName")
119-
} else {
120-
throw ex
121-
}
106+
val endpoint = EndpointBridge.searchExactEndpoint(endpointName, vertx)
107+
if (endpoint != null) {
108+
sourceMark.putUserData(ENDPOINT_ID, endpoint.getString("id"))
109+
log.trace("Detected endpoint id: ${endpoint.getString("id")}")
110+
} else {
111+
log.trace("Could not find endpoint id for: $endpointName")
122112
}
123113
}
124114

monitor/src/main/kotlin/spp/jetbrains/monitor/skywalking/SkywalkingMonitorService.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ interface SkywalkingMonitorService {
5959
suspend fun getTraces(request: GetEndpointTraces): TraceResult
6060
suspend fun getTraceStack(traceId: String): TraceSpanStackQueryResult
6161
suspend fun queryLogs(query: LogsBridge.GetEndpointLogs): AsyncResult<LogResult>
62-
suspend fun getCurrentService(): Service
62+
suspend fun getCurrentService(): Service?
6363
suspend fun getActiveServices(): List<Service>
6464
suspend fun getCurrentServiceInstance(): GetServiceInstancesQuery.Result?
6565
suspend fun getActiveServiceInstances(): List<GetServiceInstancesQuery.Result>

monitor/src/main/kotlin/spp/jetbrains/monitor/skywalking/bridge/EndpointBridge.kt

+4-17
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@
1717
package spp.jetbrains.monitor.skywalking.bridge
1818

1919
import io.vertx.core.Vertx
20-
import io.vertx.core.eventbus.ReplyException
21-
import io.vertx.core.eventbus.ReplyFailure
2220
import io.vertx.core.json.JsonObject
2321
import io.vertx.kotlin.coroutines.CoroutineVerticle
2422
import io.vertx.kotlin.coroutines.await
@@ -46,21 +44,10 @@ class EndpointBridge(private val skywalkingClient: SkywalkingClient) : Coroutine
4644

4745
vertx.eventBus().localConsumer<String>(searchExactEndpointAddress) {
4846
launch(vertx.dispatcher()) {
49-
val service = try {
50-
ServiceBridge.getCurrentService(vertx)
51-
} catch (ex: ReplyException) {
52-
if (ex.failureType() == ReplyFailure.TIMEOUT) {
53-
log.debug("Timed out looking for current service")
54-
it.reply(null)
55-
return@launch
56-
} else {
57-
ex.printStackTrace()
58-
it.fail(500, ex.message)
59-
return@launch
60-
}
61-
} catch (throwable: Throwable) {
62-
throwable.printStackTrace()
63-
it.fail(404, "Apache SkyWalking current service unavailable")
47+
val service = ServiceBridge.getCurrentService(vertx)
48+
if (service == null) {
49+
log.warn("Unable to determine current service for endpoint search")
50+
it.reply(null)
6451
return@launch
6552
}
6653

monitor/src/main/kotlin/spp/jetbrains/monitor/skywalking/bridge/ServiceBridge.kt

+39-43
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import io.vertx.kotlin.coroutines.CoroutineVerticle
2222
import io.vertx.kotlin.coroutines.await
2323
import io.vertx.kotlin.coroutines.dispatcher
2424
import kotlinx.coroutines.launch
25+
import org.slf4j.LoggerFactory
2526
import spp.jetbrains.monitor.skywalking.SkywalkingClient
2627
import spp.jetbrains.monitor.skywalking.SkywalkingClient.DurationStep
2728
import spp.protocol.platform.general.Service
@@ -43,63 +44,58 @@ class ServiceBridge(
4344
var activeServices: List<Service> = emptyList()
4445

4546
override suspend fun start() {
46-
vertx.setPeriodic(5000) { timerId ->
47-
launch(vertx.dispatcher()) {
48-
activeServices = skywalkingClient.run {
49-
getServices(getDuration(ZonedDateTime.now().minusMinutes(15), DurationStep.MINUTE))
50-
}
51-
52-
if (activeServices.isNotEmpty()) {
53-
vertx.cancelTimer(timerId)
54-
vertx.eventBus().publish(activeServicesUpdatedAddress, activeServices)
55-
56-
if (initServiceName != null) {
57-
currentService = activeServices.find { it.name == initServiceName }
47+
if (!setCurrentService()) {
48+
//periodically check for current service
49+
log.info("No current service set, starting periodic check for current service")
50+
vertx.setPeriodic(5000) { timerId ->
51+
launch(vertx.dispatcher()) {
52+
if (setCurrentService()) {
53+
vertx.cancelTimer(timerId)
5854
}
59-
if (currentService == null) {
60-
currentService = activeServices[0]
61-
}
62-
vertx.eventBus().publish(currentServiceUpdatedAddress, currentService)
6355
}
6456
}
6557
}
6658

6759
//async accessors
6860
vertx.eventBus().localConsumer<Boolean>(getCurrentServiceAddress) { msg ->
69-
if (msg.body() && currentService == null) {
70-
val consumer = currentServiceConsumer(vertx)
71-
if (currentService != null) {
72-
consumer.unregister()
73-
msg.reply(currentService)
74-
} else {
75-
consumer.handler {
76-
msg.reply(it.body())
77-
consumer.unregister()
78-
}
79-
}
80-
} else {
81-
msg.reply(currentService)
61+
if (currentService == null) {
62+
log.warn("No current service set")
8263
}
64+
msg.reply(currentService)
8365
}
8466
vertx.eventBus().localConsumer<Boolean>(getActiveServicesAddress) { msg ->
85-
if (msg.body() && activeServices.isEmpty()) {
86-
val consumer = activeServicesConsumer(vertx)
87-
if (activeServices.isNotEmpty()) {
88-
consumer.unregister()
89-
msg.reply(activeServices)
90-
} else {
91-
consumer.handler {
92-
msg.reply(it.body())
93-
consumer.unregister()
94-
}
95-
}
96-
} else {
97-
msg.reply(activeServices)
67+
if (activeServices.isEmpty()) {
68+
log.warn("No active services set")
9869
}
70+
msg.reply(activeServices)
9971
}
10072
}
10173

74+
private suspend fun setCurrentService(): Boolean {
75+
activeServices = skywalkingClient.run {
76+
getServices(getDuration(ZonedDateTime.now().minusMinutes(15), DurationStep.MINUTE))
77+
}
78+
79+
if (activeServices.isNotEmpty()) {
80+
vertx.eventBus().publish(activeServicesUpdatedAddress, activeServices)
81+
82+
if (initServiceName != null) {
83+
currentService = activeServices.find { it.name == initServiceName }
84+
currentService?.let { log.info("Current service set to: {}", it.name) }
85+
}
86+
if (currentService == null) {
87+
currentService = activeServices[0]
88+
log.info("Current service set to: {}", currentService!!.name)
89+
}
90+
vertx.eventBus().publish(currentServiceUpdatedAddress, currentService)
91+
return true
92+
}
93+
return false
94+
}
95+
10296
companion object {
97+
private val log = LoggerFactory.getLogger(ServiceBridge::class.java)
98+
10399
private const val rootAddress = "monitor.skywalking.service"
104100
private const val getCurrentServiceAddress = "$rootAddress.currentService"
105101
private const val getActiveServicesAddress = "$rootAddress.activeServices"
@@ -114,7 +110,7 @@ class ServiceBridge(
114110
return vertx.eventBus().localConsumer(activeServicesUpdatedAddress)
115111
}
116112

117-
suspend fun getCurrentService(vertx: Vertx): Service {
113+
suspend fun getCurrentService(vertx: Vertx): Service? {
118114
return vertx.eventBus()
119115
.request<Service>(getCurrentServiceAddress, true).await().body()
120116
}

monitor/src/main/kotlin/spp/jetbrains/monitor/skywalking/impl/SkywalkingMonitorServiceImpl.kt

+3-2
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ class SkywalkingMonitorServiceImpl(
5353
}
5454

5555
override suspend fun searchExactEndpoint(keyword: String, cache: Boolean): JsonObject? {
56-
val endpoints = skywalkingClient.searchEndpoint(keyword, getCurrentService().id, 1, cache)
56+
val service = getCurrentService() ?: return null
57+
val endpoints = skywalkingClient.searchEndpoint(keyword, service.id, 1, cache)
5758
return endpoints.map { it as JsonObject }.find { it.getString("name") == keyword }
5859
}
5960

@@ -77,7 +78,7 @@ class SkywalkingMonitorServiceImpl(
7778
return EndpointTracesBridge.getTraceStack(traceId, skywalkingClient.vertx)
7879
}
7980

80-
override suspend fun getCurrentService(): Service {
81+
override suspend fun getCurrentService(): Service? {
8182
return ServiceBridge.getCurrentService(skywalkingClient.vertx)
8283
}
8384

plugin/src/main/kotlin/spp/jetbrains/sourcemarker/SourceMarkerPlugin.kt

+1
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ object SourceMarkerPlugin {
133133
) {
134134
log.info("Initializing SourceMarkerPlugin on project: {}", project)
135135
restartIfNecessary()
136+
LivePluginProjectLoader.projectClosing(project)
136137
LivePluginProjectLoader.projectOpened(project)
137138

138139
val config = configInput ?: getConfig(project)

plugin/src/main/kotlin/spp/jetbrains/sourcemarker/mark/SourceMarkSearch.kt

-77
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,10 @@ import com.intellij.openapi.editor.Editor
2020
import com.intellij.openapi.util.TextRange
2121
import spp.jetbrains.marker.SourceMarker
2222
import spp.jetbrains.marker.source.SourceFileMarker
23-
import spp.jetbrains.marker.source.mark.api.MethodSourceMark
2423
import spp.jetbrains.marker.source.mark.api.SourceMark
2524
import spp.jetbrains.marker.source.mark.guide.ClassGuideMark
26-
import spp.jetbrains.marker.source.mark.guide.ExpressionGuideMark
2725
import spp.jetbrains.marker.source.mark.guide.GuideMark
2826
import spp.jetbrains.marker.source.mark.guide.MethodGuideMark
29-
import spp.protocol.artifact.ArtifactQualifiedName
30-
import spp.protocol.artifact.ArtifactType
3127

3228
/**
3329
* todo: description.
@@ -61,12 +57,6 @@ object SourceMarkSearch {
6157
return sourceMark ?: classSourceMark
6258
}
6359

64-
fun findByEndpointName(endpointName: String): GuideMark? {
65-
return SourceMarker.getSourceMarks().filterIsInstance<GuideMark>().firstOrNull {
66-
it.getUserData(SourceMarkKeys.ENDPOINT_DETECTOR)?.getEndpointName(it) == endpointName
67-
}
68-
}
69-
7060
fun findByInstrumentId(instrumentId: String): SourceMark? {
7161
return SourceMarker.getSourceMarks().firstOrNull {
7262
it.getUserData(SourceMarkKeys.INSTRUMENT_ID) == instrumentId
@@ -78,71 +68,4 @@ object SourceMarkSearch {
7868
it.getUserData(SourceMarkKeys.VIEW_SUBSCRIPTION_ID) == subscriptionId
7969
}
8070
}
81-
82-
suspend fun findSourceMark(artifact: ArtifactQualifiedName): GuideMark? {
83-
return when (artifact.type) {
84-
ArtifactType.ENDPOINT -> findEndpointSourceMark(artifact)
85-
ArtifactType.STATEMENT -> findExpressionSourceMark(artifact)
86-
ArtifactType.EXPRESSION -> findExpressionSourceMark(artifact)
87-
else -> TODO("impl")
88-
}
89-
}
90-
91-
fun findSourceMarks(artifact: ArtifactQualifiedName): List<SourceMark> {
92-
return SourceMarker.getSourceMarks().filter { it.artifactQualifiedName == artifact }
93-
}
94-
95-
suspend fun findSourceMark(logPattern: String): MethodSourceMark? {
96-
return SourceMarker.getSourceMarks()
97-
.filterIsInstance<MethodSourceMark>()
98-
.firstOrNull {
99-
it.getUserData(SourceMarkKeys.LOGGER_DETECTOR)!!.getOrFindLoggerStatements(it)
100-
.map { it.logPattern }.contains(logPattern)
101-
}
102-
}
103-
104-
suspend fun findInheritedSourceMarks(logPattern: String): List<SourceMark> {
105-
val rootMark = findSourceMark(logPattern) ?: return emptyList()
106-
return findInheritedSourceMarks(rootMark)
107-
}
108-
109-
fun findInheritedSourceMarks(rootMark: SourceMark): List<SourceMark> {
110-
return if (rootMark.isExpressionMark) {
111-
val methodMark = SourceMarker.getSourceMark(
112-
rootMark.artifactQualifiedName.copy(
113-
identifier = rootMark.artifactQualifiedName.identifier.substringBefore("#"),
114-
type = ArtifactType.METHOD
115-
),
116-
SourceMark.Type.GUTTER
117-
)
118-
//todo: proper class crawl
119-
listOfNotNull(rootMark, methodMark) + rootMark.sourceFileMarker.getClassSourceMarks()
120-
} else if (rootMark.isMethodMark) {
121-
//todo: proper class crawl
122-
listOf(rootMark) + rootMark.sourceFileMarker.getClassSourceMarks()
123-
} else {
124-
listOf(rootMark)
125-
}
126-
}
127-
128-
private suspend fun findEndpointSourceMark(artifact: ArtifactQualifiedName): MethodGuideMark? {
129-
val operationName = artifact.identifier
130-
return SourceMarker.getSourceMarks()
131-
.filterIsInstance<MethodGuideMark>()
132-
.firstOrNull {
133-
it.getUserData(SourceMarkKeys.ENDPOINT_DETECTOR)!!.getOrFindEndpointName(it) == operationName
134-
}
135-
}
136-
137-
private fun findExpressionSourceMark(artifact: ArtifactQualifiedName): ExpressionGuideMark? {
138-
if (artifact.type == ArtifactType.EXPRESSION) {
139-
return SourceMarker.getSourceMarks().filterIsInstance<ExpressionGuideMark>()
140-
.find { it.artifactQualifiedName == artifact }
141-
}
142-
143-
val qualifiedClassName = artifact.identifier.substring(0, artifact.identifier.lastIndexOf("."))
144-
val fileMarker = SourceMarker.getSourceFileMarker(qualifiedClassName)
145-
return fileMarker?.getSourceMarks()?.filterIsInstance<ExpressionGuideMark>()
146-
?.find { it.lineNumber == artifact.lineNumber!! }
147-
}
14871
}

plugin/src/main/resources/logback.xml

+6
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,12 @@
1717
<logger name="spp" level="DEBUG">
1818
<appender-ref ref="STDOUT"/>
1919
</logger>
20+
<logger name="liveplugin" level="INFO">
21+
<appender-ref ref="debug-console"/>
22+
</logger>
23+
<logger name="liveplugin" level="DEBUG">
24+
<appender-ref ref="STDOUT"/>
25+
</logger>
2026

2127
<logger name="io.vertx" level="DEBUG">
2228
<appender-ref ref="STDOUT"/>

0 commit comments

Comments
 (0)