package com.yahoo.dtf.components; import java.util.ArrayList; import java.util.HashMap; import com.yahoo.dtf.actions.Action; import com.yahoo.dtf.exception.DTFException; import com.yahoo.dtf.state.ActionState; /** * This class is responsible for knowing which components currently hold remote * state for threads from the runner side and will issue a RemoveState action * for all the recently dead runner threads in order to free up resources on the * agent side at runtime. * * The Node class itself already makes sure to clean up all the remote state * generated at runtime but if we don't do some runtime clean up we can use up * all the resources on an agent over a very long period of creating and * destroying thread son the runner side. * * @author rlgomes */ public class StateComponentHook implements ComponentHook { private final static String SENT_STATES = "dtf.sentstates."; private static ArrayList<String> deadThreads = new ArrayList<String>(); private synchronized static ArrayList<String> getSentStates(String id) { HashMap<String, ArrayList<String>> map = (HashMap<String, ArrayList<String>>) Action.getGlobalContext(SENT_STATES + id); if (map == null) { map = new HashMap<String, ArrayList<String>>(); Action.registerGlobalContext(SENT_STATES + id, map); } ArrayList<String> sent = map.get(id); if ( sent == null ) { sent = new ArrayList<String>(); map.put(id, sent); } return sent; } public static void threadDead(String id) { synchronized (deadThreads) { deadThreads.add(id); } } public ArrayList<Action> handleComponent(String id) throws DTFException { ArrayList<Action> result = new ArrayList<Action>(); ArrayList<String> sentState = getSentStates(id); synchronized ( sentState ) { for (int i = 0; i < sentState.size(); i++) { String thread = sentState.get(i); if ( deadThreads.contains(thread) ) { CleanUpState cs = new CleanUpState(); cs.setId(thread); result.add(cs); sentState.remove(thread); } } } String tname = ActionState.getInstance().getCurrentID(); sentState.add(tname); return result; } }