前面文字介绍了定时任务模块,我们可以通过配置文件的动态配置来控制任务的行为。由于配置文件的动态更新是所有配置参数都重新更新,对于多线程的,某些情况下会影响到其他任务。如我们对任务A进行了restart ,下次我们对任务B进行shutdown,如果我们忘记将A的状态改为run,则A再次restart。现在我们利用上篇文章介绍的命令行消息输入模块TLMsgScanner来创建定时任务的命令行控制台,通过命令可以对任务进行管理,而无需更改配置文件。
定时任务命令行控制台模块为TLMsgTaskConsole,继承命令行消息控制类TLMsgScanner。其配置参数只有一个msgTaskModule,用来定义要管理的定时任务模块,可以在工厂配置中直接添加:
<module name="msgTaskConsole" classfile="cn.tianlong.tlobjcet.modules.TLMsgTaskConsole" msgTaskModule="myTaskManger" />
对于之前文章绍的定时任务案例,在入口程序中启动命令行控制台:
public class Main {
public static void main(String[] args)
{
String configdir = "/person/";
String path =Main.class.getResource(configdir).getPath();
System.setProperty("log4j.configurationFile", path+"log4j2.xml");
TLObjectFactory myfactory = TLObjectFactory.getInstance(configdir,"moduleFactory_config.xml");
myfactory.boot();
TLMsg taksMsg =new TLMsg().setAction("getModule").setParam("moduleName","myTaskManger");
myfactory.putMsg(myfactory,taksMsg);
myfactory.putMsg("msgTaskConsole",new TLMsg().setAction("startScan"));
}
}
其中最后一行 myfactory.putMsg("msgTaskConsole",new TLMsg().setAction("startScan")); 为启动命令。
TLMsgTaskConsole继承TLMsgScanner ,因此需要的配置也与TLMsgScanner一样,我们在代码中直接定义了默认配置:
@Override
protected void initProperty() {
super.initProperty();
if (params != null) {
if (params.get("msgTaskModule") != null) {
msgTaskModule = params.get("msgTaskModule");
} ;
}
params.put("defaultModule",name);
params.put("defaultAction","console");
HashMap<String ,String> mparams= new HashMap<>();
mparams.put("actions","console");
msgToModules=new HashMap<>();
msgToModules.put(name,mparams);
}
参数初始化中,定义了默认的消息接受模块为控制台模块自身,默认的消息指令为 "console" 。任何输入消息都发送给控制台,然后由控制台解析指令发送给定时任务模块:
@Override
protected TLMsg checkMsgAction(Object fromWho, TLMsg msg) {
TLMsg returnMsg=null;
switch (msg.getAction()) {
case "console":
console(fromWho,msg);
break;
default:
super.checkMsgAction( fromWho, msg);
}
return returnMsg;
}
private void console(Object fromWho, TLMsg msg) {
if(msgTaskModule==null)
{
putLog("msgTaskModule is null ",LogLevel.ERROR);
return;
}
execMsg(msg);
}
private boolean execMsg(TLMsg msg) {
HashMap<String,Object> cmds =msg.getArgs();
if(cmds.size() ==1)
{
for (String cmd : cmds.keySet()) {
if(cmds.get(cmd)==null)
{
if( execCmd( cmd))
return true;
else
{
System.out.println("no cmd: "+cmd);
return false ;
}
}
}
}
if(setTaskStatus(msg) == false)
{
System.out.println("no cmd: "+cmds.toString());
return false ;
}
else
return true ;
}
private Boolean execCmd(String cmd) {
if(cmd.contains(" "))
{
String str[] = cmd.split(" ");
if(str.length !=2)
{
System.out.println(" need params ,all or gave a taskid ");
return false ;
}
if(str[0].equals("shutdown") )
{
if(shutDownTocheckTaskid(str[1]))
shutdown(str[1]);
return true ;
}
if(str[0].equals("restart") )
{
if(checkTaskid (str[1]))
restart(str[1]);
return true ;
}
if(str[0].equals("stop") )
{
if(checkTaskid (str[1]))
stop(str[1]);
return true ;
}
if(str[0].equals("run") )
{
if(checkTaskid (str[1]))
run(str[1]);
return true ;
}
return false ;
}
switch (cmd) {
case "list":
listTask();
return true;
default:
return false ;
}
}
执行效果:
控制台命令:
1、 run/stop/shutdown/restart all 或者taskid ,运行、停止、关闭、重启所有任务或某个任务
其中 shutdown all 取消所有任务线程但不关闭线程池
shutdown pool 关闭线程池。
run:运行一个任务,如果任务没启动则启动,对于暂停的任务继续运行,对于已经运行的任务不影响
stop:暂停任务,任务线程存在,可用run继续运行。
restart : 不管任务状态为何,都重新启动。
2、给任务设置参数 : t=任务id s=任务状态 ,其他参数与配置文件一样 。