Package org.mule.management.stats

Source Code of org.mule.management.stats.ProcessingTime

/*
* $Id: ProcessingTime.java 21939 2011-05-18 13:32:09Z aperepel $
* --------------------------------------------------------------------------------------
* Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
*
* The software in this package is published under the terms of the CPAL v1.0
* license, a copy of which has been included with this distribution in the
* LICENSE.txt file.
*/

package org.mule.management.stats;

import org.mule.api.MuleContext;
import org.mule.api.MuleSession;
import org.mule.api.construct.FlowConstruct;
import org.mule.util.concurrent.ThreadNameHelper;

import java.io.Serializable;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
* Accumulates the processing time for all branches of a flow
*/
public class ProcessingTime implements Serializable
{
    /**
     * Serial version
     */
    private static final long serialVersionUID = 1L;

    private static final Log logger = LogFactory.getLog(ProcessingTime.class);
    private static volatile Thread referenceThread;
    private static ReferenceQueue<ProcessingTime> queue = new ReferenceQueue<ProcessingTime>();
    private static Map refs = new ConcurrentHashMap();

    private AtomicLong accumulator = new AtomicLong();
    private FlowConstructStatistics statistics;
    private String threadName;

    /**
     * Create a ProcessingTime for the specified MuleSession.
     * @return ProcessingTime if the session has an enabled FlowConstructStatistics or null otherwise
     */
    public static ProcessingTime newInstance(MuleSession session, MuleContext muleContext)
    {
        if (session != null)
        {
            FlowConstruct fc = session.getFlowConstruct();
            if (fc != null)
            {
                FlowConstructStatistics stats = fc.getStatistics();
                if (stats != null && fc.getStatistics().isEnabled())
                {
                    return new ProcessingTime(stats, muleContext);
                }
            }

        }

        return null;
    }

    /**
     * Create a Processing Time
     * @param stats never null
     * @param muleContext
     */
    private ProcessingTime(FlowConstructStatistics stats, MuleContext muleContext)
    {
        this.statistics = stats;
        this.threadName = String.format("%sprocessing.time.monitor", ThreadNameHelper.getPrefix(muleContext));
        if (referenceThread == null)
        {
            startThread();
        }
        refs.put(new Reference(this), refs);
    }

    /**
     * Add the execution time for this branch to the flow construct's statistics
     * @param startTime  time this branch started
     */
    public void addFlowExecutionBranchTime(long startTime)
    {
        if (statistics.isEnabled())
        {
            long elapsedTime = getEffectiveTime(System.currentTimeMillis() - startTime);
            statistics.addFlowExecutionBranchTime(elapsedTime, accumulator.addAndGet(elapsedTime));
        }
    }

    /**
     * Convert processing time to effective processing time.  If processing took less than a tick, we consider
     * it to have been one millisecond
     */
    public static long getEffectiveTime(long time)
    {
        return (time <= 0) ? 1L : time;
    }

    /**
     * Start timer that processes reference queue
     */
    public void startThread()
    {
        synchronized (ProcessingTime.class)
        {
            if (referenceThread == null)
            {
                referenceThread = new Thread(new Runnable()
                {
                    /**
                     * As weak references to completed ProcessingTimes are delivered, record them
                     */
                    public void run()
                    {

                        try
                        {
                            while (true)
                            {
                                if (Thread.currentThread() != referenceThread)
                                {
                                    break;
                                }
                                try
                                {
                                    // The next two lines look silly, but
                                    //       ref = (Reference) queue.poll();
                                    // fails on the IBM 1.5 compiler
                                    Object temp = queue.remove();
                                    Reference ref = (Reference) temp;
                                    refs.remove(ref);
                                    FlowConstructStatistics stats = ref.getStatistics();
                                    if (stats.isEnabled())
                                    {
                                        stats.addCompleteFlowExecutionTime(ref.getAccumulator().longValue());
                                    }
                                }
                                catch (InterruptedException ex )
                                {
                                    Thread.currentThread().interrupt();
                                    break;
                                }
                                catch (Exception ex)
                                {
                                    // Don't let exception escape -- it kills the thread
                                    logger.error(this, ex);
                                }
                            }
                        }
                        finally
                        {
                            referenceThread = null;
                        }
                    }
                }, this.threadName);
                referenceThread.setDaemon(true);
                referenceThread.start();
            }
        }
    }

    /**
     * Stop timer that processes reference queue
     */
    public synchronized static void stopTimer()
    {
        if (referenceThread != null)
        {
            referenceThread.interrupt();
            referenceThread = null;
        }
        refs.clear();
    }

    /**
     * Weak reference that includes flow statistics to be updated
     */
    static class Reference extends WeakReference<ProcessingTime>
    {
        private FlowConstructStatistics statistics;
        private AtomicLong accumulator;

        Reference(ProcessingTime time)
        {
            super(time, queue);
            this.statistics = time.statistics;
            this.accumulator = time.accumulator;
        }

        public AtomicLong getAccumulator()
        {
            return accumulator;
        }

        public FlowConstructStatistics getStatistics()
        {
            return statistics;
        }
    }
}
TOP

Related Classes of org.mule.management.stats.ProcessingTime

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.