From 8fb76f1f9ff40ba43fc8e110190f58f87f2861b5 Mon Sep 17 00:00:00 2001 From: Victor Matchenko Date: Tue, 7 Mar 2023 17:23:51 +0100 Subject: [PATCH] IDEA-314605 use one listener per recorder Add method parameter to EP method so extension can implement different listeners for each recorder it can follow GitOrigin-RevId: 8a2ddb6971efe086684c43f481febe066dd6ba65 --- .../eventLog/EventLogListenersManager.kt | 37 +++++++++++-------- .../eventLog/ExternalEventLogSettings.java | 6 ++- 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/platform/statistics/src/com/intellij/internal/statistic/eventLog/EventLogListenersManager.kt b/platform/statistics/src/com/intellij/internal/statistic/eventLog/EventLogListenersManager.kt index a85b8a13a164..2c1657e0188d 100644 --- a/platform/statistics/src/com/intellij/internal/statistic/eventLog/EventLogListenersManager.kt +++ b/platform/statistics/src/com/intellij/internal/statistic/eventLog/EventLogListenersManager.kt @@ -1,6 +1,7 @@ // Copyright 2000-2023 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.concurrency.ConcurrentCollectionFactory import com.intellij.internal.statistic.eventLog.StatisticsEventLogProviderUtil.getExternalEventLogSettings import com.intellij.internal.statistic.utils.getPluginInfo import com.intellij.openapi.application.ApplicationManager @@ -15,38 +16,42 @@ import org.jetbrains.annotations.ApiStatus @Service(Service.Level.APP) class EventLogListenersManager { private val subscribers = MultiMap.createConcurrent() - private var listenerFromEP: StatisticsEventLogListener? = null + private var listenersFromEP = ConcurrentCollectionFactory.createConcurrentMap() init { if (ApplicationManager.getApplication().extensionArea.hasExtensionPoint(ExternalEventLogSettings.EP_NAME)) { - addListenerFromEP() + addListenersFromEP() + // Support for dynamic plugin ExternalEventLogSettings.EP_NAME.addExtensionPointListener(object : ExtensionPointListener { - override fun extensionAdded(extension: ExternalEventLogSettings, pluginDescriptor: PluginDescriptor) { - addListenerFromEP() - } + override fun extensionAdded(extension: ExternalEventLogSettings, pluginDescriptor: PluginDescriptor) = addListenersFromEP() override fun extensionRemoved(extension: ExternalEventLogSettings, pluginDescriptor: PluginDescriptor) { - if (listenerFromEP == null) return + if (listenersFromEP.isEmpty()) return // Do not filter providers by isForceCollectionEnabled flag as it can be dynamic - StatisticsEventLogProviderUtil.getEventLogProviders().forEach { provider -> - unsubscribe(listenerFromEP!!, provider.recorderId) + StatisticsEventLogProviderUtil.getEventLogProviders().map { it.recorderId }.forEach { recorderId -> + listenersFromEP[recorderId]?.let { listener -> + unsubscribe(listener, recorderId) + listenersFromEP.remove(recorderId) + } } - listenerFromEP = null } }) } } - private fun addListenerFromEP() { - if (listenerFromEP != null) return // Only one EP instance can exist do not bother if listener has been set + private fun addListenersFromEP() { + StatisticsEventLogProviderUtil.getEventLogProviders().filter { it.isForceCollectionEnabled() } + .map { it.recorderId }.forEach { addListenerFromEP(it) } + } + + private fun addListenerFromEP(recorderId: String) { + if (listenersFromEP[recorderId] != null) return // Only one EP instance can exist so do not bother if another listener has been registered for this recorderId val externalEventLogSettings = getExternalEventLogSettings() externalEventLogSettings?.let { - externalEventLogSettings.eventLogListener?.let { eventLogListener -> - listenerFromEP = eventLogListener - StatisticsEventLogProviderUtil.getEventLogProviders().filter { it.isForceCollectionEnabled() }.forEach { provider -> - subscribe(eventLogListener, provider.recorderId) - } + externalEventLogSettings.getEventLogListener(recorderId)?.let { eventLogListener -> + listenersFromEP[recorderId] = eventLogListener + subscribe(eventLogListener, recorderId) } } } diff --git a/platform/statistics/src/com/intellij/internal/statistic/eventLog/ExternalEventLogSettings.java b/platform/statistics/src/com/intellij/internal/statistic/eventLog/ExternalEventLogSettings.java index 454182d3a245..06c7376cd93d 100644 --- a/platform/statistics/src/com/intellij/internal/statistic/eventLog/ExternalEventLogSettings.java +++ b/platform/statistics/src/com/intellij/internal/statistic/eventLog/ExternalEventLogSettings.java @@ -92,9 +92,11 @@ public interface ExternalEventLogSettings { /** * Provides implementations of {@link StatisticsEventLogListener} to be used in {@link EventLogListenersManager} *
- * This method will be called only once. + * This method will be called only once per recorder on IDE start or plugin loading (for dynamic plugins) + * + * @param recorderId of a recorder which logs will trigger provided listener * */ - default @Nullable StatisticsEventLogListener getEventLogListener() { + default @Nullable StatisticsEventLogListener getEventLogListener(@NotNull String recorderId) { return null; } }