From: <sc...@hy...> - 2009-04-02 00:24:00
|
Author: scottmf Date: 2009-04-01 17:23:45 -0700 (Wed, 01 Apr 2009) New Revision: 12918 URL: http://svn.hyperic.org/?view=rev&root=Hyperic+HQ&revision=12918 Removed: branches/HQ_4_1/src/org/hyperic/hq/measurement/server/mbean/DataPurgeService.java Modified: branches/HQ_4_1/installer/data/db-upgrade.xml branches/HQ_4_1/src/org/hyperic/hq/application/HQApp.java branches/HQ_4_1/src/org/hyperic/hq/application/Scheduler.java branches/HQ_4_1/src/org/hyperic/hq/ha/server/mbean/HAService.java branches/HQ_4_1/src/org/hyperic/hq/ha/server/session/HAStartupListener.java branches/HQ_4_1/src/org/hyperic/hq/measurement/DataPurgeJob.java branches/HQ_4_1/src/org/hyperic/hq/measurement/server/session/MeasurementStartupListener.java Log: [HHQ-3005] removed quartz scheduling for DB Maintenance tasks in favor of org.hyperic.hq.application.Scheduler backed by java.util.concurrent.ScheduledThreadPoolExecutor. Added max thread pool size to 10 since we keep adding more tasks to this scheduler. Added startup methods to MeasurementStartupListener to start the DataPurgeJob Worker. Modified: branches/HQ_4_1/installer/data/db-upgrade.xml =================================================================== --- branches/HQ_4_1/installer/data/db-upgrade.xml 2009-04-02 00:13:42 UTC (rev 12917) +++ branches/HQ_4_1/installer/data/db-upgrade.xml 2009-04-02 00:23:45 UTC (rev 12918) @@ -9722,6 +9722,20 @@ </schema-directSQL> </schemaSpec> + <schemaSpec version="3.142"> + <schema-directSQL> + <statement> + delete from QRTZ_CRON_TRIGGERS where TRIGGER_NAME = 'Data Purge Trigger' + </statement> + <statement> + delete from QRTZ_JOB_DETAILS where JOB_NAME = 'Data Purge Job' + </statement> + <statement> + delete from QRTZ_TRIGGERS where TRIGGER_NAME = 'Data Purge Trigger' + </statement> + </schema-directSQL> + </schemaSpec> + </dbupgrade> </target> </project> Modified: branches/HQ_4_1/src/org/hyperic/hq/application/HQApp.java =================================================================== --- branches/HQ_4_1/src/org/hyperic/hq/application/HQApp.java 2009-04-02 00:13:42 UTC (rev 12917) +++ branches/HQ_4_1/src/org/hyperic/hq/application/HQApp.java 2009-04-02 00:23:45 UTC (rev 12918) @@ -105,7 +105,7 @@ _watchdog = new ThreadWatchdog("ThreadWatchdog"); _watchdog.initialize(); - _scheduler = new Scheduler(4); + _scheduler = new Scheduler(10); this.registerCallbackListener(ShutdownCallback.class, _scheduler); try { Modified: branches/HQ_4_1/src/org/hyperic/hq/application/Scheduler.java =================================================================== --- branches/HQ_4_1/src/org/hyperic/hq/application/Scheduler.java 2009-04-02 00:13:42 UTC (rev 12917) +++ branches/HQ_4_1/src/org/hyperic/hq/application/Scheduler.java 2009-04-02 00:23:45 UTC (rev 12918) @@ -115,6 +115,20 @@ public ScheduledFuture scheduleWithFixedDelay(Runnable task, long initialDelay, long delay) { return _executor.scheduleWithFixedDelay(task, initialDelay, delay, TimeUnit.MILLISECONDS); } + + /** + * Tries to remove from the work queue all {@link Future} + * tasks that have been cancelled. This method can be useful as a + * storage reclamation operation, that has no other impact on + * functionality. Cancelled tasks are never executed, but may + * accumulate in work queues until worker threads can actively + * remove them. Invoking this method instead tries to remove them now. + * However, this method may fail to remove tasks in + * the presence of interference by other threads. + */ + public void purgeTasks() { + _executor.purge(); + } /** * Shut down the scheduler in an orderly manner, allowing any currently Modified: branches/HQ_4_1/src/org/hyperic/hq/ha/server/mbean/HAService.java =================================================================== --- branches/HQ_4_1/src/org/hyperic/hq/ha/server/mbean/HAService.java 2009-04-02 00:13:42 UTC (rev 12917) +++ branches/HQ_4_1/src/org/hyperic/hq/ha/server/mbean/HAService.java 2009-04-02 00:23:45 UTC (rev 12918) @@ -55,7 +55,6 @@ _log.info("Starting HA Services"); - startDataPurgeService(server); startAvailCheckService(server); startAgentAIScanService(server); } @@ -67,15 +66,6 @@ // XXX: shut down services } - private void startDataPurgeService(MBeanServer server) { - try { - invoke(server, "hyperic.jmx:type=Service,name=DataPurge", - "startPurgeService"); - } catch (Exception e) { - _log.info("Unable to start service: " + e); - } - } - private void startAvailCheckService(MBeanServer server) { try { invoke(server, "hyperic.jmx:service=Scheduler,name=AvailabilityCheck", Modified: branches/HQ_4_1/src/org/hyperic/hq/ha/server/session/HAStartupListener.java =================================================================== --- branches/HQ_4_1/src/org/hyperic/hq/ha/server/session/HAStartupListener.java 2009-04-02 00:13:42 UTC (rev 12917) +++ branches/HQ_4_1/src/org/hyperic/hq/ha/server/session/HAStartupListener.java 2009-04-02 00:23:45 UTC (rev 12918) @@ -25,16 +25,17 @@ package org.hyperic.hq.ha.server.session; +import javax.management.MBeanServer; +import javax.management.ObjectName; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.hyperic.hq.application.StartupListener; import org.hyperic.hq.common.server.mbean.ProductConfigService; import org.hyperic.hq.ha.server.mbean.HAService; +import org.hyperic.hq.measurement.server.session.MeasurementStartupListener; import org.hyperic.hq.product.server.MBeanUtil; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import javax.management.MBeanServer; -import javax.management.ObjectName; - public class HAStartupListener implements StartupListener { @@ -48,6 +49,7 @@ startConfigService(server); startScheduler(server); startHAService(server); + MeasurementStartupListener.startDataPurgeWorker(); } private void startHAService(MBeanServer server) Modified: branches/HQ_4_1/src/org/hyperic/hq/measurement/DataPurgeJob.java =================================================================== --- branches/HQ_4_1/src/org/hyperic/hq/measurement/DataPurgeJob.java 2009-04-02 00:13:42 UTC (rev 12917) +++ branches/HQ_4_1/src/org/hyperic/hq/measurement/DataPurgeJob.java 2009-04-02 00:23:45 UTC (rev 12918) @@ -35,21 +35,19 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.hyperic.hq.common.SystemException; +import org.hyperic.hq.common.server.session.ServerConfigManagerEJBImpl; import org.hyperic.hq.common.shared.HQConstants; import org.hyperic.hq.common.shared.ServerConfigManagerLocal; import org.hyperic.hq.common.shared.ServerConfigManagerUtil; import org.hyperic.hq.events.shared.EventLogManagerLocal; import org.hyperic.hq.events.shared.EventLogManagerUtil; import org.hyperic.hq.measurement.shared.DataCompressLocal; -import org.hyperic.hq.measurement.shared.DataCompressUtil; +import org.hyperic.hq.measurement.server.session.DataCompressEJBImpl; import org.hyperic.hq.measurement.server.session.MeasurementManagerEJBImpl; import org.hyperic.util.TimeUtil; import org.hyperic.util.stats.ConcurrentStatsCollector; -import org.quartz.Job; -import org.quartz.JobExecutionContext; -import org.quartz.JobExecutionException; -public class DataPurgeJob implements Job { +public class DataPurgeJob implements Runnable { private static final Log _log = LogFactory.getLog(DataPurgeJob.class); @@ -68,35 +66,24 @@ private static boolean compressRunning = false; } - /** - * Public interface for quartz - */ - public void execute(JobExecutionContext context) - throws JobExecutionException { - + public synchronized void run() { try { - DataPurgeJob.compressData(); - - Properties conf; + compressData(); + Properties conf = null; try { - conf = - ServerConfigManagerUtil.getLocalHome().create().getConfig(); + conf = ServerConfigManagerEJBImpl.getOne().getConfig(); } catch (Exception e) { throw new SystemException(e); } - - long now = System.currentTimeMillis(); - + final long now = System.currentTimeMillis(); // need to do this because of the Sun JVM bug // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5102804 Introspector.flushCaches(); - purge(conf, now); - } catch (CreateException e) { - throw new JobExecutionException( - "Unable to create instance of DataManager.", e, false); - } catch (NamingException e) { - throw new JobExecutionException( - "Unable to look up DataManager.", e, false); + if (conf != null) { + purge(conf, now); + } + } catch (Throwable e) { + _log.error(e.getMessage(), e); } } @@ -106,11 +93,10 @@ public static void compressData() throws CreateException, NamingException { - ServerConfigManagerLocal serverConfig = - ServerConfigManagerUtil.getLocalHome().create(); + final ServerConfigManagerLocal serverConfig = + ServerConfigManagerEJBImpl.getOne(); - DataCompressLocal dataCompress = - DataCompressUtil.getLocalHome().create(); + final DataCompressLocal dataCompress = DataCompressEJBImpl.getOne(); // First check if we are already running synchronized (DataPurgeLockHolder.COMPRESS_RUNNING_LOCK) { Deleted: branches/HQ_4_1/src/org/hyperic/hq/measurement/server/mbean/DataPurgeService.java =================================================================== --- branches/HQ_4_1/src/org/hyperic/hq/measurement/server/mbean/DataPurgeService.java 2009-04-02 00:13:42 UTC (rev 12917) +++ branches/HQ_4_1/src/org/hyperic/hq/measurement/server/mbean/DataPurgeService.java 2009-04-02 00:23:45 UTC (rev 12918) @@ -1,147 +0,0 @@ -/* - * NOTE: This copyright does *not* cover user programs that use HQ - * program services by normal system calls through the application - * program interfaces provided as part of the Hyperic Plug-in Development - * Kit or the Hyperic Client Development Kit - this is merely considered - * normal use of the program, and does *not* fall under the heading of - * "derived work". - * - * Copyright (C) [2004, 2005, 2006], Hyperic, Inc. - * This file is part of HQ. - * - * HQ is free software; you can redistribute it and/or modify - * it under the terms version 2 of the GNU General Public License as - * published by the Free Software Foundation. This program is distributed - * in the hope that it will be useful, but WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR A - * PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - */ - -package org.hyperic.hq.measurement.server.mbean; - -import java.util.Date; - -import org.hyperic.hq.bizapp.server.action.email.EmailFilter; -import org.hyperic.hq.common.shared.ProductProperties; -import org.hyperic.hq.scheduler.shared.SchedulerLocal; -import org.hyperic.hq.scheduler.shared.SchedulerUtil; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.quartz.CronTrigger; -import org.quartz.JobDetail; - -/** - * Data purge service that handles the simple task of registering the class - * that purges old measurement data. This is a one time event, we just - * pull the config and register the job with quartz. - * - * @jmx:mbean name="hyperic.jmx:type=Service,name=DataPurge" - */ -public class DataPurgeService - implements DataPurgeServiceMBean -{ - private static final String JOB = "Data Purge Job"; - private static final String TRIGGER = "Data Purge Trigger"; - private static final String GROUP = "Data Purge Group"; - - protected Log log = LogFactory.getLog(DataPurgeService.class.getName()); - - /* Every hour at 10 after */ - private String schedule = "0 10 0-23 * * ?"; - - public DataPurgeService() {} - - /** - * @jmx:managed-operation - */ - public void stop() {} - - /** - * @jmx:managed-operation - */ - public void start() {} - - /** - * @jmx:managed-operation - */ - public void startPurgeService() { - - Class jobClass; - String jobName = ProductProperties.getProperty("hyperic.hq.dataPurge"); - try { - jobClass = Class.forName(jobName); - } catch (Exception e) { - log.error("Unable to load HQ Data Manager class=" + jobName, e); - return; - } - - log.info("Starting HQ Data Manager Service using " + jobName); - - try { - // Get a reference to the scheduler - SchedulerLocal scheduler = SchedulerUtil.getLocalHome().create(); - - // Unschedule previous job - if (scheduler.getTrigger(TRIGGER, GROUP) != null) { - scheduler.unscheduleJob(TRIGGER, GROUP); - } - - JobDetail job = new JobDetail(JOB, GROUP, jobClass); - - // See CronTrigger javadoc for more info - CronTrigger trigger = new CronTrigger(TRIGGER, GROUP, JOB, - GROUP, new Date(), - null, this.getSchedule()); - trigger.setMisfireInstruction(CronTrigger. - MISFIRE_INSTRUCTION_DO_NOTHING); - - scheduler.scheduleJob(job, trigger); - - // Clear out all EmailFilter jobs - synchronized (EmailFilter.SCHEDULER_LOCK) { - String[] triggersInGroup = - scheduler.getTriggerNames(EmailFilter.JOB_GROUP); - int numDeleted = 0; - for (int i = 0; i < triggersInGroup.length; ++i) { - if (scheduler.unscheduleJob(triggersInGroup[i], - EmailFilter.JOB_GROUP)) { - ++numDeleted; - } - } - } - } catch (Exception e) { - // This probably isnt fatal. - this.log.error("Unable to start HQ Data Manager Service", e); - } - } - - /** - * @jmx:managed-operation - */ - public void init() {} - - /** - * @jmx:managed-operation - */ - public void destroy() {} - - /** - * @jmx:managed-attribute - */ - public String getSchedule() { - return schedule; - } - /** - * @jmx:managed-attribute - */ - public void setSchedule(String schedule) { - this.schedule = schedule; - } -} Modified: branches/HQ_4_1/src/org/hyperic/hq/measurement/server/session/MeasurementStartupListener.java =================================================================== --- branches/HQ_4_1/src/org/hyperic/hq/measurement/server/session/MeasurementStartupListener.java 2009-04-02 00:13:42 UTC (rev 12917) +++ branches/HQ_4_1/src/org/hyperic/hq/measurement/server/session/MeasurementStartupListener.java 2009-04-02 00:23:45 UTC (rev 12918) @@ -25,17 +25,12 @@ package org.hyperic.hq.measurement.server.session; +import java.util.Calendar; import java.util.Collection; import java.util.HashSet; -import java.util.Iterator; -import java.util.List; import java.util.Properties; import java.util.Set; -import net.sf.ehcache.Cache; -import net.sf.ehcache.CacheManager; -import net.sf.ehcache.Element; - import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.hyperic.hq.appdef.server.session.ResourceCreatedZevent; @@ -47,17 +42,19 @@ import org.hyperic.hq.authz.server.session.ResourceDeleteCallback; import org.hyperic.hq.common.VetoException; import org.hyperic.hq.common.server.session.ServerConfigManagerEJBImpl; +import org.hyperic.hq.measurement.MeasurementConstants; import org.hyperic.hq.measurement.galerts.MetricAuxLogProvider; import org.hyperic.hq.measurement.shared.MeasurementManagerLocal; -import org.hyperic.hq.measurement.shared.TemplateManagerLocal; import org.hyperic.hq.zevents.ZeventManager; +import edu.emory.mathcs.backport.java.util.concurrent.ScheduledFuture; + public class MeasurementStartupListener implements StartupListener { private static final String PROP_REPSTATS_SIZE = "REPORT_STATS_SIZE"; - private final Log _log = + private static final Log _log = LogFactory.getLog(MeasurementStartupListener.class); private static final Object LOCK = new Object(); @@ -65,6 +62,7 @@ private static DataInserter _availDataInserter; private static DefaultMetricEnableCallback _defEnableCallback; private static MetricDeleteCallback _delCallback; + private static ScheduledFuture _dataPurgeFuture; public void hqStarted() { // Make sure we have the aux-log provider loaded @@ -128,8 +126,62 @@ prefetchEnabledMeasurementsAndTemplates(); initReportsStats(); AgentScheduleSynchronizer.getInstance().initialize(); + startDataPurgeWorker(); } + + public static void stopDataPurgeWorker() { + if (_dataPurgeFuture != null) { + _log.info("Stopping Data Purge Worker"); + _dataPurgeFuture.cancel(true); + HQApp.getInstance().getScheduler().purgeTasks(); + _dataPurgeFuture = null; + } + } + /** + * Starts either the com.hyperic.hq.measurement.DataPurgeJob or + * org.hyperic.hq.measurement.DataPurgeJob after stopping an existing + * worker if one is already scheduled. The worker is scheduled to run + * at 10 past every hour. + */ + public static void startDataPurgeWorker() { + stopDataPurgeWorker(); + // want to schedule at 10 past the hour for legacy, nice to know + // when all of our DB maintenance occurs. + final Calendar cal = Calendar.getInstance(); + cal.setTimeInMillis(now()); + if (cal.get(Calendar.MINUTE) >= 10) { + cal.add(Calendar.HOUR_OF_DAY, 1); + } + cal.set(Calendar.MINUTE, 10); + cal.set(Calendar.SECOND, 0); + cal.set(Calendar.MILLISECOND, 0); + final long initialDelay = cal.getTimeInMillis() - now(); + _log.info("Starting Data Purge Worker"); + Runnable dataPurgeJob; + try { + final String klazz = "com.hyperic.hq.measurement.DataPurgeJob"; + dataPurgeJob = (Runnable)Class.forName(klazz).newInstance(); + _log.info("Started DataPurgeWorker as " + klazz); + } catch (Exception e) { + try { + final String klazz = "org.hyperic.hq.measurement.DataPurgeJob"; + dataPurgeJob = (Runnable)Class.forName(klazz).newInstance(); + _log.info("Started DataPurgeWorker as " + klazz); + } catch (Exception e1) { + _log.fatal("Could not start DataPurgeWorker", e1); + return; + } + } + final HQApp app = HQApp.getInstance(); + _dataPurgeFuture = app.getScheduler().scheduleAtFixedRate( + dataPurgeJob, initialDelay, MeasurementConstants.HOUR); + } + + private static final long now() { + return System.currentTimeMillis(); + } + private void prefetchEnabledMeasurementsAndTemplates() { MeasurementManagerLocal mMan = MeasurementManagerEJBImpl.getOne(); mMan.findAllEnabledMeasurementsAndTemplates(); |