集群环境下的单例任务调度基类

本文介绍了一种在集群环境下实现基于ID的单例任务调度基类的方法,该方法确保同一时间只调度一次任务,并通过超时机制处理任务状态。详细解释了接口声明、实现机理及关键代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近为公司框架提供了基于ID的单例的任务调度基类,用于集群的环境下,一个任务同一时间只能被调度一次。

 

接口声明
继承该基类的任务需要覆盖两个抽象函数:
        protected abstract String getServiceID();//服务ID,与数据库中的和timeservice.xml中的要配置相同       
        protected abstract void doTask();//执行任务,需覆盖的业务方法

 

实现机理

每个任务要有唯一的ServiceId,该任务在t_s_sys_timeservice 中有一条记录,同时有一个state记录着状态信息,state为0表示未占用,state为1表示已占用。

设计上还要考虑处理异常的情况,通过引入一个超时时间,如果已经超时,则认为改状态为未被占用

 

关键代码

 

package com.itown.framework.schedule;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.apache.log4j.Logger;

import com.itown.framework.exception.ServiceInvokeException;
import com.itown.framework.impl.ThreadContext;
import com.itown.framework.persistence.DataSourceFactory;
import com.itown.framework.persistence.ParamsMaker;
import com.itown.framework.persistence.SingleDBHelper;
import com.itown.framework.transaction.FrameworkTransaction;
import com.itown.framework.transaction.JDBCTransaction;

/**
*	timeout_interval用来设定超时时间,单位是秒,极端情况state可能为1,当达到超时时间时,再次执行,要求超时时间一定要大于task的执行时间
*/
public abstract class SingletonTimeService extends TimeService {
	
	private static final Logger	logger	= Logger.getLogger(SingletonTimeService.class);
	
	private String selectSql = "select * from t_s_sys_timeservice where (id = ? and state = '0') or (id = ? and sysdate > update_date + timeout_interval/86400 )"; 
	private String updateLockSql = "update t_s_sys_timeservice set update_date = sysdate,state = 1 where (id = ? and state = '0') or (id = ? and sysdate > update_date + timeout_interval/86400 )"; 
	private String updateUnlockSql = "update t_s_sys_timeservice set update_date = sysdate,state = '1' where id = ?"; 
	
	public void doTimeService() {
        String funcName = "SingletonTimeService.doTimeService";
        logger.info(funcName + " begin time:" + System.currentTimeMillis());
		ThreadContext ctx = ThreadContext.getThreadContext();
		FrameworkTransaction _tr = null;
		Connection _conn = null;
		try {
			_conn = DataSourceFactory.getDefaultConnection();			
			_tr = new JDBCTransaction(_conn);
			_tr.begin();			

			//争任务,此处无法采用框架提供的封装
			PreparedStatement ps = null;
			ResultSet rs = null;
			try {
				logger.info(funcName + " selectSql:" + selectSql);
				logger.info(funcName + " id:" + getServiceID());
				ps = _conn.prepareStatement(selectSql);
				ps.setString(1, getServiceID());
				ps.setString(2, getServiceID());
				rs = ps.executeQuery();
			} catch (SQLException ex) {
				logger.error(ex);
				throw ex;
			}
			int result =0;//result > 0 表示抢到任务
			if(rs.next()){
				SingleDBHelper helper = new SingleDBHelper(_conn);				
				//锁定任务
				try{
					logger.info(funcName + " updateLockSql:" + updateLockSql);
					logger.info(funcName + " id:" + getServiceID());
					result=helper.executeUpdate(updateLockSql,ParamsMaker.makeParams(getServiceID()));
					_tr.commit();
					
				}catch(Exception e){
					logger.error(e);
				}
				
				//执行任务
				try{
					_tr.begin();
					logger.info(funcName + " 开始执行timeservice(id="+getServiceID()+")任务...");
					if(result>0){
						doTask();
					}
					logger.info(funcName + " 结束执行timeservice(id="+getServiceID()+")任务。");
				}catch(Throwable e){
					logger.error(e);
					throw e;
					
				}				

				//解锁
				//注释此timeservice解锁业务,超时会自动满足timeservice执行条件;

				try{
					logger.info(funcName + " updateUnlockSql:" + updateUnlockSql);
					logger.info(funcName + " id:" + getServiceID());
					if(result>0){
						helper.executeUpdate(updateUnlockSql,ParamsMaker.makeParams(getServiceID()));
					}
				}catch(Exception e){
					logger.error(e);
				}
				
			}
			
			//事务相关操作
			_tr.commit();							
		} catch (Throwable ex) {
			if (_tr != null) {
				try {
					_tr.rollback();
				} catch (Exception ex1) {
					logger.error(ex1);
				}
			}
			throw new ServiceInvokeException("调度异常", ex);
		} finally {
			ctx.runShieldStatements();
			DataSourceFactory.release(_conn);
		}
	}

	protected abstract String getServiceID();
	
	protected abstract void doTask();
}

 

 

``` #include "swarm_node.h" // mc_control_instance* mc_control_instance::instance = nullptr; Swarm_Node::Swarm_Node() : ModuleParams(nullptr), ScheduledWorkItem(MODULE_NAME, px4::wq_configurations::swarm_node) { } Swarm_Node::~Swarm_Node() { perf_free(_loop_perf); perf_free(_loop_interval_perf); } bool Swarm_Node::init() { // execute Run() on every sensor_accel publication //if (!_sensor_accel_sub.registerCallback()) { // PX4_ERR("callback registration failed"); // return false; //} // alternatively, Run on fixed interval ScheduleOnInterval(20000_us); // 2000 us interval, 200 Hz rate return true; } bool Swarm_Node::takeoff() { control_instance::getInstance()->Control_posxyz(begin_x,begin_y,begin_z-5); return false; } bool Swarm_Node::arm_offboard() { return false; } bool Swarm_Node::swarm_node_init() { _vehicle_local_position_sub.copy(&_vehicle_local_position); _a01_sub.copy(&_target); _a02_sub.copy(&_start_flag); // _target.lat= 47.3978161; // _target.lon=8.5460368; // PX4_INFO("_start_flag.start_swarm=%d",_start_flag.start_swarm); if((_vehicle_local_position.xy_valid)&&_start_flag.start_swarm) { vehicle_status_s _vehicle_status; if(_vehicle_status_sub.copy(&_vehicle_status)) { vehicle_id=_vehicle_status.system_id; if(vehicle_id>1) { _global_local_proj_ref.initReference(_vehicle_local_position.ref_lat,_vehicle_local_position.ref_lon,hrt_absolute_time()); _global_local_proj_ref.project(_target.lat,_target.lon,target_x,target_y); float dist =sqrtf((_vehicle_local_position.x-target_x)*(_vehicle_local_position.x-target_x)+(_vehicle_local_position.y-target_y)*(_vehicle_local_position.y-target_y)); // mavlink_log_info(&_mavlink_log_pub, "与目标的距离:%f",_a02_dist_to_target.dist_to_target); if(dist<200) { // mavlink_log_info(&_mavlink_log_pub, "与目标的距离:%f",_a02_dist_to_target.dist_to_target); _vehicle_local_position_sub.copy(&_vehicle_local_position); begin_x=_vehicle_local_position.x; begin_y=_vehicle_local_position.y; begin_z=_vehicle_local_position.z; _global_local_proj_ref.initReference(_vehicle_local_position.ref_lat,_vehicle_local_position.ref_lon,hrt_absolute_time()); return true; } else { return false; } } else if(vehicle_id==1) { time_tick=hrt_absolute_time(); return true; } } } else { return false; } return false; }```解释插入代码
最新发布
03-22
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值