package act.job; /*- * #%L * ACT Framework * %% * Copyright (C) 2014 - 2017 ActFramework * %% * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * #L% */ import act.cli.*; import act.event.OnEvent; import act.util.JsonView; import act.util.PropertySpec; import act.util.SimpleProgressGauge; import act.ws.WebSocketConnectEvent; import act.ws.WebSocketConnectionManager; import act.ws.WebSocketContext; import act.ws.WsEndpoint; import com.alibaba.fastjson.JSONObject; import org.osgl.$; import org.osgl.util.C; import org.osgl.util.S; import javax.inject.Inject; import java.util.Comparator; import java.util.List; import java.util.concurrent.ScheduledThreadPoolExecutor; /** * Provide admin service to act {@link JobManager} */ @SuppressWarnings("unused") public class JobAdmin { private static Comparator _UNIQ_JOB_FILTER = new Comparator() { @Override public int compare(Job o1, Job o2) { return o1.id().compareTo(o2.id()); } }; /** * List all jobs in the job manager * @return a list of {@link Job jobs} */ @Command(value = "act.job.list", help = "List jobs") @PropertySpec(Job.BRIEF_VIEW) @TableView public List listJobs(@Optional(lead = "-q") final String q, JobManager jobManager) { C.List jobs = jobManager.jobs().append(jobManager.virtualJobs()).unique(_UNIQ_JOB_FILTER); if (S.notBlank(q)) { jobs = jobs.filter(new $.Predicate() { @Override public boolean test(Job job) { return job.toString().contains(q); } }); } return jobs; } @Command(value = "act.job.show", help = "Show job details") @JsonView @PropertySpec(Job.DETAIL_VIEW) public Job getJob(@Required("specify job id") final String id, JobManager jobManager) { return jobManager.jobById(id); } @Command(value = "act.job.progress", help = "Show job progress") public int getJobProgress(@Required("specify job id") final String id, JobManager jobManager) { Job job = jobManager.jobById(id); return null == job ? -1 : job.getProgressInPercent(); } @Command(name = "act.job.cancel", help = "Cancel a job") public void cancel(@Required("specify job id") String id, JobManager jobManager) { jobManager.cancel(id); } @Command(value = "act.job.scheduler", help = "Show Job manager scheduler status") public String getSchedulerStatus(JobManager jobManager) { ScheduledThreadPoolExecutor executor = jobManager.executor(); JSONObject json = new JSONObject(); json.put("is terminating", executor.isTerminating()); json.put("is terminated", executor.isTerminated()); json.put("is shutdown", executor.isShutdown()); json.put("# of runnable in the queue", executor.getQueue().size()); json.put("active count", executor.getActiveCount()); json.put("# of completed tasks", executor.getActiveCount()); json.put("core pool size", executor.getCorePoolSize()); json.put("pool size", executor.getPoolSize()); return json.toJSONString(); } public static class WebsocketEndpoints { @WsEndpoint("/~/job/{id}/progress") public static class JobProgress { @Inject private WebSocketConnectionManager connectionManager; @OnEvent public void onConnect(WebSocketConnectEvent event) { WebSocketContext context = event.source(); String jobId = context.actionContext().paramVal("id"); String tag = SimpleProgressGauge.wsJobProgressTag(jobId); connectionManager.subscribe(context.actionContext().session(), tag); } } } }