diff --git a/platform/statistics/api-dump-unreviewed.txt b/platform/statistics/api-dump-unreviewed.txt index ce45885f4a01..a43b33918626 100644 --- a/platform/statistics/api-dump-unreviewed.txt +++ b/platform/statistics/api-dump-unreviewed.txt @@ -166,6 +166,7 @@ a:com.intellij.internal.statistic.eventLog.StatisticsEventLoggerProvider - b:(java.lang.String,I,J,I,Z,Z,Z,I,kotlin.jvm.internal.DefaultConstructorMarker):V - createEventsMergeStrategy():com.intellij.internal.statistic.eventLog.StatisticsEventMergeStrategy - f:getActiveLogFile():com.intellij.internal.statistic.eventLog.EventLogFile +- getCoroutineScope():kotlinx.coroutines.CoroutineScope - sf:getEP_NAME():com.intellij.openapi.extensions.ExtensionPointName - f:getLogFilesProvider():com.intellij.internal.statistic.eventLog.EventLogFilesProvider - getLogger():com.intellij.internal.statistic.eventLog.StatisticsEventLogger diff --git a/platform/statistics/src/com/intellij/internal/statistic/StatisticsServiceScope.kt b/platform/statistics/src/com/intellij/internal/statistic/StatisticsServiceScope.kt new file mode 100644 index 000000000000..a5e3b41232a7 --- /dev/null +++ b/platform/statistics/src/com/intellij/internal/statistic/StatisticsServiceScope.kt @@ -0,0 +1,24 @@ +// 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.internal.statistic + +import com.intellij.openapi.components.Service +import com.intellij.openapi.components.service +import com.intellij.openapi.project.Project +import kotlinx.coroutines.* +import org.jetbrains.annotations.ApiStatus + +@ApiStatus.Internal +interface StatisticsServiceScope { + companion object { + fun getScope(project: Project): CoroutineScope = project.service().scope + fun getScope(): CoroutineScope = service().scope + } +} + +@ApiStatus.Internal +@Service(Service.Level.APP) +class StatisticsServiceApplicationScope(val scope: CoroutineScope) + +@ApiStatus.Internal +@Service(Service.Level.PROJECT) +class StatisticsServiceProjectScope(val scope: CoroutineScope) \ No newline at end of file diff --git a/platform/statistics/src/com/intellij/internal/statistic/eventLog/StatisticsEventLogger.kt b/platform/statistics/src/com/intellij/internal/statistic/eventLog/StatisticsEventLogger.kt index f497e522d525..176382333b9c 100644 --- a/platform/statistics/src/com/intellij/internal/statistic/eventLog/StatisticsEventLogger.kt +++ b/platform/statistics/src/com/intellij/internal/statistic/eventLog/StatisticsEventLogger.kt @@ -1,8 +1,9 @@ -// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +// 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.internal.statistic.eventLog import com.intellij.ide.plugins.ProductLoadingStrategy import com.intellij.idea.AppMode +import com.intellij.internal.statistic.StatisticsServiceScope import com.intellij.internal.statistic.eventLog.logger.StatisticsEventLogThrottleWriter import com.intellij.internal.statistic.persistence.UsageStatisticsPersistenceComponent import com.intellij.openapi.application.ApplicationManager @@ -10,6 +11,7 @@ import com.intellij.openapi.diagnostic.logger import com.intellij.openapi.extensions.ExtensionPointName import com.intellij.openapi.util.Disposer import com.intellij.platform.runtime.product.ProductMode +import kotlinx.coroutines.* import java.io.File import java.util.* import java.util.concurrent.CompletableFuture @@ -81,6 +83,7 @@ abstract class StatisticsEventLoggerProvider(val recorderId: String, } } + open val coroutineScope: CoroutineScope = StatisticsServiceScope.getScope() private val localLogger: StatisticsEventLogger by lazy { createLocalLogger() } private val actualLogger: StatisticsEventLogger by lazy { createLogger() } internal val eventLogSystemLogger: EventLogSystemCollector by lazy { EventLogSystemCollector(this) } @@ -137,14 +140,15 @@ abstract class StatisticsEventLoggerProvider(val recorderId: String, val configService = EventLogConfigOptionsService.getInstance() val throttledWriter = StatisticsEventLogThrottleWriter( - configService, recorderId, version.toString(), writer + configService, recorderId, version.toString(), writer, coroutineScope ) val logger = StatisticsFileEventLogger( recorderId, config.sessionId, isHeadless, eventLogConfiguration.build, config.bucket.toString(), version.toString(), throttledWriter, UsageStatisticsPersistenceComponent.getInstance(), createEventsMergeStrategy(), ideMode, productMode ) - Disposer.register(ApplicationManager.getApplication(), logger) + + coroutineScope.coroutineContext.job.invokeOnCompletion { Disposer.dispose(logger) } return logger } diff --git a/platform/statistics/src/com/intellij/internal/statistic/eventLog/logger/StatisticsEventLogThrottleWriter.kt b/platform/statistics/src/com/intellij/internal/statistic/eventLog/logger/StatisticsEventLogThrottleWriter.kt index b399fb7eb60c..12c3345a2913 100644 --- a/platform/statistics/src/com/intellij/internal/statistic/eventLog/logger/StatisticsEventLogThrottleWriter.kt +++ b/platform/statistics/src/com/intellij/internal/statistic/eventLog/logger/StatisticsEventLogThrottleWriter.kt @@ -1,21 +1,24 @@ -// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// 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.internal.statistic.eventLog.logger -import com.intellij.application.subscribe import com.intellij.internal.statistic.eventLog.* import com.intellij.internal.statistic.eventLog.EventLogConfigOptionsService.EventLogThresholdConfigOptionsListener import com.intellij.internal.statistic.utils.EventRateThrottleResult import com.intellij.internal.statistic.utils.EventsIdentityWindowThrottle import com.intellij.internal.statistic.utils.EventsRateWindowThrottle +import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.components.service import com.intellij.openapi.util.Disposer import com.jetbrains.fus.reporting.model.lion3.LogEvent import com.jetbrains.fus.reporting.model.lion3.LogEventAction import com.jetbrains.fus.reporting.model.lion3.LogEventGroup +import kotlinx.coroutines.CoroutineScope internal class StatisticsEventLogThrottleWriter(configOptionsService: EventLogConfigOptionsService, private val recorderId: String, private val recorderVersion: String, - private val delegate: StatisticsEventLogWriter) : StatisticsEventLogWriter { + private val delegate: StatisticsEventLogWriter, + coroutineScope: CoroutineScope) : StatisticsEventLogWriter { private val ourLock: Any = Object() /** @@ -37,7 +40,7 @@ internal class StatisticsEventLogThrottleWriter(configOptionsService: EventLogCo val groupAlertThreshold = getOrDefault(configOptions.groupAlertThreshold, 6000) ourGroupThrottle = EventsIdentityWindowThrottle(groupThreshold, groupAlertThreshold, 60L * 60 * 1000) - EventLogConfigOptionsService.TOPIC.subscribe(this, object : EventLogThresholdConfigOptionsListener(recorderId) { + ApplicationManager.getApplication().messageBus.connect(coroutineScope).subscribe(EventLogConfigOptionsService.TOPIC, object : EventLogThresholdConfigOptionsListener(recorderId) { override fun onThresholdChanged(newValue: Int) { if (newValue > 0) { synchronized(ourLock) {