package com.vip.saturn.job.internal.sharding;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import com.vip.saturn.job.basic.AbstractSaturnJob;
import com.vip.saturn.job.basic.CrondJob;
import org.apache.curator.framework.api.CuratorWatcher;
import org.apache.zookeeper.WatchedEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.vip.saturn.job.basic.JobScheduler;
import com.vip.saturn.job.internal.listener.AbstractListenerManager;
import com.vip.saturn.job.threads.SaturnThreadFactory;
/**
* 分片监听管理器.
*
* @author linzhaoming
*
*/
public class ShardingListenerManager extends AbstractListenerManager {
static Logger log = LoggerFactory.getLogger(ShardingListenerManager.class);
private boolean isShutdown;
private CuratorWatcher necessaryWatcher;
private ShardingService shardingService;
public ShardingListenerManager(final JobScheduler jobScheduler) {
super(jobScheduler);
shardingService = jobScheduler.getShardingService();
if(!isCrondJob(jobScheduler.getCurrentConf().getSaturnJobClass())) { // because crondJob do nothing in onResharding method, no need this watcher
necessaryWatcher = new NecessaryWatcher();
}
}
private boolean isCrondJob(Class<?> saturnJobClass) {
if (saturnJobClass != null) {
Class<?> superClass = saturnJobClass.getSuperclass();
String crondJobCanonicalName = CrondJob.class.getCanonicalName();
String abstractSaturnJobCanonicalName = AbstractSaturnJob.class.getCanonicalName();
while (superClass != null) {
String superClassCanonicalName = superClass.getCanonicalName();
if (superClassCanonicalName.equals(crondJobCanonicalName)) {
return true;
}
if(superClassCanonicalName.equals(abstractSaturnJobCanonicalName)) { // AbstractSaturnJob is CrondJob's parent
return false;
}
superClass = superClass.getSuperclass();
}
}
return false;
}
@Override
public void start() {
if(necessaryWatcher != null) {
shardingService.registerNecessaryWatcher(necessaryWatcher);
}
}
@Override
public void shutdown() {
super.shutdown();
isShutdown = true;
}
class NecessaryWatcher implements CuratorWatcher {
@Override
public void process(WatchedEvent event) throws Exception {
switch (event.getType()) {
case NodeCreated:
case NodeDataChanged:
doBusiness(event);
default:
shardingService.registerNecessaryWatcher();
}
}
private void doBusiness(final WatchedEvent event) {
try {
// cannot block re-registerNecessaryWatcher, so use thread pool to do business,
// and the thread pool is the same with job-tree-cache's
zkCacheManager.getExecutorService().execute(new Runnable() {
@Override
public void run() {
try {
if (isShutdown) {
return;
}
if (jobScheduler == null || jobScheduler.getJob() == null) {
return;
}
log.info("[{}] msg={} trigger on-resharding event, type:{}, path:{}", jobName, jobName, event.getType(), event.getPath());
jobScheduler.getJob().onResharding();
} catch (Throwable t) {
log.error(t.getMessage(), t);
}
}
});
} catch (Throwable t) {
log.error(t.getMessage(), t);
}
}
}
}