All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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