diff --git a/code/api/executor-api/src/main/java/nu/marginalia/executor/client/ExecutorClient.java b/code/api/executor-api/src/main/java/nu/marginalia/executor/client/ExecutorClient.java index 8a67cb1d6..51fa06c6e 100644 --- a/code/api/executor-api/src/main/java/nu/marginalia/executor/client/ExecutorClient.java +++ b/code/api/executor-api/src/main/java/nu/marginalia/executor/client/ExecutorClient.java @@ -1,8 +1,10 @@ package nu.marginalia.executor.client; import com.google.inject.Inject; +import io.reactivex.rxjava3.core.Observable; import nu.marginalia.client.AbstractDynamicClient; import nu.marginalia.client.Context; +import nu.marginalia.client.exception.RouteNotConfiguredException; import nu.marginalia.executor.model.ActorRunStates; import nu.marginalia.executor.model.load.LoadParameters; import nu.marginalia.executor.model.transfer.TransferItem; @@ -18,6 +20,8 @@ import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; import java.util.concurrent.TimeUnit; public class ExecutorClient extends AbstractDynamicClient { @@ -63,11 +67,6 @@ public void calculateAdjacencies(Context ctx, int node) { post(ctx, node, "/process/adjacency-calculation", "").blockingSubscribe(); } - public void exportData(Context ctx) { -// post(ctx, node, "/process/adjacency-calculation/", "").blockingSubscribe(); - // FIXME this shouldn't be done in the executor - } - public void sideloadEncyclopedia(Context ctx, int node, Path sourcePath, String baseUrl) { post(ctx, node, "/sideload/encyclopedia?path="+ URLEncoder.encode(sourcePath.toString(), StandardCharsets.UTF_8) + "&baseUrl=" + URLEncoder.encode(baseUrl, StandardCharsets.UTF_8), @@ -110,15 +109,33 @@ public void restoreBackup(Context context, int node, String fid) { } public ActorRunStates getActorStates(Context context, int node) { - return get(context, node, "/actor", ActorRunStates.class).blockingFirst(); + try { + return get(context, node, "/actor", ActorRunStates.class).blockingFirst(); + } + catch (RouteNotConfiguredException ex) { + // node is down, return dummy data + return new ActorRunStates(node, new ArrayList<>()); + } } public UploadDirContents listSideloadDir(Context context, int node) { - return get(context, node, "/sideload/", UploadDirContents.class).blockingFirst(); + try { + return get(context, node, "/sideload/", UploadDirContents.class).blockingFirst(); + } + catch (RouteNotConfiguredException ex) { + // node is down, return dummy data + return new UploadDirContents("/", new ArrayList<>()); + } } public FileStorageContent listFileStorage(Context context, int node, FileStorageId fileId) { - return get(context, node, "/storage/"+fileId.id(), FileStorageContent.class).blockingFirst(); + try { + return get(context, node, "/storage/"+fileId.id(), FileStorageContent.class).blockingFirst(); + } + catch (RouteNotConfiguredException ex) { + // node is down, return dummy data + return new FileStorageContent(new ArrayList<>()); + } } public void transferFile(Context context, int node, FileStorageId fileId, String path, OutputStream destOutputStream) { diff --git a/code/common/config/src/main/java/nu/marginalia/nodecfg/model/NodeConfiguration.java b/code/common/config/src/main/java/nu/marginalia/nodecfg/model/NodeConfiguration.java index 10816f0fc..fb7c7aba8 100644 --- a/code/common/config/src/main/java/nu/marginalia/nodecfg/model/NodeConfiguration.java +++ b/code/common/config/src/main/java/nu/marginalia/nodecfg/model/NodeConfiguration.java @@ -9,4 +9,7 @@ public record NodeConfiguration(int node, boolean disabled ) { + public int getId() { + return node; + } } diff --git a/code/services-core/control-service/src/main/java/nu/marginalia/control/node/model/IndexNode.java b/code/services-core/control-service/src/main/java/nu/marginalia/control/node/model/IndexNode.java deleted file mode 100644 index 6748a2ce5..000000000 --- a/code/services-core/control-service/src/main/java/nu/marginalia/control/node/model/IndexNode.java +++ /dev/null @@ -1,4 +0,0 @@ -package nu.marginalia.control.node.model; - -public record IndexNode(int id) { -} diff --git a/code/services-core/control-service/src/main/java/nu/marginalia/control/node/svc/ControlNodeService.java b/code/services-core/control-service/src/main/java/nu/marginalia/control/node/svc/ControlNodeService.java index 1c15599d8..dd3533932 100644 --- a/code/services-core/control-service/src/main/java/nu/marginalia/control/node/svc/ControlNodeService.java +++ b/code/services-core/control-service/src/main/java/nu/marginalia/control/node/svc/ControlNodeService.java @@ -183,7 +183,7 @@ private Object newSpecsModel(Request request, Response response) throws SQLExcep return Map.of( "tab", Map.of("storage", true), - "node", new IndexNode(nodeId), + "node", nodeConfigurationService.get(nodeId), "view", Map.of("specs", true) ); } @@ -193,7 +193,7 @@ private Object nodeActorsModel(Request request, Response response) throws SQLExc return Map.of( "tab", Map.of("actors", true), - "node", new IndexNode(nodeId), + "node", nodeConfigurationService.get(nodeId), "actors", executorClient.getActorStates(Context.fromRequest(request), nodeId).states() ); } @@ -203,7 +203,7 @@ private Object nodeActionsModel(Request request, Response response) throws SQLEx return Map.of( "tab", Map.of("actions", true), - "node", new IndexNode(nodeId), + "node", nodeConfigurationService.get(nodeId), "view", Map.of(request.queryParams("view"), true), "uploadDirContents", executorClient.listSideloadDir(Context.fromRequest(request), nodeId), "allBackups", @@ -223,7 +223,7 @@ private Object nodeStorageConfModel(Request request, Response response) throws S return Map.of( "tab", Map.of("storage", true), "view", Map.of("conf", true), - "node", new IndexNode(nodeId), + "node", nodeConfigurationService.get(nodeId), "storagebase", getStorageBaseList(nodeId) ); } @@ -245,7 +245,7 @@ private Object nodeStorageListModel(Request request, Response response) throws S return Map.of( "tab", Map.of("storage", true), "view", Map.of(view, true), - "node", new IndexNode(nodeId), + "node", nodeConfigurationService.get(nodeId), "storage", makeFileStorageBaseWithStorage(getFileStorageIds(type, nodeId)) ); } @@ -266,7 +266,7 @@ private Object nodeStorageDetailsModel(Request request, Response response) throw return Map.of( "tab", Map.of("storage", true), "view", Map.of(view, true), - "node", new IndexNode(nodeId), + "node", nodeConfigurationService.get(nodeId), "storage", storage ); } @@ -284,7 +284,7 @@ private Object nodeConfigModel(Request request, Response response) throws SQLExc return Map.of( "tab", Map.of("config", true), - "node", new IndexNode(nodeId), + "node", nodeConfigurationService.get(nodeId), "config", Objects.requireNonNull(nodeConfigurationService.get(nodeId), "Failed to fetch configuration"), "storage", storage); } @@ -325,7 +325,7 @@ private Object nodeOverviewModel(Request request, Response response) throws SQLE actors.removeIf(actor -> actor.state().equals("MONITOR")); return Map.of( - "node", new IndexNode(nodeId), + "node", nodeConfigurationService.get(nodeId), "status", getStatus(config), "events", getEvents(nodeId), "processes", heartbeatService.getProcessHeartbeatsForNode(nodeId), diff --git a/code/services-core/control-service/src/main/java/nu/marginalia/control/sys/svc/ControlSysActionsService.java b/code/services-core/control-service/src/main/java/nu/marginalia/control/sys/svc/ControlSysActionsService.java index 535f90f7f..270607390 100644 --- a/code/services-core/control-service/src/main/java/nu/marginalia/control/sys/svc/ControlSysActionsService.java +++ b/code/services-core/control-service/src/main/java/nu/marginalia/control/sys/svc/ControlSysActionsService.java @@ -72,7 +72,6 @@ public void register() { Spark.post("/public/actions/recrawl-all", this::recrawlAll, Redirects.redirectToOverview); Spark.post("/public/actions/flush-api-caches", this::flushApiCaches, Redirects.redirectToOverview); Spark.post("/public/actions/reload-blogs-list", this::reloadBlogsList, Redirects.redirectToOverview); - Spark.post("/public/actions/trigger-data-exports", this::triggerDataExports, Redirects.redirectToOverview); } @SneakyThrows @@ -99,14 +98,6 @@ private Object actionsModel(Request request, Response response) { return Map.of("precessionNodes", eligibleNodes); } - public Object triggerDataExports(Request request, Response response) throws Exception { - eventLog.logEvent("USER-ACTION", "EXPORT-DATA"); - - executorClient.exportData(Context.fromRequest(request)); - - return ""; - } - public Object reloadBlogsList(Request request, Response response) throws Exception { eventLog.logEvent("USER-ACTION", "RELOAD-BLOGS-LIST"); diff --git a/code/services-core/control-service/src/main/resources/templates/control/node/actions/partial-new-crawl.hdb b/code/services-core/control-service/src/main/resources/templates/control/node/actions/partial-new-crawl.hdb index 091c1f460..9e0ae7f82 100644 --- a/code/services-core/control-service/src/main/resources/templates/control/node/actions/partial-new-crawl.hdb +++ b/code/services-core/control-service/src/main/resources/templates/control/node/actions/partial-new-crawl.hdb @@ -10,8 +10,8 @@ This will perform a new crawl on node {{node.id}} based on the crawl spec you select below. Additional specifications can be created with this form. -
-

IMPORTANT! Be sure you've read and understood the +

+

IMPORTANT! Be sure you've read and understood the crawling documentation before you begin a crawl. You will be accessing real servers from your connection, and you may end up on IP greylists that temporarily block your access to those servers for up to a few weeks; on rare occasions permanently. The crawler diff --git a/code/services-core/control-service/src/main/resources/templates/control/node/partial-node-nav.hdb b/code/services-core/control-service/src/main/resources/templates/control/node/partial-node-nav.hdb index e48a3172d..6ba528b34 100644 --- a/code/services-core/control-service/src/main/resources/templates/control/node/partial-node-nav.hdb +++ b/code/services-core/control-service/src/main/resources/templates/control/node/partial-node-nav.hdb @@ -1,5 +1,11 @@

Index Node {{node.id}}

+{{#if node.disabled}} + This index node is disabled! +{{/if}} +{{#unless node.acceptQueries}} + This index node is not accepting queries! +{{/unless}} \ No newline at end of file +