mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-03-22 15:19:59 +07:00
[stats-collector] eliminating unneeded abstractions over service status
GitOrigin-RevId: 72afd295fa24447b7a29541ac98f3eae39eb90b2
This commit is contained in:
committed by
intellij-monorepo-bot
parent
9759360eec
commit
bdaef0b795
@@ -1,52 +0,0 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.stats.completion.network.status
|
||||
|
||||
import com.intellij.openapi.application.ApplicationInfo
|
||||
import com.intellij.openapi.components.service
|
||||
import com.intellij.openapi.diagnostic.logger
|
||||
import com.intellij.stats.completion.network.assertNotEDT
|
||||
import com.intellij.stats.completion.network.service.RequestService
|
||||
import com.intellij.stats.completion.network.status.bean.AnalyticsPlatformSettingsDeserializer
|
||||
|
||||
class AnalyticsPlatformServiceStatus(private val statusUrl: String) : WebServiceStatus {
|
||||
companion object {
|
||||
private val LOG = logger<AnalyticsPlatformServiceStatus>()
|
||||
private fun productCode(): String = ApplicationInfo.getInstance().build.productCode
|
||||
|
||||
fun withDefaultUrl(): AnalyticsPlatformServiceStatus =
|
||||
AnalyticsPlatformServiceStatus("https://resources.jetbrains.com/storage/ap/mlcc/config/v1/${productCode()}.json")
|
||||
}
|
||||
@Volatile
|
||||
private var isServerOk = false
|
||||
@Volatile
|
||||
private var dataServerUrl = ""
|
||||
|
||||
override val id: String = "AnalyticsPlatform"
|
||||
|
||||
override fun isServerOk(): Boolean = isServerOk
|
||||
|
||||
override fun dataServerUrl(): String = dataServerUrl
|
||||
|
||||
override fun update() {
|
||||
isServerOk = false
|
||||
dataServerUrl = ""
|
||||
|
||||
assertNotEDT()
|
||||
val response = service<RequestService>().get(statusUrl)
|
||||
if (response != null && response.isOK()) {
|
||||
val settings = AnalyticsPlatformSettingsDeserializer.deserialize(response.text) ?: return
|
||||
|
||||
val satisfyingEndpoints = settings.versions.filter { it.satisfies() && it.endpoint != null }
|
||||
if (satisfyingEndpoints.isEmpty()) {
|
||||
LOG.debug("Analytics Platform completion web service status. No satisfying endpoints.")
|
||||
return
|
||||
}
|
||||
if (satisfyingEndpoints.size > 1) {
|
||||
LOG.error("Analytics Platform completion web service status. More than one satisfying endpoints. First one will be used.")
|
||||
}
|
||||
val endpointSettings = satisfyingEndpoints.first()
|
||||
isServerOk = true
|
||||
dataServerUrl = endpointSettings.endpoint!!
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.stats.completion.network.status
|
||||
|
||||
interface WebServiceStatus {
|
||||
val id: String
|
||||
|
||||
fun isServerOk(): Boolean
|
||||
fun dataServerUrl(): String
|
||||
|
||||
fun update()
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.stats.completion.network.status
|
||||
|
||||
import com.intellij.openapi.diagnostic.logger
|
||||
import com.intellij.openapi.util.registry.Registry
|
||||
|
||||
object WebServiceStatusManager {
|
||||
private const val USE_ANALYTICS_PLATFORM_REGISTRY = "completion.stats.analytics.platform.send"
|
||||
private const val ANALYTICS_PLATFORM_URL_REGISTRY = "completion.stats.analytics.platform.url"
|
||||
private val LOG = logger<WebServiceStatusManager>()
|
||||
private val statuses: MutableMap<String, WebServiceStatus> = mutableMapOf()
|
||||
|
||||
init {
|
||||
if (Registry.`is`(USE_ANALYTICS_PLATFORM_REGISTRY, false)) {
|
||||
registerAnalyticsPlatformStatus()
|
||||
}
|
||||
}
|
||||
|
||||
fun getAllStatuses(): List<WebServiceStatus> = statuses.values.toList()
|
||||
|
||||
private fun registerAnalyticsPlatformStatus() {
|
||||
try {
|
||||
val registry = Registry.get(ANALYTICS_PLATFORM_URL_REGISTRY)
|
||||
if (registry.isChangedFromDefault()) {
|
||||
register(AnalyticsPlatformServiceStatus(registry.asString()))
|
||||
return
|
||||
}
|
||||
}
|
||||
catch (e: Throwable) {
|
||||
LOG.error("No url for Analytics Platform web status. Set registry: $ANALYTICS_PLATFORM_URL_REGISTRY")
|
||||
}
|
||||
register(AnalyticsPlatformServiceStatus.withDefaultUrl())
|
||||
}
|
||||
|
||||
private fun register(status: WebServiceStatus) {
|
||||
val old = statuses[status.id]
|
||||
if (old != null) {
|
||||
LOG.warn("Service status with id [${old.id}] already created.")
|
||||
return
|
||||
}
|
||||
|
||||
statuses[status.id] = status
|
||||
}
|
||||
}
|
||||
@@ -1,60 +1,72 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.stats.completion.sender
|
||||
|
||||
import com.intellij.ide.ApplicationActivity
|
||||
import com.intellij.internal.statistic.utils.StatisticsUploadAssistant
|
||||
import com.intellij.openapi.application.ApplicationInfo
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.components.service
|
||||
import com.intellij.openapi.diagnostic.getOrLogException
|
||||
import com.intellij.openapi.diagnostic.logger
|
||||
import com.intellij.openapi.extensions.ExtensionNotApplicableException
|
||||
import com.intellij.stats.completion.network.status.WebServiceStatusManager
|
||||
import com.intellij.openapi.util.registry.Registry
|
||||
import com.intellij.stats.completion.network.service.RequestService
|
||||
import com.intellij.stats.completion.network.status.bean.AnalyticsPlatformSettingsDeserializer
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.ensureActive
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlin.coroutines.coroutineContext
|
||||
import kotlin.time.Duration.Companion.minutes
|
||||
|
||||
private fun isSendAllowed(): Boolean {
|
||||
return isCompletionLogsSendAllowed() && StatisticsUploadAssistant.isSendAllowed()
|
||||
}
|
||||
internal fun isCompletionLogsSendAllowed(): Boolean =
|
||||
ApplicationManager.getApplication().isEAP && System.getProperty("completion.stats.send.logs", "true").toBoolean()
|
||||
|
||||
internal fun isCompletionLogsSendAllowed(): Boolean {
|
||||
return ApplicationManager.getApplication().isEAP && System.getProperty("completion.stats.send.logs", "true").toBoolean()
|
||||
}
|
||||
private const val USE_ANALYTICS_PLATFORM_KEY = "completion.stats.analytics.platform.send"
|
||||
private const val ANALYTICS_PLATFORM_URL_KEY = "completion.stats.analytics.platform.url"
|
||||
|
||||
private val LOG = logger<SenderPreloadingActivity>()
|
||||
|
||||
private class SenderPreloadingActivity : ApplicationActivity {
|
||||
private val statusUrl: String
|
||||
|
||||
init {
|
||||
val app = ApplicationManager.getApplication()
|
||||
if (app.isUnitTestMode || app.isHeadlessEnvironment) {
|
||||
if (app.isUnitTestMode || app.isHeadlessEnvironment || !Registry.`is`(USE_ANALYTICS_PLATFORM_KEY, false)) {
|
||||
throw ExtensionNotApplicableException.create()
|
||||
}
|
||||
statusUrl = Registry.get(ANALYTICS_PLATFORM_URL_KEY).takeIf { it.isChangedFromDefault() }?.asString()
|
||||
?: "https://resources.jetbrains.com/storage/ap/mlcc/config/v1/${ApplicationInfo.getInstance().build.productCode}.json"
|
||||
}
|
||||
|
||||
override suspend fun execute() {
|
||||
// do not check right after the start - avoid getting UsageStatisticsPersistenceComponent too early
|
||||
delay(5.minutes)
|
||||
while (isSendAllowed()) {
|
||||
while (isCompletionLogsSendAllowed() && StatisticsUploadAssistant.isSendAllowed()) {
|
||||
delay(5.minutes)
|
||||
runCatching {
|
||||
send()
|
||||
}.getOrLogException(logger<SenderPreloadingActivity>())
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun send() {
|
||||
for (status in WebServiceStatusManager.getAllStatuses()) {
|
||||
coroutineContext.ensureActive()
|
||||
|
||||
runCatching {
|
||||
status.update()
|
||||
if (status.isServerOk()) {
|
||||
withContext(Dispatchers.IO) {
|
||||
service<StatisticSender>().sendStatsData(status.dataServerUrl())
|
||||
withContext(Dispatchers.IO) {
|
||||
runCatching {
|
||||
updateAndGetUrl()?.let { url ->
|
||||
service<StatisticSender>().sendStatsData(url)
|
||||
}
|
||||
}.onFailure {
|
||||
LOG.error(it)
|
||||
}
|
||||
}.getOrLogException(logger<SenderPreloadingActivity>())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateAndGetUrl(): String? {
|
||||
val response = service<RequestService>().get(statusUrl)
|
||||
if (response == null || !response.isOK()) return null
|
||||
|
||||
val settings = AnalyticsPlatformSettingsDeserializer.deserialize(response.text) ?: return null
|
||||
|
||||
val satisfyingEndpoints = settings.versions.filter { it.satisfies() && it.endpoint != null }
|
||||
if (satisfyingEndpoints.isEmpty()) {
|
||||
LOG.debug("Analytics Platform completion web service status. No satisfying endpoints.")
|
||||
return null
|
||||
}
|
||||
if (satisfyingEndpoints.size > 1) {
|
||||
LOG.error("Analytics Platform completion web service status. More than one satisfying endpoints. First one will be used.")
|
||||
}
|
||||
return satisfyingEndpoints.first().endpoint!!
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user