001/*
002 *  Copyright 2013 Anyware Services
003 *
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016
017package org.ametys.web.cache.monitoring.process;
018
019import java.util.Calendar;
020import java.util.GregorianCalendar;
021import java.util.Timer;
022import java.util.TimerTask;
023
024import org.apache.avalon.framework.activity.Disposable;
025import org.apache.avalon.framework.activity.Initializable;
026import org.apache.avalon.framework.logger.LogEnabled;
027import org.apache.avalon.framework.logger.Logger;
028import org.apache.avalon.framework.service.ServiceException;
029import org.apache.avalon.framework.service.ServiceManager;
030import org.apache.avalon.framework.service.Serviceable;
031
032import org.ametys.core.util.DateUtils;
033import org.ametys.runtime.config.Config;
034import org.ametys.web.cache.monitoring.process.access.ResourceAccessComponent;
035import org.ametys.web.cache.monitoring.process.statistics.ResourceStatisticsComponent;
036
037/**
038 * This scheduler launches ResourceAccessMonitor and CacheMonitoringUpdater every hour at 15.
039 */
040public class CacheMonitoringScheduler extends TimerTask implements Initializable, Serviceable, Disposable, LogEnabled
041{
042    /** Logger */
043    protected Logger _logger;
044
045    /** Timer. */
046    protected Timer _timer;
047
048    /** Resource Access Monitor */
049    protected ResourceAccessComponent _resourceAccessMonitor;
050
051    /** Cache stats updater */
052    protected ResourceStatisticsComponent _cacheStatsUpdater;
053
054    @Override
055    public void service(ServiceManager manager) throws ServiceException
056    {
057        _cacheStatsUpdater = (ResourceStatisticsComponent) manager.lookup(ResourceStatisticsComponent.ROLE);
058        _resourceAccessMonitor = (ResourceAccessComponent) manager.lookup(ResourceAccessComponent.ROLE);
059    }
060
061    @Override
062    public void enableLogging(Logger logger)
063    {
064        _logger = logger;
065    }
066
067    @Override
068    public void initialize() throws Exception
069    {
070        // Daemon thread
071        _timer = new Timer("CacheMonitoringScheduler", true);
072
073        // The task is each hour, starting at h15m if not too late.
074        // It is a quarter after the execution of the task of the FrontCacheMonitoringScheduler
075        GregorianCalendar calendar = new GregorianCalendar();
076        int minute = calendar.get(Calendar.MINUTE);
077
078        // If 3h10, will starts at 3h15.
079        // If 3h11, will starts at 4h15
080        if (minute > 10)
081        {
082            calendar.add(Calendar.HOUR_OF_DAY, 1);
083        }
084        
085        calendar.set(Calendar.MINUTE, 15);
086        calendar.set(Calendar.SECOND, 0);
087        calendar.set(Calendar.MILLISECOND, 0);
088
089        _timer.scheduleAtFixedRate(this, calendar.getTime(), 60 * 60 * 1000);
090
091        if (_logger.isInfoEnabled())
092        {
093            _logger.info("Cache monitoring scheduler : The process will run each hour, starting " + calendar.getTime());
094        }
095    }
096
097    @Override
098    public void dispose()
099    {
100        cancel();
101        _timer.cancel();
102        _logger = null;
103    }
104
105    @Override
106    public void run()
107    {
108        boolean enabled = Config.getInstance().getValue("cache.monitoring.schedulers.enable");
109        if (!enabled)
110        {
111            return;
112        }
113
114        if (_logger.isInfoEnabled())
115        {
116            _logger.info("Starting the cache statistics process");
117        }
118
119        // Export pending records
120        try
121        {
122            long start = System.currentTimeMillis();
123            _resourceAccessMonitor.exportPendings();
124            long endExport = System.currentTimeMillis();
125    
126            // Then update stats.
127            _cacheStatsUpdater.updateStatistics();
128            long endUpdate = System.currentTimeMillis();
129    
130            // And purge processed raw data
131            _cacheStatsUpdater.purgeRawData();
132    
133            if (_logger.isInfoEnabled())
134            {
135                long end = System.currentTimeMillis();
136    
137                String totalDuration = DateUtils.formatDuration(end - start);
138                String exportDuration = DateUtils.formatDuration(endExport - start);
139                String updateDuration = DateUtils.formatDuration(endUpdate - endExport);
140                String purgeDuration = DateUtils.formatDuration(end - endUpdate);
141    
142                _logger.info(String.format("The whole cache statistics process took %s [export raw data to db : %s, update cache statistics: %s, purge processed data: %s]",
143                        totalDuration, exportDuration, updateDuration, purgeDuration));
144            }
145        }
146        catch (Throwable t)
147        {
148            _logger.error("Unexpected error while during the execution of the cache monitoring process.", t);
149        }
150    }
151}