package org.zstack.core.gc; import org.zstack.core.cloudbus.EventCallback; import org.zstack.core.thread.AsyncThread; import org.zstack.utils.DebugUtils; import java.util.HashMap; import java.util.Map; /** * Created by xing5 on 2017/3/3. */ public abstract class EventBasedGarbageCollector extends GarbageCollector { public void load(GarbageCollectorVO vo) { loadFromVO(vo); setup(); installTriggers(); logger.debug(String.format("[GC] loaded a job[name:%s, id:%s]", NAME, uuid)); if (!lock()) { logger.debug(String.format("[GC] the job[name:%s, id:%s] is being executed by another trigger," + "skip management node to excuete", NAME, uuid)); return; } logger.debug(String.format("[GC] the job[name:%s, id:%s] is triggered by management node", NAME, uuid)); runTrigger(); } private Map<String, EventCallback> eventCallbacks = new HashMap<>(); protected void onEvent(String path, Trigger c) { eventCallbacks.put(path, new EventCallback() { @Override @AsyncThread protected void run(Map tokens, Object data) { GarbageCollectorVO vo = dbf.findByUuid(uuid, GarbageCollectorVO.class); if (vo == null) { logger.warn(String.format("[GC] cannot find a job[name:%s, id:%s], assume it's deleted", NAME, uuid)); cancel(); return; } if (!c.trigger(tokens, data)) { // don't trigger it return; } if (!lock()) { logger.debug(String.format("[GC] the job[name:%s, id:%s] is being executed by another trigger," + "skip this event[%s]", NAME, uuid, path)); return; } logger.debug(String.format("[GC] the job[name:%s, id:%s] is triggered by an event[%s]", NAME, uuid, path)); vo.setStatus(GCStatus.Processing); dbf.update(vo); runTrigger(); } }); } protected abstract void setup(); private void installTriggers() { setup(); DebugUtils.Assert(!eventCallbacks.isEmpty(), String.format("%s[%s] doesn't call onEvent() in the setup() to install any triggers", NAME, getClass())); for (Map.Entry<String, EventCallback> e : eventCallbacks.entrySet()) { evtf.onLocal(e.getKey(), e.getValue()); } canceller = () -> eventCallbacks.values().forEach((it) -> evtf.off(it)); } public final void submit() { saveToDb(); installTriggers(); gcMgr.registerGC(this); } }