support timeout option for sync exec command, avoid exec job concurrently

This commit is contained in:
gongdewei
2020-04-30 11:00:55 +08:00
parent ed1b51b743
commit f06e6082d7
3 changed files with 76 additions and 9 deletions
+25 -2
View File
@@ -63,8 +63,31 @@ Cache-Control: no-cache
{
"action": "exec",
"command": "watch demo.MathGame primeFactors 'params' -n 3 ",
"sessionId":"8132aa34-3e9a-477d-b20d-488032ba76b2"
"timeout": 5000,
"command": "watch demo.MathGame primeFactors 'params' -n 2 ",
"sessionId":"940874b4-829a-4770-a01c-f10f6be4d53a"
}
###
POST http://localhost:8563/api
Accept: */*
Cache-Control: no-cache
{
"action": "exec",
"timeout": 5000,
"command": "trace demo.MathGame primeFactors ",
"sessionId":"940874b4-829a-4770-a01c-f10f6be4d53a"
}
###
POST http://localhost:8563/api
Accept: */*
Cache-Control: no-cache
{
"action": "interrupt_job",
"sessionId":"940874b4-829a-4770-a01c-f10f6be4d53a"
}
###
@@ -13,6 +13,7 @@ public class ApiRequest {
private String requestId;
private String sessionId;
private String consumerId;
private Integer timeout;
private Map<String, Object> options;
@Override
@@ -23,6 +24,7 @@ public class ApiRequest {
", requestId='" + requestId + '\'' +
", sessionId='" + sessionId + '\'' +
", consumerId='" + consumerId + '\'' +
", timeout=" + timeout +
", options=" + options +
'}';
}
@@ -74,4 +76,12 @@ public class ApiRequest {
public void setConsumerId(String consumerId) {
this.consumerId = consumerId;
}
public Integer getTimeout() {
return timeout;
}
public void setTimeout(Integer timeout) {
this.timeout = timeout;
}
}
@@ -48,6 +48,7 @@ import java.util.concurrent.atomic.AtomicInteger;
public class HttpApiHandler {
private static final Logger logger = LoggerFactory.getLogger(HttpApiHandler.class);
public static final int DEFAULT_EXEC_TIMEOUT = 30000;
private final SessionManager sessionManager;
private final AtomicInteger requestIdGenerator = new AtomicInteger(0);
private static HttpApiHandler instance;
@@ -280,9 +281,24 @@ public class HttpApiHandler {
response.setSessionId(session.getSessionId())
.setBody(body);
if(!session.tryLock()){
response.setState(ApiState.REFUSED)
.setMessage("Another command is executing.");
return response;
}
int lock = session.getLock();
PackingResultDistributor packingResultDistributor = null;
Job job = null;
try {
Job foregroundJob = session.getForegroundJob();
if (foregroundJob != null){
response.setState(ApiState.REFUSED)
.setMessage("Another job is running.");
logger.info("Another job is running, jobId: {}", foregroundJob.id());
return response;
}
packingResultDistributor = new PackingResultDistributorImpl(session);
job = this.createJob(commandLine, session, packingResultDistributor);
session.setForegroundJob(job);
@@ -292,10 +308,18 @@ public class HttpApiHandler {
logger.error("Exec command failed:" + e.getMessage() + ", command:" + commandLine, e);
response.setState(ApiState.FAILED).setMessage("Exec command failed:" + e.getMessage());
return response;
} finally {
if (session.getLock() == lock) {
session.unLock();
}
}
//wait for job completed or timeout
boolean timeExpired = !waitForJob(job);
Integer timeout = apiRequest.getTimeout();
if (timeout == null || timeout <= 0) {
timeout = DEFAULT_EXEC_TIMEOUT;
}
boolean timeExpired = !waitForJob(job, timeout);
if (timeExpired) {
logger.warn("Job is exceeded time limit, force interrupt it, jobId: {}", job.id());
job.interrupt();
@@ -303,12 +327,14 @@ public class HttpApiHandler {
} else {
response.setState(ApiState.SUCCEEDED);
}
//session.setForegroundJob(null);
//packing results
body.put("jobId", job.id());
body.put("jobStatus", job.status());
body.put("timeExpired", timeExpired);
if (timeExpired) {
body.put("timeout", timeout);
}
body.put("results", packingResultDistributor.getResults());
response.setSessionId(session.getSessionId())
@@ -341,9 +367,11 @@ public class HttpApiHandler {
int lock = session.getLock();
try {
if (session.getForegroundJob() != null){
Job foregroundJob = session.getForegroundJob();
if (foregroundJob != null){
response.setState(ApiState.REFUSED)
.setMessage("The foreground job of session is running.");
.setMessage("Another job is running.");
logger.info("Another job is running, jobId: {}", foregroundJob.id());
return response;
}
@@ -383,7 +411,13 @@ public class HttpApiHandler {
return new ApiResponse().setState(ApiState.FAILED).setMessage("no foreground job is running");
}
job.interrupt();
return new ApiResponse().setState(ApiState.SUCCEEDED);
Map<String, Object> body = new TreeMap<String, Object>();
body.put("jobId", job.id());
body.put("jobStatus", job.status());
return new ApiResponse()
.setState(ApiState.SUCCEEDED)
.setBody(body);
}
/**
@@ -415,7 +449,7 @@ public class HttpApiHandler {
return response;
}
private boolean waitForJob(Job job) {
private boolean waitForJob(Job job, int timeout) {
long startTime = System.currentTimeMillis();
while (true) {
switch (job.status()) {
@@ -423,7 +457,7 @@ public class HttpApiHandler {
case TERMINATED:
return true;
}
if (System.currentTimeMillis() - startTime > 30000) {
if (System.currentTimeMillis() - startTime > timeout) {
return false;
}
try {