From 64cee4f389222cce425c4af60773fbffe69cf8a5 Mon Sep 17 00:00:00 2001 From: kylixs Date: Mon, 23 Mar 2020 22:43:39 +0800 Subject: [PATCH] extract JobListener, remove dependency ShellImpl --- .../taobao/arthas/core/shell/system/Job.java | 5 + .../arthas/core/shell/system/JobListener.java | 18 +++ .../shell/system/impl/JobControllerImpl.java | 38 +++++- .../core/shell/system/impl/JobImpl.java | 109 +++++++++++------- 4 files changed, 125 insertions(+), 45 deletions(-) create mode 100644 core/src/main/java/com/taobao/arthas/core/shell/system/JobListener.java 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)); +// } } }