From 8b2fe884152d7bb03e0a8ac0753fdc84df541ce9 Mon Sep 17 00:00:00 2001 From: mrproliu <741550557@qq.com> Date: Mon, 17 Jul 2023 09:07:38 +0800 Subject: [PATCH] Using cache reference for query UI menu (#11099) --- .../oap/server/core/CoreModuleProvider.java | 4 +- .../management/ui/menu/UIMenuInitializer.java | 4 +- .../ui/menu/UIMenuManagementService.java | 74 ++++++++----------- 3 files changed, 34 insertions(+), 48 deletions(-) diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/CoreModuleProvider.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/CoreModuleProvider.java index e278b7b0f8..68536b5c50 100755 --- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/CoreModuleProvider.java +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/CoreModuleProvider.java @@ -329,7 +329,7 @@ public class CoreModuleProvider extends ModuleProvider { this.registerServiceImplementation( UITemplateManagementService.class, new UITemplateManagementService(getManager())); this.registerServiceImplementation( - UIMenuManagementService.class, new UIMenuManagementService(getManager())); + UIMenuManagementService.class, new UIMenuManagementService(getManager(), moduleConfig)); if (moduleConfig.getMetricsDataTTL() < 2) { throw new ModuleStartException( @@ -433,7 +433,7 @@ public class CoreModuleProvider extends ModuleProvider { } try { - new UIMenuInitializer(getManager()).start(moduleConfig.getUiMenuRefreshInterval()); + new UIMenuInitializer(getManager()).init(); } catch (IOException e) { throw new ModuleStartException(e.getMessage(), e); } diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/management/ui/menu/UIMenuInitializer.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/management/ui/menu/UIMenuInitializer.java index c8e814fca8..d9c12a504e 100644 --- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/management/ui/menu/UIMenuInitializer.java +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/management/ui/menu/UIMenuInitializer.java @@ -45,7 +45,7 @@ public class UIMenuInitializer { .getService(UIMenuManagementService.class); } - public void start(int fetchIntervalSecond) throws IOException { + public void init() throws IOException { final var menuFile = "ui-initialized-templates/menu.yaml"; try { Reader menuReader = ResourceUtils.read(menuFile); @@ -56,7 +56,7 @@ public class UIMenuInitializer { } // save menu and start fetch menu - uiMenuManagementService.saveMenuAndStartFetch(menuData.getMenus(), fetchIntervalSecond); + uiMenuManagementService.saveMenu(menuData.getMenus()); } catch (FileNotFoundException e) { log.debug("No such file of path: {}, skipping loading UI menu.", menuFile); } diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/management/ui/menu/UIMenuManagementService.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/management/ui/menu/UIMenuManagementService.java index a552127a6f..0d2f936fdb 100644 --- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/management/ui/menu/UIMenuManagementService.java +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/management/ui/menu/UIMenuManagementService.java @@ -18,10 +18,15 @@ package org.apache.skywalking.oap.server.core.management.ui.menu; +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; import com.google.common.reflect.TypeToken; import com.google.gson.Gson; +import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.apache.skywalking.oap.server.core.CoreModule; +import org.apache.skywalking.oap.server.core.CoreModuleConfig; import org.apache.skywalking.oap.server.core.query.MetadataQueryService; import org.apache.skywalking.oap.server.core.query.type.MenuItem; import org.apache.skywalking.oap.server.core.storage.StorageModule; @@ -35,25 +40,29 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; @Slf4j -public class UIMenuManagementService implements Service, Runnable { +public class UIMenuManagementService implements Service { private static final String MENU_ID = "1"; private static final Gson GSON = new Gson(); - private static final int MENU_GET_MAX_SECOND = 3; + private final LoadingCache> menuItemCache; private UIMenuManagementDAO menuDAO; private ModuleManager moduleManager; - private CompletableFuture> menuItemFuture; - private boolean isMenuItemsBeenFetched = false; private MetadataQueryService metadataQueryService; - public UIMenuManagementService(ModuleManager moduleManager) { + public UIMenuManagementService(ModuleManager moduleManager, CoreModuleConfig moduleConfig) { this.moduleManager = moduleManager; - this.menuItemFuture = new CompletableFuture<>(); + this.menuItemCache = CacheBuilder.newBuilder() + .maximumSize(1) + .refreshAfterWrite(moduleConfig.getUiMenuRefreshInterval(), TimeUnit.SECONDS) + .build(new CacheLoader<>() { + @Override + public List load(Boolean key) throws Exception { + return fetchMenuItems(); + } + }); } private UIMenuManagementDAO getMenuDAO() { @@ -70,10 +79,10 @@ public class UIMenuManagementService implements Service, Runnable { return metadataQueryService; } - public void saveMenuAndStartFetch(List menuItems, int fetchInterval) throws IOException { + public void saveMenu(List menuItems) throws IOException { // ignore if already existing if (getMenuDAO().getMenu(MENU_ID) != null) { - startingFetchMenu(fetchInterval); + this.getMenuItems(); return; } @@ -83,46 +92,23 @@ public class UIMenuManagementService implements Service, Runnable { menu.setConfigurationJson(GSON.toJson(menuItems)); getMenuDAO().saveMenu(menu); - startingFetchMenu(fetchInterval); - } - - private void startingFetchMenu(int fetchIntervalSecond) { - Executors.newSingleThreadScheduledExecutor() - .scheduleWithFixedDelay(this, 0, fetchIntervalSecond, java.util.concurrent.TimeUnit.SECONDS); + this.getMenuItems(); } + @SneakyThrows public List getMenuItems() { - try { - return menuItemFuture.get(MENU_GET_MAX_SECOND, TimeUnit.SECONDS); - } catch (Throwable t) { - throw new IllegalStateException("Failed to get menu items", t); - } + return menuItemCache.get(true); } - @Override - public void run() { - try { - UIMenu menu = getMenuDAO().getMenu(MENU_ID); - if (menu == null) { - log.warn("cannot find the menu data from storage"); - return; - } - - List menuItems = GSON.fromJson(menu.getConfigurationJson(), new TypeToken>() { - }.getType()); - final List items = this.convertToMenuItems(menuItems); - // if the menu haven't been fetched one time, then just complete it - if (!isMenuItemsBeenFetched) { - menuItemFuture.complete(items); - isMenuItemsBeenFetched = true; - } else { - // otherwise, the value should be updated to new one - menuItemFuture = CompletableFuture.completedFuture(items); - } - } catch (Throwable t) { - log.warn("Failed to fetch menu items", t); - menuItemFuture.completeExceptionally(t); + private List fetchMenuItems() throws IOException { + UIMenu menu = getMenuDAO().getMenu(MENU_ID); + if (menu == null) { + throw new IllegalStateException("cannot found UI menu"); } + + List menuItems = GSON.fromJson(menu.getConfigurationJson(), new TypeToken>() { + }.getType()); + return this.convertToMenuItems(menuItems); } private List convertToMenuItems(List settings) throws IOException {