package com.hubspot.blazar.data.service;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import com.google.common.collect.ImmutableMap;
import com.google.inject.Inject;
import com.hubspot.blazar.base.InterProjectBuild;
import com.hubspot.blazar.base.ModuleBuild;
import com.hubspot.blazar.base.RepositoryBuild;
import com.hubspot.blazar.base.metrics.ActiveBranchBuildsInState;
import com.hubspot.blazar.base.metrics.ActiveInterProjectBuildsInState;
import com.hubspot.blazar.base.metrics.ActiveModuleBuildsInState;
import com.hubspot.blazar.data.dao.MetricsDao;
import com.hubspot.blazar.data.dao.QueueItemDao;
import com.hubspot.blazar.data.queue.QueueItem;
public class MetricsService {
private static final long BUILD_PROBABLY_HUNG_AGE_MILLIS = TimeUnit.MINUTES.toMillis(30);
private MetricsDao dao;
private QueueItemDao queueItemDao;
@Inject
public MetricsService(MetricsDao dao, QueueItemDao queueItemDao) {
this.dao = dao;
this.queueItemDao = queueItemDao;
}
/**
* This method is not expensive per-se but if you want a single-state or will call this method many times in a
* single second you should use {@Link CachingMetricsService#getCachedActiveModuleBuildCountByState(state)}
* @return Collection of build states to counts of builds in that state
*/
public Map<ModuleBuild.State, Integer> countActiveModuleBuildsByState() {
Set<ActiveModuleBuildsInState> pairs = dao.countActiveModuleBuildsByState();
ImmutableMap.Builder<ModuleBuild.State, Integer> mapBuilder = ImmutableMap.builder();
for (ActiveModuleBuildsInState pair : pairs) {
mapBuilder.put(pair.getState(), pair.getCount());
}
return mapBuilder.build();
}
/**
* This method is not expensive per-se but if you want a single-state or will call this method many times in a
* single second you should use {@Link CachingMetricsService#getCachedActiveBranchBuildCountByState(state)}
* @return Collection of build states to counts of builds in that state
*/
public Map<RepositoryBuild.State, Integer> countActiveBranchBuildsByState() {
Set<ActiveBranchBuildsInState> pairs = dao.countActiveBranchBuildsByState();
ImmutableMap.Builder<RepositoryBuild.State, Integer> mapBuilder = ImmutableMap.builder();
for (ActiveBranchBuildsInState pair : pairs) {
mapBuilder.put(pair.getState(), pair.getCount());
}
return mapBuilder.build();
}
/**
* This method is not expensive per-se but if you want a single-state or will call this method many times in a
* single second you should use {@Link CachingMetricsService#getCachedActiveInterProjectBuildCountByState(state)}
* @return Collection of build states to counts of builds in that state
*/
public Map<InterProjectBuild.State, Integer> countActiveInterProjectBuildsByState() {
Set<ActiveInterProjectBuildsInState> pairs = dao.countActiveInterProjectBuildsByState();
ImmutableMap.Builder<InterProjectBuild.State, Integer> mapBuilder = ImmutableMap.builder();
for(ActiveInterProjectBuildsInState pair : pairs) {
mapBuilder.put(pair.getState(), pair.getCount());
}
return mapBuilder.build();
}
/**
* This method is not expensive per-se but if you want a single-state or will call this method many times in a
* single second you should use {@Link CachingMetricsService#checkAndUpdateQueuedItemCountMap(state)}
* @return Collection of events to counts of unprocessed events in that state
*/
public Map<Class<?>, Integer> countQueuedEventsByType() {
Map<Class<?>, Integer> countMap = new HashMap<>();
Set<QueueItem> items = queueItemDao.getItemsReadyToExecute();
for (QueueItem item : items) {
if (countMap.containsKey(item.getType())) {
countMap.put(item.getType(), countMap.get(item.getType()) + 1);
} else {
countMap.put(item.getType(), 1);
}
}
return ImmutableMap.copyOf(countMap);
}
/**
* @return A set of strings describing the builds that are probably hung.
*/
public Set<RepositoryBuild> getHungRepoBuilds() {
return dao.getBuildsRunningForLongerThan(System.currentTimeMillis(), BUILD_PROBABLY_HUNG_AGE_MILLIS);
}
}