
com.github.endoscope.core.CurrentStats Maven / Gradle / Ivy
The newest version!
package com.github.endoscope.core;
import java.util.Date;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.function.Function;
import com.github.endoscope.properties.Properties;
import org.slf4j.Logger;
import static org.slf4j.LoggerFactory.getLogger;
/**
* This class contains current Stats and queue of Contexts awaiting to be added to current stats.
* It is responsible for separation of quick synchronous operations from longer asynchronous operations.
*
* All operations on this class must be thread safe.
*
* Storing Contexts in queue must be thread safe and as fast as possible.
* This is critical requirement as otherwise it could affect monitored application performance.
*
* Operations on stats also needs to be thread safe as we don't know who runs #lockReadStats method.
* All stats operations might take a lot of time: save, processing and updates (in case of complex stats).
* Because of that we need different thread that will move data from queue to stats.
*/
public class CurrentStats {
private static final Logger log = getLogger(CurrentStats.class);
private Stats stats;
private LinkedBlockingDeque queue;
public CurrentStats() {
stats = createEmptyStats();
queue = new LinkedBlockingDeque<>(Properties.getMaxQueueSize());
}
private Stats createEmptyStats() {
Stats stats = new Stats(Properties.getAggregateSubCalls());
stats.setStartDate(new Date());
return stats;
}
public void add(Context context){
try{
queue.addLast(context);
}catch(IllegalStateException e){//eg. due to exhausted queue size
//don't sync here - that could block application
stats.threadSafeIncrementLost();
}
}
public T lockReadStats(Function function){
synchronized(stats){
return function.apply(stats);
}
}
public int getQueueSize(){
return queue.size();
}
void processAllFromQueue(){
Context ctx = queue.pollFirst();
synchronized(stats){
while(ctx != null){
stats.store(ctx);
ctx = queue.pollFirst();
}
}
}
public void setFatalError(String message){
stats.setFatalError(message);//assignment is thread safe
}
/**
* Creates new empty stats and returns old one.
* @return old stats
*/
public Stats resetStats(){
Stats old = stats;
stats = createEmptyStats();
return old;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy