- Add the "shutdownWorker"-endpoint to accept requests for shutting-down the Worker, gracefully, after it completes its current work (including sending the publications-files to the Controller). A user-defined "auth-code" is required.
- Add the "cancelShutdownWorker"-endpoint to cancel a previous "shutdownWorker"-request. A user-defined "auth-code" is required.
This commit is contained in:
parent
d6e94912a4
commit
26cbb83b51
|
@ -41,7 +41,7 @@ public class UrlsWorkerApplication {
|
||||||
private static final String inputDataFilePath = FileUtils.workingDir + "inputData.txt";
|
private static final String inputDataFilePath = FileUtils.workingDir + "inputData.txt";
|
||||||
public static String workerId = null;
|
public static String workerId = null;
|
||||||
public static int maxAssignmentsLimitPerBatch = 0;
|
public static int maxAssignmentsLimitPerBatch = 0;
|
||||||
public static int maxAssignmentsBatchesToHandleBeforeRestart = -1; // Default value: -1 = argument-absent, 0 = infinite-batches
|
public static int maxAssignmentsBatchesToHandleBeforeShutdown = -1; // Default value: -1 = argument-absent, 0 = infinite-batches
|
||||||
public static String controllerBaseUrl = null; // BaseUrl template: "http://IP:PORT/api/"
|
public static String controllerBaseUrl = null; // BaseUrl template: "http://IP:PORT/api/"
|
||||||
|
|
||||||
private static ConfigurableApplicationContext context;
|
private static ConfigurableApplicationContext context;
|
||||||
|
@ -64,7 +64,7 @@ public class UrlsWorkerApplication {
|
||||||
|
|
||||||
public static void gentleAppShutdown()
|
public static void gentleAppShutdown()
|
||||||
{
|
{
|
||||||
int exitCode = SpringApplication.exit(context, () -> 0); // The "PreDestroy" method will be called.
|
int exitCode = SpringApplication.exit(context, () -> 0); // The "PreDestroy" method will be called. (the "context" will be closed automatically (I checked it))
|
||||||
System.exit(exitCode);
|
System.exit(exitCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,10 +145,10 @@ public class UrlsWorkerApplication {
|
||||||
}
|
}
|
||||||
String maxAssignmentsBatchesStr = data[2].trim();
|
String maxAssignmentsBatchesStr = data[2].trim();
|
||||||
try {
|
try {
|
||||||
maxAssignmentsBatchesToHandleBeforeRestart = Integer.parseInt(maxAssignmentsBatchesStr);
|
maxAssignmentsBatchesToHandleBeforeShutdown = Integer.parseInt(maxAssignmentsBatchesStr);
|
||||||
} catch (NumberFormatException nfe) {
|
} catch (NumberFormatException nfe) {
|
||||||
logger.warn("The given \"maxAssignmentsBatchesToHandleBeforeRestart\" (" + maxAssignmentsBatchesStr + ") was not a number! Will handle an infinite number of batches!");
|
logger.warn("The given \"maxAssignmentsBatchesToHandleBeforeRestart\" (" + maxAssignmentsBatchesStr + ") was not a number! Will handle an infinite number of batches!");
|
||||||
maxAssignmentsBatchesToHandleBeforeRestart = 0;
|
maxAssignmentsBatchesToHandleBeforeShutdown = 0;
|
||||||
}
|
}
|
||||||
controllerBaseUrl = data[3].trim();
|
controllerBaseUrl = data[3].trim();
|
||||||
try {
|
try {
|
||||||
|
@ -163,14 +163,14 @@ public class UrlsWorkerApplication {
|
||||||
controllerBaseUrl += "/"; // Make sure the other urls will not break later.
|
controllerBaseUrl += "/"; // Make sure the other urls will not break later.
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( (workerId == null) || (maxAssignmentsLimitPerBatch == 0) || (maxAssignmentsBatchesToHandleBeforeRestart == -1) || (controllerBaseUrl == null) ) {
|
if ( (workerId == null) || (maxAssignmentsLimitPerBatch == 0) || (maxAssignmentsBatchesToHandleBeforeShutdown == -1) || (controllerBaseUrl == null) ) {
|
||||||
String errorMsg = "No \"workerId\" or/and \"maxAssignmentsLimitPerBatch\" or/and \"maxAssignmentsBatchesToHandleBeforeRestart\" or/and \"controllerBaseUrl\" could be retrieved from the file: " + inputDataFilePath;
|
String errorMsg = "No \"workerId\" or/and \"maxAssignmentsLimitPerBatch\" or/and \"maxAssignmentsBatchesToHandleBeforeRestart\" or/and \"controllerBaseUrl\" could be retrieved from the file: " + inputDataFilePath;
|
||||||
logger.error(errorMsg);
|
logger.error(errorMsg);
|
||||||
System.err.println(errorMsg);
|
System.err.println(errorMsg);
|
||||||
System.exit(63);
|
System.exit(63);
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info("workerId: " + workerId + ", maxAssignmentsLimitPerBatch: " + maxAssignmentsLimitPerBatch + ", maxAssignmentsBatchesToHandleBeforeRestart: " + maxAssignmentsBatchesToHandleBeforeRestart + ", controllerBaseUrl: " + controllerBaseUrl); // It's safe and helpful to show them in the logs.
|
logger.info("workerId: " + workerId + ", maxAssignmentsLimitPerBatch: " + maxAssignmentsLimitPerBatch + ", maxAssignmentsBatchesToHandleBeforeRestart: " + maxAssignmentsBatchesToHandleBeforeShutdown + ", controllerBaseUrl: " + controllerBaseUrl); // It's safe and helpful to show them in the logs.
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
String errorMsg = "An error prevented the retrieval of the workerId and the controllerBaseUrl from the file: " + inputDataFilePath + "\n" + e.getMessage();
|
String errorMsg = "An error prevented the retrieval of the workerId and the controllerBaseUrl from the file: " + inputDataFilePath + "\n" + e.getMessage();
|
||||||
|
|
|
@ -2,8 +2,11 @@ package eu.openaire.urls_worker.controllers;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@ -18,18 +21,54 @@ public class GeneralController {
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(GeneralController.class);
|
private static final Logger logger = LoggerFactory.getLogger(GeneralController.class);
|
||||||
|
|
||||||
|
@Value("${security.shutdownOrCancelCode}")
|
||||||
|
private String shutdownOrCancelCode;
|
||||||
|
|
||||||
|
|
||||||
public GeneralController() {}
|
public GeneralController() {}
|
||||||
|
|
||||||
|
|
||||||
@GetMapping("isAlive")
|
@GetMapping("isAlive")
|
||||||
public ResponseEntity<?> isWorkerAlive() {
|
public ResponseEntity<?> isWorkerAlive() {
|
||||||
|
|
||||||
logger.info("Received an \"isAlive\" request.");
|
logger.info("Received an \"isAlive\" request.");
|
||||||
|
|
||||||
return ResponseEntity.ok().build();
|
return ResponseEntity.ok().build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static boolean shouldShutdownWorker = false;
|
||||||
|
|
||||||
|
@GetMapping("shutdownWorker/{shutdownCode}")
|
||||||
|
public ResponseEntity<?> shutdownWorkerGracefully(@PathVariable String shutdownCode)
|
||||||
|
{
|
||||||
|
String initMsg = "Received a \"shutdownWorker\" request.";
|
||||||
|
if ( shutdownCode.equals(shutdownOrCancelCode) ) {
|
||||||
|
shouldShutdownWorker = true;
|
||||||
|
logger.info(initMsg + " The worker will shutdown, after finishing current work.");
|
||||||
|
return ResponseEntity.ok().build();
|
||||||
|
} else {
|
||||||
|
String errorMsg = initMsg + " But, it has an invalid \"shutdownCode\": " + shutdownCode;
|
||||||
|
logger.error(errorMsg);
|
||||||
|
return ResponseEntity.status(HttpStatus.FORBIDDEN).body(errorMsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@GetMapping("cancelShutdownWorker/{cancelCode}")
|
||||||
|
public ResponseEntity<?> cancelShutdownWorkerGracefully(@PathVariable String cancelCode)
|
||||||
|
{
|
||||||
|
String initMsg = "Received a \"cancelShutdownWorker\" request.";
|
||||||
|
if ( cancelCode.equals(shutdownOrCancelCode) ) {
|
||||||
|
shouldShutdownWorker = false;
|
||||||
|
logger.info(initMsg + " Any previous \"shutdownWorker\"-request is canceled. The \"maxAssignmentsBatchesToHandleBeforeShutdown\" will still be honored (if it's set).");
|
||||||
|
return ResponseEntity.ok().build();
|
||||||
|
} else {
|
||||||
|
String errorMsg = initMsg + " But, it has an invalid \"cancelCode\": " + cancelCode;
|
||||||
|
logger.error(errorMsg);
|
||||||
|
return ResponseEntity.status(HttpStatus.FORBIDDEN).body(errorMsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@GetMapping("getHandledAssignmentsCounts")
|
@GetMapping("getHandledAssignmentsCounts")
|
||||||
public ResponseEntity<?> getHandledAssignmentsCounts()
|
public ResponseEntity<?> getHandledAssignmentsCounts()
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,6 +5,7 @@ import com.google.common.collect.Multimap;
|
||||||
import eu.openaire.publications_retriever.util.url.GenericUtils;
|
import eu.openaire.publications_retriever.util.url.GenericUtils;
|
||||||
import eu.openaire.publications_retriever.util.url.UrlUtils;
|
import eu.openaire.publications_retriever.util.url.UrlUtils;
|
||||||
import eu.openaire.urls_worker.UrlsWorkerApplication;
|
import eu.openaire.urls_worker.UrlsWorkerApplication;
|
||||||
|
import eu.openaire.urls_worker.controllers.GeneralController;
|
||||||
import eu.openaire.urls_worker.models.Assignment;
|
import eu.openaire.urls_worker.models.Assignment;
|
||||||
import eu.openaire.urls_worker.models.UrlReport;
|
import eu.openaire.urls_worker.models.UrlReport;
|
||||||
import eu.openaire.urls_worker.payloads.requests.AssignmentsRequest;
|
import eu.openaire.urls_worker.payloads.requests.AssignmentsRequest;
|
||||||
|
@ -129,7 +130,7 @@ public class AssignmentsHandler {
|
||||||
else
|
else
|
||||||
postWorkerReport(assignmentRequestCounter);
|
postWorkerReport(assignmentRequestCounter);
|
||||||
|
|
||||||
numHandledAssignmentsBatches ++; // This is used later to stop this app, when a user-defined upper limit is reached.
|
numHandledAssignmentsBatches ++; // This is used later to stop this app, if a user-defined upper limit is set and reached.
|
||||||
|
|
||||||
// Every time we reach a "limit" of handled id-url clear some data-structures of the underlying "PublicationsRetriever" program.
|
// Every time we reach a "limit" of handled id-url clear some data-structures of the underlying "PublicationsRetriever" program.
|
||||||
// This helps with reducing the memory consumption over the period of weeks or months, and also give a 2nd chance to some domains which may be blocked due to a connectivity issues, but after a month they may be fine.
|
// This helps with reducing the memory consumption over the period of weeks or months, and also give a 2nd chance to some domains which may be blocked due to a connectivity issues, but after a month they may be fine.
|
||||||
|
@ -140,9 +141,12 @@ public class AssignmentsHandler {
|
||||||
if ( idUrlPairsHandled >= idUrlsToHandleBeforeClearingDomainAndPathTrackingData )
|
if ( idUrlPairsHandled >= idUrlsToHandleBeforeClearingDomainAndPathTrackingData )
|
||||||
GenericUtils.clearDomainAndPathTrackingData();
|
GenericUtils.clearDomainAndPathTrackingData();
|
||||||
|
|
||||||
if ( AssignmentsHandler.numHandledAssignmentsBatches == UrlsWorkerApplication.maxAssignmentsBatchesToHandleBeforeRestart )
|
if ( GeneralController.shouldShutdownWorker
|
||||||
|
|| (AssignmentsHandler.numHandledAssignmentsBatches == UrlsWorkerApplication.maxAssignmentsBatchesToHandleBeforeShutdown) )
|
||||||
{
|
{
|
||||||
logger.info("The maximum assignments-batches (" + UrlsWorkerApplication.maxAssignmentsBatchesToHandleBeforeRestart + ") to be handled was reached! Shut down, in order for the external Linux-service to restart on its own..");
|
logger.info("The worker will now shutdown, as " + (GeneralController.shouldShutdownWorker
|
||||||
|
? "it received a \"shutdownWorker\" request!"
|
||||||
|
: "the maximum assignments-batches (" + UrlsWorkerApplication.maxAssignmentsBatchesToHandleBeforeShutdown + ") to be handled was reached!"));
|
||||||
UrlsWorkerApplication.gentleAppShutdown();
|
UrlsWorkerApplication.gentleAppShutdown();
|
||||||
// The "gentleAppShutdown()" will exit the app, so the "isAvailableForWork" will not be set below.
|
// The "gentleAppShutdown()" will exit the app, so the "isAvailableForWork" will not be set below.
|
||||||
}
|
}
|
||||||
|
@ -152,6 +156,10 @@ public class AssignmentsHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Post the worker report and wait for the Controller to request the publication-files.
|
||||||
|
* Once the Controller finishes with uploading the files to the S3-ObjectStore, it returns an "HTTP-200-OK" response to the Worker.
|
||||||
|
* */
|
||||||
public static boolean postWorkerReport(Long assignmentRequestCounter)
|
public static boolean postWorkerReport(Long assignmentRequestCounter)
|
||||||
{
|
{
|
||||||
String postUrl = UrlsWorkerApplication.controllerBaseUrl + "urls/addWorkerReport";
|
String postUrl = UrlsWorkerApplication.controllerBaseUrl + "urls/addWorkerReport";
|
||||||
|
|
|
@ -15,6 +15,10 @@ server.port = 1881
|
||||||
# Server api path
|
# Server api path
|
||||||
server.servlet.context-path=/api
|
server.servlet.context-path=/api
|
||||||
|
|
||||||
|
# Here set the code to be checked, when receiving "shutdown" and "cancel-shutdown" requests.
|
||||||
|
security.shutdownOrCancelCode=
|
||||||
|
|
||||||
|
|
||||||
# LOGGING LEVELS
|
# LOGGING LEVELS
|
||||||
logging.config=classpath:logback-spring.xml
|
logging.config=classpath:logback-spring.xml
|
||||||
logging.level.root=INFO
|
logging.level.root=INFO
|
||||||
|
|
Loading…
Reference in New Issue