StartCommand.java 6.62 KB
package com.bsth;


import com.bsth.repository.schedule.CarConfigInfoRepository;
import com.bsth.security.SecurityMetadataSourceService;
import com.bsth.service.realcontrol.buffer.GetSchedulePlanThread;
import com.bsth.service.realcontrol.buffer.SchedulePersistenceThread;
import com.bsth.util.DateUtils;
import com.bsth.vehicle.common.CommonRefreshThread;
import com.bsth.vehicle.directive.service.DirectiveService;
import com.bsth.vehicle.directive.thread.DirectivePersistenceThread;
import com.bsth.vehicle.directive.thread.FirstScheduleIssuedThread;
import com.bsth.vehicle.gpsdata.GpsArrivalThread;
import com.bsth.vehicle.gpsdata.GpsRefreshThread;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * 随应用启动运行
 * @author PanZhao
 *
 */
@Component
public class StartCommand implements CommandLineRunner{

	Logger logger = LoggerFactory.getLogger(this.getClass());
	
	@Autowired
	SecurityMetadataSourceService invocationSecurityMetadataSourceService;
	
	public static ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(7);
	
	@Autowired
	GpsRefreshThread gpsRefreshThread;
	@Autowired
	GetSchedulePlanThread getSchedulePlanThread;
	@Autowired
	CommonRefreshThread commonRefreshThread;
	@Autowired
	DirectivePersistenceThread directivePersistenceThread;
	@Autowired
	SchedulePersistenceThread SchedulePersistenceThread;
	@Autowired
	GpsArrivalThread gpsArrivalStationThread;
	@Autowired
	FirstScheduleIssuedThread firstScheduleIssuedThread;
	
	@Autowired
	DirectiveService directiveService;
	@Autowired
	CarConfigInfoRepository carConfigInfoRepository;
	
	static Long hourTime = 1000 * 60 * 60L;
	
	@Override
	public void run(String... arg0){
		
		try {
			//启动时加载所有资源
			invocationSecurityMetadataSourceService.loadResourceDefine();
			
			/**
			 * GPS实时数据更新 线程
			 * 每8秒和网关HTTP接口同步一次
			 */
			scheduler.scheduleWithFixedDelay(gpsRefreshThread, 0, 8, TimeUnit.SECONDS);
			
			/**
			 * 每天 凌晨 2 点 抓取当天实际排班
			 */
			//启动时先run一次
			getSchedulePlanThread.start();
			scheduler.scheduleAtFixedRate(getSchedulePlanThread
					, ((DateUtils.getTimesnight2() + hourTime * 2) - System.currentTimeMillis()) / 1000
					, 60 * 60 * 24, TimeUnit.SECONDS);
			
			/**
			 * 调度指令两分钟入库一次
			 * 指令会缓存在内存,直到收到所有响应再入库
			 */
			scheduler.scheduleWithFixedDelay(directivePersistenceThread, 20, 60 * 2, TimeUnit.SECONDS);
			
			/**
			 * 车辆,设备,公司等常用的映射数据,每两小时刷新一次
			 */
			scheduler.scheduleWithFixedDelay(commonRefreshThread, 0, 60 * 60 * 2, TimeUnit.SECONDS);
			
			/**
			 * 每分钟将有变更的班次入库(不包括子任务)
			 * 单纯为了提高 线调操作 的响应速度
			 */
			scheduler.scheduleWithFixedDelay(SchedulePersistenceThread, 60 * 1, 60 * 1, TimeUnit.SECONDS);
			
			/**
			 * 每15秒从数据库抓取到离站信息和班次匹配
			 * (网关生成的到离站数据也是延迟批量入库,所以缩短该线程执行周期并不会提高 “实际到离站” 的实时性)
			 */
			scheduler.scheduleWithFixedDelay(gpsArrivalStationThread, 15, 20, TimeUnit.SECONDS);
			
			/**
			 * 首个调度指令下发(2分钟运行一次)
			 * 每辆车的第一个调度指令由该线程下发
			 * 后续班次由 “实际终点到达” 事件触发指令下发
			 */
			scheduler.scheduleWithFixedDelay(firstScheduleIssuedThread, 60 , 60 * 2, TimeUnit.SECONDS);
			
			/**
			 * ######### 测试  ###############
			 */
/*			new Timer().schedule(new TimerTask() {
				
				@Override
				public void run() {
					//根据班次模拟一份到离站数据
					Set<String> set = ScheduleBuffer.vehSchListMap.keySet();
					ArrivalInfo outArr, inArr;
					List<ArrivalInfo> arrList = new ArrayList<>();
					Date d = new Date();
					for(String nbbm : set){
						
						for(ScheduleRealInfo sch : ScheduleBuffer.vehSchListMap.get(nbbm)){
							//发出
							outArr = new ArrivalInfo(CommonMapped.vehicDeviceBiMap.inverse().get(nbbm)
									, sch.getFcsjT(), sch.getXlBm(), Integer.parseInt(sch.getXlDir()), sch.getQdzCode(), 1, d , 31);
							
							//到达
							inArr = new ArrivalInfo(CommonMapped.vehicDeviceBiMap.inverse().get(nbbm)
									, sch.getZdsjT(), sch.getXlBm(), Integer.parseInt(sch.getXlDir()), sch.getZdzCode(), 0, d , 31);
							
							arrList.add(outArr);
							arrList.add(inArr);
						}
					}
					try {
						Connection conn = DBUtils_MS.getConnection();
						String sql = "insert into bsth_c_arrival_info(device_id, line_id, stop_no, ts, up_down, in_out, weeks_year, create_date)"
								+ " values(?, ?, ?, ? , ?, ?,?, now())";
						
						conn.setAutoCommit(false);
						java.sql.PreparedStatement ps = conn.prepareStatement(sql);
						
						for(ArrivalInfo arr : arrList){
							ps.setString(1, arr.getDeviceId());
							ps.setString(2, arr.getLineCode());
							ps.setString(3, arr.getStopNo());
							ps.setLong(4, arr.getTs() == null? 0: arr.getTs());
							ps.setInt(5, arr.getUpDown());
							ps.setInt(6, arr.getInOut());
							ps.setInt(7, arr.getWeeksYear());
							
							ps.addBatch();
						}
						
						ps.executeBatch();
						conn.commit();
					} catch (SQLException e) {
						e.printStackTrace();
					}
					
					//new BatchSaveUtils<ArrivalInfo>().saveList(arrList, ArrivalInfo.class);
				}
			}, 5000);*/
			
/*			//延迟一会
			new Timer().schedule(new TimerTask() {
				
				@Override
				public void run() {
					//临时全量刷车辆线路
					List<CarConfigInfo> ccis = carConfigInfoRepository.findAll();
					Cars car;
					Line line;
					String lineCode;
					int code;
					for(CarConfigInfo cci : ccis){
						car = cci.getCl();
						line = cci.getXl();
						lineCode = line.getLineCode();
						System.out.println("车辆:" + car.getInsideCode() + "切换线路:" + line.getLineCode());
						code = directiveService.lineChange(car.getInsideCode(), Integer.parseInt(lineCode));
						//directiveService.send60Phrase(car.getInsideCode(), "");
						System.out.println("返回值:" + code);
					}
				}
			}, 1000 * 10);*/
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}