package net.sf.appstatus.services; import java.util.concurrent.atomic.AtomicLong; import net.sf.appstatus.core.services.IService; import org.apache.commons.lang3.ObjectUtils; public class Service implements IService { protected AtomicLong cacheHits = new AtomicLong(); protected AtomicLong hits = new AtomicLong(); protected AtomicLong running = new AtomicLong(); protected String name; protected String group; private CachedCallStatistics totalStats; private CachedCallStatistics windowStats; private CachedCallStatistics windowPrevisiousStats; private long windowSize = 2000; private long windowStart = 0; private int minMaxDelay; public Service(int minMaxDelay) { this.minMaxDelay = minMaxDelay; totalStats = new CachedCallStatistics(minMaxDelay); windowStats = new CachedCallStatistics(minMaxDelay); windowPrevisiousStats = new CachedCallStatistics(minMaxDelay); } public long getRunning() { while (true) { long runningCalls = running.get(); if (runningCalls < 0) { // Try to fix value running.compareAndSet(runningCalls, 0); } else return runningCalls; } } /** * This method is synchronized to ensure correct statistics computation * * @param executionTime * @param cacheHit * @param failure * @param error */ public void addCall(Long executionTime, boolean cacheHit, boolean failure, boolean error, int nestedCalls) { totalStats.addCall(executionTime, cacheHit, failure, error, nestedCalls); updateWindows(); windowStats.addCall(executionTime, cacheHit, failure, error, nestedCalls); } /** * Archive previous window if expired, and create a new window for next * results. */ private void updateWindows() { long currentTime = System.currentTimeMillis(); if (currentTime - windowStart > windowSize) { synchronized (this) { if (currentTime - windowStart > windowSize) { if (currentTime - windowStart <= 2 * windowSize) { windowPrevisiousStats = windowStats; } else { windowPrevisiousStats = new CachedCallStatistics(minMaxDelay); } windowStats = new CachedCallStatistics(minMaxDelay); windowStart = currentTime; } } } } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getGroup() { return group; } public void setGroup(String group) { this.group = group; } public Double getAvgResponseTime() { return totalStats.getDirectStatistics().getAvgResponseTime(); } public long getCacheHits() { return cacheHits.get(); } public long getHits() { return hits.get(); } public long getFailures() { return totalStats.getFailures(); } public long getErrors() { return totalStats.getErrors(); } public Long getMaxResponseTime() { return totalStats.getDirectStatistics().getMaxResponseTime(); } public Long getMinResponseTime() { return totalStats.getDirectStatistics().getMinResponseTime(); } public Double getAvgResponseTimeWithCache() { return totalStats.getCacheStatistics().getAvgResponseTime(); } public Long getMaxResponseTimeWithCache() { return totalStats.getCacheStatistics().getMaxResponseTime(); } public Long getMinResponseTimeWithCache() { return totalStats.getCacheStatistics().getMinResponseTime(); } public double getAvgNestedCalls() { return totalStats.getDirectStatistics().getAvgNestedCalls(); } public double getAvgNestedCallsWithCache() { return totalStats.getCacheStatistics().getAvgNestedCalls(); } public int compareTo(IService otherService) { int groupCompare = ObjectUtils.compare(group, otherService.getGroup()); if (groupCompare != 0) { return groupCompare; } return ObjectUtils.compare(name, otherService.getName()); } public double getCurrentRate() { updateWindows(); return (windowPrevisiousStats.getTotalHits() * 1000) / (double) windowSize; } }