/* * Copyright to the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.rioproject.cybernode.service; import org.rioproject.deploy.ServiceBeanInstance; import org.rioproject.event.EventHandler; import org.rioproject.opstring.ServiceElement; import org.rioproject.sla.SLA; import org.rioproject.sla.SLAThresholdEvent; import org.rioproject.system.SystemWatchID; import org.rioproject.watch.Calculable; import org.rioproject.impl.watch.ThresholdListener; import org.rioproject.watch.ThresholdType; import org.rioproject.watch.ThresholdValues; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicBoolean; /** * If thresholds get crossed for memory related MeasurableCapability components, this class * will either request immediate garbage collection or (in the case of perm gen) * release as a provisionable resource. * * @author Dennis Reedy */ public class ComputeResourcePolicyHandler implements ThresholdListener { private final EventHandler thresholdEventHandler; private final ServiceElement serviceElement; private final Executor thresholdTaskPool = Executors.newCachedThreadPool(); private final ServiceConsumer serviceConsumer; private final ServiceBeanInstance instance; private final AtomicBoolean terminate = new AtomicBoolean(false); private static final Logger logger = LoggerFactory.getLogger(ComputeResourcePolicyHandler.class.getName()); public ComputeResourcePolicyHandler(final ServiceElement serviceElement, final EventHandler thresholdEventHandler, final ServiceConsumer serviceConsumer, final ServiceBeanInstance instance) { this.serviceElement = serviceElement; this.thresholdEventHandler = thresholdEventHandler; this.instance = instance; this.serviceConsumer = serviceConsumer; } public void terminate() { terminate.set(true); } public void notify(Calculable calculable, ThresholdValues thresholdValues, ThresholdType type) { if(terminate.get()) return; String status = type.name().toLowerCase(); logger.debug("Threshold={}, Status={}, Value={}, Low={}, High={}", calculable.getId(), status, calculable.getValue(), thresholdValues.getLowThreshold(), thresholdValues.getHighThreshold()); if(type==ThresholdType.BREACHED) { double tValue = calculable.getValue(); if(tValue>thresholdValues.getCurrentHighThreshold()) { if(serviceConsumer!=null) { serviceConsumer.updateMonitors(); } if(calculable.getId().equals(SystemWatchID.JVM_MEMORY)) { logger.warn("Memory utilization is {}, threshold set at {}, request immediate garbage collection", calculable.getValue(), thresholdValues.getCurrentHighThreshold()); System.gc(); } if(calculable.getId().contains(SystemWatchID.JVM_PERM_GEN)) { logger.warn("Perm Gen has breached with utilization > {}", thresholdValues.getCurrentHighThreshold()); //if(isEnlisted()) //release(false); //svcConsumer.cancelRegistrations(); } } } else if(type== ThresholdType.CLEARED) { if(serviceConsumer!=null) { serviceConsumer.updateMonitors(); } } try { double[] range = new double[]{thresholdValues.getCurrentLowThreshold(), thresholdValues.getCurrentHighThreshold()}; SLA sla = new SLA(calculable.getId(), range); SLAThresholdEvent event = new SLAThresholdEvent(instance.getService(), serviceElement, instance, calculable, sla, serviceElement.getName()+" Resource Policy Handler", instance.getHostAddress(), type); thresholdTaskPool.execute(new SLAThresholdEventTask(event, thresholdEventHandler)); } catch(Exception e) { logger.warn("Could not send a SLAThresholdEvent as a result of compute resource threshold [{}] being crossed", calculable.getId(), e); } } }