package multimonster.resourcemanager; import multimonster.common.MMThread; import multimonster.common.UserIdentifier; import multimonster.common.resource.Costs; import multimonster.common.resource.QueueTime; import multimonster.common.resource.ResourceRequestIdentifier; import multimonster.common.resource.ResourceWaiter; import multimonster.resourcemanager.exceptions.ManagementException; import multimonster.resourcemanager.exceptions.NoResourcesAvailable; import multimonster.resourcemanager.exceptions.ResourceManagerException; import org.apache.log4j.Logger; /** * @author Holger Velke * */ class ResourceManager { private static Logger log = Logger.getLogger(ResourceManager.class); /** * @label uses * @clientCardinality 1 * @supplierCardinality 1 */ private ManagementPlugIn management = null; private RequestQueue queue = null; /** * @link * @shapeType PatternLink * @pattern Singleton * @supplierRole Singleton factory */ /*# private ResourceManager _resourceManager; */ private static ResourceManager instance = null; /** * @label creates * @labelDirection forward */ private ResourceRequest lnkResourceRequest; /** * @throws ResourceManagerException * */ private ResourceManager() throws ResourceManagerException { ResourceManagerPlugInFactory factory = null; factory = ResourceManagerPlugInFactory.getInstance(); try { this.management = factory.getManagementPlugIn(); } catch (ManagementException e) { throw new ResourceManagerException("No resource-management available.", e); } } /** * @param uId * @param costs * @param maxQT * @return */ public synchronized ResourceRequestIdentifier requestResources( UserIdentifier uId, Costs costs, QueueTime maxQT, ResourceWaiter waiter) { ResourceRequestIdentifier rrId = null; ResourceRequest request = null; // log.debug("requestResource()"); request = new ResourceRequest(uId, costs, maxQT, waiter); if (queue == null) queue = getRequestQueue(request); else if (!queue.isRunning()) queue = getRequestQueue(request); else queue.add(request); rrId = request.getRrId(); return rrId; } /** * @return */ private RequestQueue getRequestQueue(ResourceRequest request) { RequestQueue queue = new RequestQueue(this); queue.add(request); (new MMThread(queue)).start(); return queue; } /** * @param uId * @param costs * @return */ public synchronized ResourceRequestIdentifier requestResources( UserIdentifier uId, Costs costs) { ResourceRequestIdentifier rrId = null; ResourceRequest request = null; // log.debug("requestResource()"); if (management == null) { log.error("no management plugin - unable to grant resources"); // TODO better throw NoManagementPlugIn Exception return null; } try { request = new ResourceRequest(uId, costs); management.reserve(request); rrId = request.getRrId(); } catch (NoResourcesAvailable e) { // TODO better throw an exception rrId = null; } catch (ManagementException e) { log.error("problem reserving resources - " + e.getMessage()); // TODO better throw an exception rrId = null; } log.info("grantResources: "+rrId); return rrId; } /** * @param rrId * @return */ public synchronized Costs releaseResources(ResourceRequestIdentifier rrId) throws ResourceManagerException { Costs realCosts = null; log.info("releaseResources: "+rrId); realCosts = management.free(rrId); if ((queue != null)&&(queue.isRunning())){ // queue is only running if someone is waiting for resources queue.notifyFreeResources(); } return realCosts; } /** * @return the singleton <code>ResourceManager</code> * @throws ResourceManagerException */ public static ResourceManager getInstance() throws ResourceManagerException { if (instance == null) { synchronized (multimonster.resourcemanager.ResourceManager.class) { if (instance == null) { instance = new multimonster.resourcemanager.ResourceManager(); } } } return instance; } /** * @param request * @return <code>true</code> if resources are reserved <br> * <code>false</code> if not */ public synchronized boolean requestResources(ResourceRequest request) { boolean result = false; try { management.reserve(request); result = true; } catch (NoResourcesAvailable e) { result = false; } catch (ManagementException e) { log.error("problem reserving resources - " + e.getMessage()); result = false; } return result; } }