(control) Button for removing a stale 'NEW' status

If a process is violently terminated, the associated file storage may get stuck in the ephemeral 'NEW' state, preventing future operations on the associated data.

To remedy this without having to dig through the database, a button was added to reset the state.  It's a band-aid, but the situation is rare enough that I think it's fine.
This commit is contained in:
Viktor Lofgren 2023-11-28 15:18:24 +01:00
parent 1dafa0c74d
commit ff3ceb981e
3 changed files with 20 additions and 0 deletions

View File

@ -2,6 +2,7 @@ package nu.marginalia.control.node.model;
import nu.marginalia.storage.model.FileStorage; import nu.marginalia.storage.model.FileStorage;
import nu.marginalia.storage.model.FileStorageBaseType; import nu.marginalia.storage.model.FileStorageBaseType;
import nu.marginalia.storage.model.FileStorageState;
import nu.marginalia.storage.model.FileStorageType; import nu.marginalia.storage.model.FileStorageType;
import java.nio.file.Path; import java.nio.file.Path;
@ -12,6 +13,9 @@ public record FileStorageWithActions(FileStorage storage) {
public boolean isCrawlable() { public boolean isCrawlable() {
return storage.type() == FileStorageType.CRAWL_SPEC; return storage.type() == FileStorageType.CRAWL_SPEC;
} }
public boolean isStatusNew() {
return storage.state() == FileStorageState.NEW;
}
public boolean isAtagsExportable() { public boolean isAtagsExportable() {
return storage.type() == FileStorageType.CRAWL_DATA; return storage.type() == FileStorageType.CRAWL_DATA;
} }

View File

@ -108,6 +108,9 @@ public class ControlNodeService {
Spark.post("/public/nodes/:id/storage/crawl/:fid", this::triggerCrawl, Spark.post("/public/nodes/:id/storage/crawl/:fid", this::triggerCrawl,
redirectControl.renderRedirectAcknowledgement("Crawling", "..") redirectControl.renderRedirectAcknowledgement("Crawling", "..")
); );
Spark.post("/public/nodes/:id/storage/reset-state/:fid", this::resetState,
redirectControl.renderRedirectAcknowledgement("Restoring", "..")
);
Spark.post("/public/nodes/:id/storage/backup-restore/:fid", this::triggerRestoreBackup, Spark.post("/public/nodes/:id/storage/backup-restore/:fid", this::triggerRestoreBackup,
redirectControl.renderRedirectAcknowledgement("Restoring", "..") redirectControl.renderRedirectAcknowledgement("Restoring", "..")
); );
@ -121,6 +124,11 @@ public class ControlNodeService {
Spark.post("/public/nodes/:id/fsms/:fsm/stop", this::stopFsm); Spark.post("/public/nodes/:id/fsms/:fsm/stop", this::stopFsm);
} }
private Object resetState(Request request, Response response) throws SQLException {
fileStorageService.setFileStorageState(FileStorageId.parse(request.params("fid")), FileStorageState.UNSET);
return "";
}
private Object exportData(Request req, Response rsp) { private Object exportData(Request req, Response rsp) {
executorClient.exportData(Context.fromRequest(req), Integer.parseInt(req.params("id"))); executorClient.exportData(Context.fromRequest(req), Integer.parseInt(req.params("id")));
return ""; return "";

View File

@ -67,6 +67,14 @@
</tr> </tr>
</form> </form>
{{/if}} {{/if}}
{{#if isStatusNew}}
<form method="post" action="/nodes/{{node.id}}/storage/reset-state/{{storage.id}}" onsubmit="return confirm('Confirm removal of \'NEW\' state for {{storage.path}}')">
<tr>
<td>Remove 'NEW' state (use this if the generating process stopped)</td>
<td><button class="btn btn-primary" type="submit">Reset State</button></td>
</tr>
</form>
{{/if}}
{{#if isAtagsExportable}} {{#if isAtagsExportable}}
<form method="post" action="/nodes/{{node.id}}/storage/{{storage.id}}/export-atags" onsubmit="return confirm('Confirm export of anchor tags from {{storage.path}}')"> <form method="post" action="/nodes/{{node.id}}/storage/{{storage.id}}/export-atags" onsubmit="return confirm('Confirm export of anchor tags from {{storage.path}}')">
<tr> <tr>