All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.yuweix.kuafu.schedule.base.AbstractTask Maven / Gradle / Ivy

There is a newer version: 2.0.0
Show newest version
package com.yuweix.kuafu.schedule.base;


import com.yuweix.kuafu.data.elect.Elector;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.ref.SoftReference;
import java.lang.reflect.Field;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;


/**
 * @author yuwei
 */
public abstract class AbstractTask {
	private static final Logger log = LoggerFactory.getLogger(AbstractTask.class);
	private static final Elector DEFAULT_LEADER_ELECTOR = new Elector() {
		@Override
		public String acquire(String lock) {
			return getLocalNode();
		}
		@Override
		public void release(String lock) {
			//NO-OP
		}
		@Override
		public String getLocalNode() {
			return "local";
		}
	};

	private static SoftReference, ElectorWrapper>> ELECTOR_MAP_REF;
	private static final Object electorLock = new Object();
	private static final class ElectorWrapper {
		private Elector elector = null;
		ElectorWrapper(Elector elector) {
			this.elector = elector;
		}
	}
	private static final ElectorWrapper EMPTY_ELECTOR = new ElectorWrapper(null);

	public AbstractTask() {

	}

	public void execute() {
		this.start();
	}

	public final void start() {
		if (!isEnabled()) {
			return;
		}
		long startTime = System.currentTimeMillis();
		Elector elector = getLeaderElector();
		if (elector == null) {
			elector = DEFAULT_LEADER_ELECTOR;
		}

		String lockName = getLockName();
		boolean release = getRelease();
		Elector.R res = elector.tryAcquire(lockName);
		if (res.isSuccess()) {
			before();
			try {
				executeTask();
			} catch (Exception e) {
				handle(e);
			} finally {
				if (release) {
					try {
						elector.release(lockName);
					} catch (Exception ignored) {
					}
				}
			}
			after();
			long elapsedTime = System.currentTimeMillis() - startTime;
			log.info("Job executed here, Job name: {}, Local node: {}, Time elapsed: {}"
					, this.getClass().getName(), res.getLocal(), elapsedTime >= 1000 ? (elapsedTime / 1000.0) + "s" : elapsedTime + "ms");
		} else {
			log.warn("Not leader, job didn't execute! Job name: {}, Leader: {}", this.getClass().getName(), res.getLeader());
		}
	}

	protected boolean isEnabled() {
		return true;
	}

	protected void before() {

	}
	protected void handle(Throwable t) {
		log.error("{}", t.getMessage());
	}
	protected void after() {

	}
	protected abstract void executeTask();
	protected String getLockName() {
		return this.getClass().getName();
	}

	/**
	 * 是否释放Leader选择器
	 */
	protected boolean getRelease() {
		return true;
	}

	private static Map, ElectorWrapper> getElectorWrapperMap() {
		Map, ElectorWrapper> map = null;
		if (ELECTOR_MAP_REF == null || (map = ELECTOR_MAP_REF.get()) == null) {
			synchronized (electorLock) {
				if (ELECTOR_MAP_REF == null || (map = ELECTOR_MAP_REF.get()) == null) {
					map = new ConcurrentHashMap<>();
					ELECTOR_MAP_REF = new SoftReference<>(map);
				}
			}
		}
		return map;
	}
	protected Elector getLeaderElector() {
		Class clz = this.getClass();
		Map, ElectorWrapper> map = getElectorWrapperMap();
		ElectorWrapper wrapper = map.get(clz);
		if (wrapper == null) {
			synchronized (this) {
				wrapper = map.get(clz);
				if (wrapper == null) {
					wrapper = reflectElector(clz);
					map.put(clz, wrapper);
				}
			}
		}
		return wrapper.elector;
	}
	private ElectorWrapper reflectElector(Class clazz) {
		while (clazz != null) {
			Field[] fields = clazz.getDeclaredFields();
			for (Field f: fields) {
				if (f.getType() == Elector.class) {
					f.setAccessible(true);
					try {
						return new ElectorWrapper((Elector) f.get(this));
					} catch (IllegalAccessException e) {
						throw new RuntimeException(e);
					}
				}
			}
			clazz = clazz.getSuperclass();
		}
		return EMPTY_ELECTOR;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy