mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-02-05 08:06:56 +07:00
GTW-4243 Refactor notifications flow for remote sessions
Instead of subscribing to the notification topic and sending received notifications to a client, choose what notification should process the notification. That would prevent notification duplication in RD mode (we were processing the same notification twice - by backend and local managers) To achieve described behavior: - Introduce NotificationRouter as an extension poitn and different implementations for local/controller/guest scenarios. The notification will be processed by the first applicable router - Move NotificationsListener outside NotificationsManagerImpl, so we could process notifications by the right router - add showNotification method to NotificationsManager abstract class, so we can access it from outside - BackendNotificationsHost becomes application-level service (instead of project-level) Notification routers: - Guest: If notifications is sent under client's id, we send notification to that client - Controller: If notification is sent under local id, we check is there an active controller session (we are in RD mode). If there is, we sent all notifications to that controller - Local: Otherwise we process notification by the local manager GitOrigin-RevId: c6f9e365c15acfea81145a9acf33ff8bb82013a5
This commit is contained in:
committed by
intellij-monorepo-bot
parent
20f970b928
commit
3f17df6bc4
@@ -0,0 +1,27 @@
|
||||
// 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.notification
|
||||
|
||||
import com.intellij.openapi.extensions.ExtensionPointName
|
||||
import com.intellij.openapi.project.Project
|
||||
|
||||
/**
|
||||
* Interface for a notification router.
|
||||
*
|
||||
* This interface defines a method for routing a notification to some notification manager
|
||||
* Implementations of this interface can be registered as extension points.
|
||||
*/
|
||||
interface NotificationRouter {
|
||||
|
||||
/**
|
||||
* Routes a notification to some notification manager to be processed
|
||||
*
|
||||
* @param notification The notification to be routed.
|
||||
* @param project The project notification should be shown for
|
||||
* @return Returns true if the notification is routed to some manager, false otherwise.
|
||||
*/
|
||||
fun routeNotification(notification: Notification, project: Project?): Boolean
|
||||
|
||||
companion object {
|
||||
val EP_NAME: ExtensionPointName<NotificationRouter> = ExtensionPointName("com.intellij.notificationRouter")
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,8 @@ public abstract class NotificationsManager {
|
||||
return ApplicationManager.getApplication().getService(NotificationsManager.class);
|
||||
}
|
||||
|
||||
public abstract void showNotification(@NotNull Notification notification, @Nullable Project project);
|
||||
|
||||
public abstract void expire(@NotNull Notification notification);
|
||||
|
||||
public abstract <T extends Notification> T @NotNull [] getNotificationsOfType(@NotNull Class<T> klass, @Nullable Project project);
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
// 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.notification.impl
|
||||
|
||||
import com.intellij.notification.Notification
|
||||
import com.intellij.notification.NotificationRouter
|
||||
import com.intellij.openapi.project.Project
|
||||
|
||||
class LocalNotificationRouter: NotificationRouter {
|
||||
override fun routeNotification(notification: Notification, project: Project?): Boolean {
|
||||
NotificationsManagerImpl.getNotificationsManager().showNotification(notification, project)
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
// 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.notification.impl
|
||||
|
||||
import com.intellij.notification.Notification
|
||||
import com.intellij.notification.NotificationRouter
|
||||
import com.intellij.notification.Notifications
|
||||
import com.intellij.notification.impl.NotificationsManagerImpl.isDummyEnvironment
|
||||
import com.intellij.openapi.diagnostic.logger
|
||||
import com.intellij.openapi.extensions.ExtensionNotApplicableException
|
||||
import com.intellij.openapi.project.Project
|
||||
|
||||
class NotificationsListener : Notifications {
|
||||
private val project: Project?
|
||||
|
||||
@Suppress("unused")
|
||||
constructor() {
|
||||
project = null
|
||||
}
|
||||
|
||||
@Suppress("unused")
|
||||
private constructor(project: Project?) {
|
||||
this.project = project
|
||||
if (isDummyEnvironment()) {
|
||||
throw ExtensionNotApplicableException.create()
|
||||
}
|
||||
}
|
||||
|
||||
override fun notify(notification: Notification) {
|
||||
for (listener in NotificationRouter.EP_NAME.extensionList) {
|
||||
try {
|
||||
if (listener.routeNotification(notification, project)) {
|
||||
return
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
LOG.error(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val LOG = logger<NotificationsListener>()
|
||||
}
|
||||
}
|
||||
@@ -126,7 +126,8 @@ public final class NotificationsManagerImpl extends NotificationsManager {
|
||||
return ArrayUtil.toObjectArray(result, klass);
|
||||
}
|
||||
|
||||
private void doNotify(Notification notification, @Nullable Project project) {
|
||||
@Override
|
||||
public void showNotification(@NotNull Notification notification, @Nullable Project project) {
|
||||
NotificationsConfigurationImpl configuration = NotificationsConfigurationImpl.getInstanceImpl();
|
||||
NotificationSettings settings = NotificationsConfigurationImpl.getSettings(notification.getGroupId());
|
||||
|
||||
@@ -166,7 +167,7 @@ public final class NotificationsManagerImpl extends NotificationsManager {
|
||||
}
|
||||
|
||||
@RequiresEdt
|
||||
private void showNotification(Notification notification, @Nullable Project project) {
|
||||
private void showNotificationInner(Notification notification, @Nullable Project project) {
|
||||
if (LOG.isDebugEnabled()) LOG.debug("incoming: " + notification + ", project=" + project);
|
||||
|
||||
if (myEarlyNotifications != null) {
|
||||
@@ -297,7 +298,7 @@ public final class NotificationsManagerImpl extends NotificationsManager {
|
||||
span.setAttribute("project", project.toString());
|
||||
}
|
||||
span.setAttribute("notification", notification.toString());
|
||||
showNotification(notification, project);
|
||||
showNotificationInner(notification, project);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1135,7 +1136,7 @@ public final class NotificationsManagerImpl extends NotificationsManager {
|
||||
return text.getPreferredSize().height;
|
||||
}
|
||||
|
||||
private static boolean isDummyEnvironment() {
|
||||
static boolean isDummyEnvironment() {
|
||||
Application app = ApplicationManager.getApplication();
|
||||
return app.isUnitTestMode() || app.isCommandLine();
|
||||
}
|
||||
@@ -1234,27 +1235,6 @@ public final class NotificationsManagerImpl extends NotificationsManager {
|
||||
return null;
|
||||
}
|
||||
|
||||
static final class MyNotificationListener implements Notifications {
|
||||
private final Project project;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
MyNotificationListener() {
|
||||
project = null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private MyNotificationListener(@Nullable Project project) {
|
||||
this.project = project;
|
||||
if (isDummyEnvironment()) {
|
||||
throw ExtensionNotApplicableException.create();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notify(@NotNull Notification notification) {
|
||||
((NotificationsManagerImpl)NotificationsManager.getNotificationsManager()).doNotify(notification, project);
|
||||
}
|
||||
}
|
||||
|
||||
private static @Nullable Point getCollapsedTextEndLocation(JEditorPane text, BalloonLayoutData layoutData) {
|
||||
try {
|
||||
|
||||
@@ -524,5 +524,6 @@
|
||||
|
||||
<extensionPoint name="meetNewUiCustomization" interface="com.intellij.ide.ui.experimental.meetNewUi.MeetNewUiCustomization" dynamic="true"/>
|
||||
|
||||
<extensionPoint name="notificationRouter" interface="com.intellij.notification.NotificationRouter" dynamic="true"/>
|
||||
</extensionPoints>
|
||||
</idea-plugin>
|
||||
|
||||
@@ -1552,6 +1552,8 @@
|
||||
<toolbarQuickAction implementationClass="com.intellij.openapi.wm.impl.headertoolbar.BuildQuickAction" listGroupID="MainToolbarQuickActions.Run" />
|
||||
<toolbarQuickAction implementationClass="com.intellij.openapi.wm.impl.headertoolbar.CoverageQuickAction" listGroupID="MainToolbarQuickActions.Run" />
|
||||
<toolbarQuickAction implementationClass="com.intellij.openapi.wm.impl.headertoolbar.ProfilerQuickAction" listGroupID="MainToolbarQuickActions.Run" />
|
||||
|
||||
<notificationRouter implementation="com.intellij.notification.impl.LocalNotificationRouter" order="last"/>
|
||||
</extensions>
|
||||
|
||||
<extensions defaultExtensionNs="org.jetbrains">
|
||||
@@ -1612,7 +1614,7 @@
|
||||
</applicationListeners>
|
||||
|
||||
<projectListeners>
|
||||
<listener class="com.intellij.notification.impl.NotificationsManagerImpl$MyNotificationListener"
|
||||
<listener class="com.intellij.notification.impl.NotificationsListener"
|
||||
activeInHeadlessMode="false"
|
||||
activeInTestMode="false"
|
||||
topic="com.intellij.notification.Notifications"/>
|
||||
|
||||
@@ -182,7 +182,7 @@
|
||||
|
||||
<listener class="com.intellij.notification.impl.NotificationsToolWindowNotificationListener"
|
||||
topic="com.intellij.notification.Notifications"/>
|
||||
<listener class="com.intellij.notification.impl.NotificationsManagerImpl$MyNotificationListener"
|
||||
<listener class="com.intellij.notification.impl.NotificationsListener"
|
||||
topic="com.intellij.notification.Notifications"/>
|
||||
<listener class="com.intellij.notification.impl.NotificationsConfigurationImpl$MyNotificationListener"
|
||||
topic="com.intellij.notification.Notifications"/>
|
||||
|
||||
Reference in New Issue
Block a user