From f06e6082d7780bfdc07040f8f225d265ee7443ac Mon Sep 17 00:00:00 2001 From: gongdewei Date: Thu, 30 Apr 2020 11:00:55 +0800 Subject: [PATCH] support timeout option for sync exec command, avoid exec job concurrently --- core/http-api-test.http | 27 ++++++++++- .../shell/term/impl/http/api/ApiRequest.java | 10 ++++ .../term/impl/http/api/HttpApiHandler.java | 48 ++++++++++++++++--- 3 files changed, 76 insertions(+), 9 deletions(-) diff --git a/core/http-api-test.http b/core/http-api-test.http index 18948a8c6..7f37de338 100644 --- a/core/http-api-test.http +++ b/core/http-api-test.http @@ -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" } ### diff --git a/core/src/main/java/com/taobao/arthas/core/shell/term/impl/http/api/ApiRequest.java b/core/src/main/java/com/taobao/arthas/core/shell/term/impl/http/api/ApiRequest.java index 55a48d0d3..a3d2da354 100644 --- a/core/src/main/java/com/taobao/arthas/core/shell/term/impl/http/api/ApiRequest.java +++ b/core/src/main/java/com/taobao/arthas/core/shell/term/impl/http/api/ApiRequest.java @@ -13,6 +13,7 @@ public class ApiRequest { private String requestId; private String sessionId; private String consumerId; + private Integer timeout; private Map 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; + } } diff --git a/core/src/main/java/com/taobao/arthas/core/shell/term/impl/http/api/HttpApiHandler.java b/core/src/main/java/com/taobao/arthas/core/shell/term/impl/http/api/HttpApiHandler.java index 827291974..c5dda2eb4 100644 --- a/core/src/main/java/com/taobao/arthas/core/shell/term/impl/http/api/HttpApiHandler.java +++ b/core/src/main/java/com/taobao/arthas/core/shell/term/impl/http/api/HttpApiHandler.java @@ -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 body = new TreeMap(); + 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 {