diff --git a/core/src/main/java/com/taobao/arthas/core/shell/system/Job.java b/core/src/main/java/com/taobao/arthas/core/shell/system/Job.java
index d884ba36b..e061264f2 100644
--- a/core/src/main/java/com/taobao/arthas/core/shell/system/Job.java
+++ b/core/src/main/java/com/taobao/arthas/core/shell/system/Job.java
@@ -57,6 +57,11 @@ public interface Job {
*/
Job resume();
+ /**
+ * @return true if the job is running in background
+ */
+ boolean isRunInBackground();
+
/**
* Send the job to background.
*
diff --git a/core/src/main/java/com/taobao/arthas/core/shell/system/JobListener.java b/core/src/main/java/com/taobao/arthas/core/shell/system/JobListener.java
new file mode 100644
index 000000000..fb40ca90c
--- /dev/null
+++ b/core/src/main/java/com/taobao/arthas/core/shell/system/JobListener.java
@@ -0,0 +1,18 @@
+package com.taobao.arthas.core.shell.system;
+
+import com.taobao.arthas.core.shell.system.impl.JobImpl;
+
+/**
+ * Job listener
+ * @author gongdewei 2020-03-23
+ */
+public interface JobListener {
+
+ void onForeground(Job job);
+
+ void onBackground(Job job);
+
+ void onTerminated(Job job);
+
+ void onSuspend(Job job);
+}
diff --git a/core/src/main/java/com/taobao/arthas/core/shell/system/impl/JobControllerImpl.java b/core/src/main/java/com/taobao/arthas/core/shell/system/impl/JobControllerImpl.java
index d7a0c200d..20ad4001e 100644
--- a/core/src/main/java/com/taobao/arthas/core/shell/system/impl/JobControllerImpl.java
+++ b/core/src/main/java/com/taobao/arthas/core/shell/system/impl/JobControllerImpl.java
@@ -11,6 +11,7 @@ import com.taobao.arthas.core.shell.handlers.Handler;
import com.taobao.arthas.core.shell.impl.ShellImpl;
import com.taobao.arthas.core.shell.system.Job;
import com.taobao.arthas.core.shell.system.JobController;
+import com.taobao.arthas.core.shell.system.JobListener;
import com.taobao.arthas.core.shell.system.Process;
import com.taobao.arthas.core.shell.system.impl.ProcessImpl.ProcessOutput;
import com.taobao.arthas.core.shell.term.Term;
@@ -34,6 +35,7 @@ import java.util.concurrent.atomic.AtomicInteger;
/**
* @author Julien Viet
* @author hengyunabc 2019-05-14
+ * @author gongdewei 2020-03-23
*/
public class JobControllerImpl implements JobController {
@@ -66,7 +68,7 @@ public class JobControllerImpl implements JobController {
boolean runInBackground = runInBackground(tokens);
Process process = createProcess(tokens, commandManager, jobId, shell.term());
process.setJobId(jobId);
- JobImpl job = new JobImpl(jobId, this, process, line.toString(), runInBackground, shell);
+ JobImpl job = new JobImpl(jobId, this, process, line.toString(), runInBackground, shell.session(), new ShellJobHandler(shell));
jobs.put(jobId, job);
return job;
}
@@ -225,4 +227,38 @@ public class JobControllerImpl implements JobController {
public void close() {
close(null);
}
+
+ private class ShellJobHandler implements JobListener {
+ ShellImpl shell;
+
+ public ShellJobHandler(ShellImpl shell) {
+ this.shell = shell;
+ }
+
+ @Override
+ public void onForeground(Job job) {
+ shell.setForegroundJob(job);
+ }
+
+ @Override
+ public void onBackground(Job job) {
+ shell.setForegroundJob(null);
+ shell.readline();
+ }
+
+ @Override
+ public void onTerminated(Job job) {
+ if (!job.isRunInBackground()){
+ shell.readline();
+ }
+ }
+
+ @Override
+ public void onSuspend(Job job) {
+ if (!job.isRunInBackground()){
+ shell.readline();
+ }
+ }
+ }
+
}
diff --git a/core/src/main/java/com/taobao/arthas/core/shell/system/impl/JobImpl.java b/core/src/main/java/com/taobao/arthas/core/shell/system/impl/JobImpl.java
index 6f37e8632..42afa3013 100644
--- a/core/src/main/java/com/taobao/arthas/core/shell/system/impl/JobImpl.java
+++ b/core/src/main/java/com/taobao/arthas/core/shell/system/impl/JobImpl.java
@@ -7,11 +7,10 @@ import java.util.concurrent.atomic.AtomicBoolean;
import com.taobao.arthas.core.shell.future.Future;
import com.taobao.arthas.core.shell.handlers.Handler;
-import com.taobao.arthas.core.shell.handlers.shell.ShellForegroundUpdateHandler;
-import com.taobao.arthas.core.shell.impl.ShellImpl;
import com.taobao.arthas.core.shell.session.Session;
import com.taobao.arthas.core.shell.system.ExecStatus;
import com.taobao.arthas.core.shell.system.Job;
+import com.taobao.arthas.core.shell.system.JobListener;
import com.taobao.arthas.core.shell.system.Process;
import com.taobao.arthas.core.shell.term.Term;
import com.taobao.arthas.core.shell.term.impl.TermImpl;
@@ -21,6 +20,7 @@ import com.taobao.arthas.core.util.FileUtils;
/**
* @author Julien Viet
* @author hengyunabc 2019-05-14
+ * @author gongdewei 2020-03-23
*/
public class JobImpl implements Job {
@@ -28,25 +28,30 @@ public class JobImpl implements Job {
final JobControllerImpl controller;
final Process process;
final String line;
+ private volatile Session session;
private volatile ExecStatus actualStatus; // Used internally for testing only
volatile long lastStopped; // When the job was last stopped
- volatile ShellImpl shell;
+ volatile JobListener jobHandler;
volatile Handler statusUpdateHandler;
volatile Date timeoutDate;
final Future terminateFuture;
final AtomicBoolean runInBackground;
- final Handler foregroundUpdatedHandler;
+ //final Handler foregroundUpdatedHandler;
JobImpl(int id, final JobControllerImpl controller, Process process, String line, boolean runInBackground,
- ShellImpl shell) {
+ Session session, JobListener jobHandler) {
this.id = id;
this.controller = controller;
this.process = process;
this.line = line;
+ this.session = session;
this.terminateFuture = Future.future();
this.runInBackground = new AtomicBoolean(runInBackground);
- this.shell = shell;
- this.foregroundUpdatedHandler = new ShellForegroundUpdateHandler(shell);
+ this.jobHandler = jobHandler;
+ if (jobHandler == null) {
+ throw new IllegalArgumentException("JobListener is required");
+ }
+ //this.foregroundUpdatedHandler = new ShellForegroundUpdateHandler(shell);
process.terminatedHandler(new TerminatedHandler(controller));
}
@@ -76,7 +81,7 @@ public class JobImpl implements Job {
@Override
public Session getSession() {
- return shell.session();
+ return session;
}
@Override
@@ -89,19 +94,19 @@ public class JobImpl implements Job {
runInBackground.set(!foreground);
- if (foreground) {
- if (foregroundUpdatedHandler != null) {
- foregroundUpdatedHandler.handle(this);
- }
- }
+// if (foreground) {
+// if (foregroundUpdatedHandler != null) {
+// foregroundUpdatedHandler.handle(this);
+// }
+// }
if (statusUpdateHandler != null) {
statusUpdateHandler.handle(process.status());
}
if (foreground) {
- shell.setForegroundJob(this);
+ jobHandler.onForeground(this);
} else {
- shell.setForegroundJob(null);
+ jobHandler.onBackground(this);
}
return this;
}
@@ -113,14 +118,15 @@ public class JobImpl implements Job {
} catch (IllegalStateException ignore) {
return this;
}
- if (!runInBackground.get() && foregroundUpdatedHandler != null) {
- foregroundUpdatedHandler.handle(null);
- }
+// if (!runInBackground.get() && foregroundUpdatedHandler != null) {
+// foregroundUpdatedHandler.handle(null);
+// }
if (statusUpdateHandler != null) {
statusUpdateHandler.handle(process.status());
}
- shell.setForegroundJob(null);
+// shell.setForegroundJob(null);
+ jobHandler.onSuspend(this);
return this;
}
@@ -147,6 +153,11 @@ public class JobImpl implements Job {
return line;
}
+ @Override
+ public boolean isRunInBackground() {
+ return runInBackground.get();
+ }
+
@Override
public Job toBackground() {
if (!this.runInBackground.get()) {
@@ -156,10 +167,12 @@ public class JobImpl implements Job {
if (statusUpdateHandler != null) {
statusUpdateHandler.handle(process.status());
}
+ jobHandler.onBackground(this);
}
}
- shell.setForegroundJob(null);
+// shell.setForegroundJob(null);
+// jobHandler.onBackground(this);
return this;
}
@@ -167,15 +180,16 @@ public class JobImpl implements Job {
public Job toForeground() {
if (this.runInBackground.get()) {
if (runInBackground.compareAndSet(true, false)) {
- if (foregroundUpdatedHandler != null) {
- foregroundUpdatedHandler.handle(this);
- }
+// if (foregroundUpdatedHandler != null) {
+// foregroundUpdatedHandler.handle(this);
+// }
process.toForeground();
if (statusUpdateHandler != null) {
statusUpdateHandler.handle(process.status());
}
- shell.setForegroundJob(this);
+// shell.setForegroundJob(this);
+ jobHandler.onForeground(this);
}
}
@@ -194,26 +208,32 @@ public class JobImpl implements Job {
@Override
public Job run(boolean foreground) {
- if (foreground && foregroundUpdatedHandler != null) {
- foregroundUpdatedHandler.handle(this);
- }
+// if (foreground && foregroundUpdatedHandler != null) {
+// foregroundUpdatedHandler.handle(this);
+// }
actualStatus = ExecStatus.RUNNING;
if (statusUpdateHandler != null) {
statusUpdateHandler.handle(ExecStatus.RUNNING);
}
- process.setTty(shell.term());
- process.setSession(shell.session());
+ //TODO process's tty
+ //process.setTty(shell.term());
+ process.setSession(this.session);
process.run(foreground);
- if (!foreground && foregroundUpdatedHandler != null) {
- foregroundUpdatedHandler.handle(null);
- }
-
+// if (!foreground && foregroundUpdatedHandler != null) {
+// foregroundUpdatedHandler.handle(null);
+// }
+//
+// if (foreground) {
+// shell.setForegroundJob(this);
+// } else {
+// shell.setForegroundJob(null);
+// }
if (foreground) {
- shell.setForegroundJob(this);
+ jobHandler.onForeground(this);
} else {
- shell.setForegroundJob(null);
+ jobHandler.onBackground(this);
}
return this;
}
@@ -230,9 +250,10 @@ public class JobImpl implements Job {
public void handle(Integer exitCode) {
if (!runInBackground.get() && actualStatus.equals(ExecStatus.RUNNING)) {
// 只有前台在运行的任务,才需要调用foregroundUpdateHandler
- if (foregroundUpdatedHandler != null) {
- foregroundUpdatedHandler.handle(null);
- }
+// if (foregroundUpdatedHandler != null) {
+// foregroundUpdatedHandler.handle(null);
+// }
+ jobHandler.onTerminated(JobImpl.this);
}
controller.removeJob(JobImpl.this.id);
if (statusUpdateHandler != null) {
@@ -240,12 +261,12 @@ public class JobImpl implements Job {
}
terminateFuture.complete();
- // save command history
- Term term = shell.term();
- if (term instanceof TermImpl) {
- List history = ((TermImpl) term).getReadline().getHistory();
- FileUtils.saveCommandHistory(history, new File(Constants.CMD_HISTORY_FILE));
- }
+ // TODO save command history
+// Term term = shell.term();
+// if (term instanceof TermImpl) {
+// List history = ((TermImpl) term).getReadline().getHistory();
+// FileUtils.saveCommandHistory(history, new File(Constants.CMD_HISTORY_FILE));
+// }
}
}