[jboss-svn-commits] JBL Code SVN: r14574 - in labs/shotoku/trunk/shotoku-cache: cache-admin/src/java/org/jboss/shotoku/cache/admin and 10 other directories.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Sun Aug 26 05:08:09 EDT 2007
Author: adamw
Date: 2007-08-26 05:08:09 -0400 (Sun, 26 Aug 2007)
New Revision: 14574
Added:
labs/shotoku/trunk/shotoku-cache/TODO
labs/shotoku/trunk/shotoku-cache/cache-admin/src/java/org/jboss/shotoku/cache/admin/MonitorBean.java
labs/shotoku/trunk/shotoku-cache/cache-base/src/java/org/jboss/shotoku/cache/RenewableCacheItemOperations.java
labs/shotoku/trunk/shotoku-cache/cache-base/src/java/org/jboss/shotoku/cache/service/monitor/
labs/shotoku/trunk/shotoku-cache/cache-base/src/java/org/jboss/shotoku/cache/service/monitor/CacheAlert.java
labs/shotoku/trunk/shotoku-cache/cache-base/src/java/org/jboss/shotoku/cache/service/monitor/CacheAlertFactory.java
labs/shotoku/trunk/shotoku-cache/cache-base/src/java/org/jboss/shotoku/cache/service/monitor/CacheAlertImpl.java
labs/shotoku/trunk/shotoku-cache/cache-base/src/java/org/jboss/shotoku/cache/service/monitor/DummyRenewableCacheMonitorService.java
labs/shotoku/trunk/shotoku-cache/cache-base/src/java/org/jboss/shotoku/cache/service/monitor/RenewableCacheMonitorServiceMBean.java
labs/shotoku/trunk/shotoku-cache/cache-service/src/java/org/jboss/shotoku/cache/service/monitor/
labs/shotoku/trunk/shotoku-cache/cache-service/src/java/org/jboss/shotoku/cache/service/monitor/RenewableCacheMonitorService.java
Removed:
labs/shotoku/trunk/shotoku-cache/cache-base/src/java/org/jboss/shotoku/cache/RenewableCacheItemData.java
Modified:
labs/shotoku/trunk/shotoku-cache/cache-admin/src/java/org/jboss/shotoku/cache/admin/AdminBean.java
labs/shotoku/trunk/shotoku-cache/cache-admin/src/java/org/jboss/shotoku/cache/admin/CacheItemBean.java
labs/shotoku/trunk/shotoku-cache/cache-admin/src/web/WEB-INF/faces-config.xml
labs/shotoku/trunk/shotoku-cache/cache-admin/src/web/pages/admin.jsp
labs/shotoku/trunk/shotoku-cache/cache-base/src/java/org/jboss/shotoku/cache/RenewableCacheItem.java
labs/shotoku/trunk/shotoku-cache/cache-base/src/java/org/jboss/shotoku/cache/SignalExitUpdateThreadData.java
labs/shotoku/trunk/shotoku-cache/cache-base/src/java/org/jboss/shotoku/cache/UpdateThread.java
labs/shotoku/trunk/shotoku-cache/cache-base/src/java/org/jboss/shotoku/cache/UpdateThreadData.java
labs/shotoku/trunk/shotoku-cache/cache-base/src/java/org/jboss/shotoku/cache/service/DummyRenewableCacheService.java
labs/shotoku/trunk/shotoku-cache/cache-base/src/java/org/jboss/shotoku/cache/service/RenewableCacheServiceMBean.java
labs/shotoku/trunk/shotoku-cache/cache-base/src/java/org/jboss/shotoku/tools/CacheTools.java
labs/shotoku/trunk/shotoku-cache/cache-service/src/etc/META-INF/jboss-service.xml
labs/shotoku/trunk/shotoku-cache/cache-service/src/java/org/jboss/shotoku/cache/service/RenewableCacheService.java
labs/shotoku/trunk/shotoku-cache/cache-test/src/java/org/jboss/shotoku/cache/test/TestServlet.java
Log:
Admin and monitoring
Added: labs/shotoku/trunk/shotoku-cache/TODO
===================================================================
--- labs/shotoku/trunk/shotoku-cache/TODO (rev 0)
+++ labs/shotoku/trunk/shotoku-cache/TODO 2007-08-26 09:08:09 UTC (rev 14574)
@@ -0,0 +1,8 @@
+* toggle panel
+* investigate multiple ProjectConfigurationWatcher-s
+* refreshing of keys after a key reset
+* refreshing cachitem_info after alerts reset
+* e-mail notifications of alerts
+* check form-sending for cache item configuration
+* migrate AdministratedServices
+* service unavailability when stopped; null get() when CI unregistered
Modified: labs/shotoku/trunk/shotoku-cache/cache-admin/src/java/org/jboss/shotoku/cache/admin/AdminBean.java
===================================================================
--- labs/shotoku/trunk/shotoku-cache/cache-admin/src/java/org/jboss/shotoku/cache/admin/AdminBean.java 2007-08-26 08:11:03 UTC (rev 14573)
+++ labs/shotoku/trunk/shotoku-cache/cache-admin/src/java/org/jboss/shotoku/cache/admin/AdminBean.java 2007-08-26 09:08:09 UTC (rev 14574)
@@ -8,10 +8,9 @@
import javax.faces.component.UIData;
import javax.faces.context.FacesContext;
-import javax.management.MalformedObjectNameException;
import javax.servlet.http.HttpServletRequest;
-import org.jboss.shotoku.cache.RenewableCacheItemData;
+import org.jboss.shotoku.cache.RenewableCacheItemOperations;
import org.jboss.shotoku.cache.service.RenewableCacheServiceMBean;
import org.jboss.shotoku.cache.service.RenewableCacheStatistics;
import org.jboss.shotoku.tools.CacheTools;
@@ -20,11 +19,12 @@
private String mbeanName;
private RenewableCacheServiceMBean service;
+
private List<CacheItemBean> cacheItems;
private long newServiceInterval;
private int newUpdateThreadCount;
- private List<String> currentAlerts;
+ private MonitorBean monitorBean;
public AdminBean() {
// For development only.
@@ -39,8 +39,8 @@
}
try {
- service = CacheTools.getService(mbean);
- } catch (MalformedObjectNameException e) {
+ service = (RenewableCacheServiceMBean) CacheTools.getService(mbean, RenewableCacheServiceMBean.class);
+ } catch (Exception e) {
throw new RuntimeException(e);
}
}
@@ -48,7 +48,6 @@
return service;
}
-
private final static Comparator<CacheItemBean> cacheItemBeanComparator = new Comparator<CacheItemBean>() {
public int compare(CacheItemBean arg0, CacheItemBean arg1) {
int id1 = arg0.getId();
@@ -67,18 +66,21 @@
};
+ public MonitorBean getMonitorBean() {
+ return monitorBean;
+ }
+
+ public void setMonitorBean(MonitorBean monitorBean) {
+ this.monitorBean = monitorBean;
+ }
+
public List<CacheItemBean> getCacheItems() {
if (cacheItems == null) {
- currentAlerts = new ArrayList<String>();
cacheItems = new ArrayList<CacheItemBean>();
- for (RenewableCacheItemData<?> cacheItemData : getService().getCacheItemsData()) {
+ for (RenewableCacheItemOperations<?> cacheItemData : getService().getCacheItemsOperations()) {
CacheItemBean cacheItemBean = new CacheItemBean(cacheItemData, getService(), this);
cacheItems.add(cacheItemBean);
-
- if (cacheItemBean.isAlerted()) {
- currentAlerts.add(cacheItemBean.getName());
- }
}
Collections.sort(cacheItems, cacheItemBeanComparator);
@@ -94,7 +96,7 @@
public void setMbeanName(String mbeanName) {
this.mbeanName = mbeanName;
}
-
+
public long getServiceLastUpdateSecondsAgo() {
return (System.currentTimeMillis() - getService().getLastUpdate())/1000;
}
@@ -139,24 +141,12 @@
getService().setInterval(newServiceInterval);
getService().setUpdateThreadCount(newUpdateThreadCount);
- Date date = new Date();
- date.toString();
-
CacheFacesTools.addTimedFacesMessage("Service interval and update " +
"thread count changed successfully.");
return null;
}
- public List<String> getCurrentAlerts() {
- getCacheItems();
- return currentAlerts;
- }
-
- public int getCurrentAlertsSize() {
- return getCurrentAlerts().size();
- }
-
/**
* Data table of a cache item. Used to retrieve a key, which has been selected.
*/
Modified: labs/shotoku/trunk/shotoku-cache/cache-admin/src/java/org/jboss/shotoku/cache/admin/CacheItemBean.java
===================================================================
--- labs/shotoku/trunk/shotoku-cache/cache-admin/src/java/org/jboss/shotoku/cache/admin/CacheItemBean.java 2007-08-26 08:11:03 UTC (rev 14573)
+++ labs/shotoku/trunk/shotoku-cache/cache-admin/src/java/org/jboss/shotoku/cache/admin/CacheItemBean.java 2007-08-26 09:08:09 UTC (rev 14574)
@@ -6,28 +6,23 @@
import java.util.Map;
import org.jboss.cache.CacheException;
-import org.jboss.shotoku.cache.RenewableCacheItemData;
+import org.jboss.shotoku.cache.RenewableCacheItemOperations;
import org.jboss.shotoku.cache.service.RenewableCacheServiceMBean;
+import org.jboss.shotoku.cache.service.monitor.CacheAlert;
public class CacheItemBean {
- private RenewableCacheItemData<?> cacheItem;
+ private RenewableCacheItemOperations<?> cacheItem;
private List<? extends Object> keysDuringUpdate;
private List<? extends Object> keysNotDuringUpdate;
private Map<Object, Long> keysUpdatesAgo;
private RenewableCacheServiceMBean service;
- /**
- * If any of the keys where updated/ are in update for a time that is longer
- * than twice the interval of this cache item.
- */
- private boolean alerted;
-
private int newId;
private long newInterval;
private AdminBean adminBean;
- public CacheItemBean(RenewableCacheItemData<?> cacheItem, RenewableCacheServiceMBean service, AdminBean adminBean) {
+ public CacheItemBean(RenewableCacheItemOperations<?> cacheItem, RenewableCacheServiceMBean service, AdminBean adminBean) {
this.cacheItem = cacheItem;
this.service = service;
@@ -39,15 +34,10 @@
Map<?, Long> keysUpdates = cacheItem.getKeysUpdates();
long now = System.currentTimeMillis();
- long maxKeyUpdateAgo = 0;
keysUpdatesAgo = new HashMap<Object, Long>();
for (Object key : keysUpdates.keySet()) {
long lastKeyUpdate = (now-keysUpdates.get(key));
keysUpdatesAgo.put(key, lastKeyUpdate/1000);
-
- if (lastKeyUpdate > maxKeyUpdateAgo) {
- maxKeyUpdateAgo = lastKeyUpdate;
- }
}
//
@@ -57,8 +47,6 @@
interval = service.getInterval();
}
- alerted = maxKeyUpdateAgo > (2*interval);
-
//
keysNotDuringUpdate = new ArrayList<Object>(keysUpdates.keySet());
@@ -66,9 +54,13 @@
}
public String getName() {
- return cacheItem.getClass().getName();
+ return cacheItem.getName();
}
+ public String getInfo() {
+ return cacheItem.getInfo();
+ }
+
public List<? extends Object> getKeysDuringUpdate() {
return keysDuringUpdate;
}
@@ -93,10 +85,10 @@
}
}
- public boolean isAlerted() {
- return alerted;
+ public List<CacheAlert> getAlerts() {
+ return adminBean.getMonitorBean().getMonitor().getAlertsForCacheItem(cacheItem);
}
-
+
public int getId() {
return cacheItem.getId();
}
Added: labs/shotoku/trunk/shotoku-cache/cache-admin/src/java/org/jboss/shotoku/cache/admin/MonitorBean.java
===================================================================
--- labs/shotoku/trunk/shotoku-cache/cache-admin/src/java/org/jboss/shotoku/cache/admin/MonitorBean.java (rev 0)
+++ labs/shotoku/trunk/shotoku-cache/cache-admin/src/java/org/jboss/shotoku/cache/admin/MonitorBean.java 2007-08-26 09:08:09 UTC (rev 14574)
@@ -0,0 +1,113 @@
+package org.jboss.shotoku.cache.admin;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jboss.shotoku.cache.RenewableCacheItemOperations;
+import org.jboss.shotoku.cache.service.monitor.DummyRenewableCacheMonitorService;
+import org.jboss.shotoku.cache.service.monitor.RenewableCacheMonitorServiceMBean;
+import org.jboss.shotoku.tools.CacheTools;
+
+public class MonitorBean {
+ private RenewableCacheMonitorServiceMBean monitor;
+
+ private boolean monitorAvailable;
+ private String monitorMbeanName;
+
+ public RenewableCacheMonitorServiceMBean getMonitor() {
+ if (monitor == null) {
+ String mbean = getMonitorMbeanName();
+ if (mbean == null) {
+ mbean = CacheTools.DEFAULT_CACHE_MONITOR_MBEAN;
+ }
+
+ try {
+ monitor = (RenewableCacheMonitorServiceMBean) CacheTools.getService(mbean, RenewableCacheMonitorServiceMBean.class);
+ monitorAvailable = true;
+ } catch (Exception e) {
+ monitor = new DummyRenewableCacheMonitorService();
+ monitorAvailable = false;
+ }
+ }
+
+ return monitor;
+ }
+
+ public String getMonitorMbeanName() {
+ return monitorMbeanName;
+ }
+
+ public void setMonitorMbeanName(String monitorMbeanName) {
+ this.monitorMbeanName = monitorMbeanName;
+ }
+
+ public boolean getMonitorAvailable() {
+ getMonitor();
+ return monitorAvailable;
+ }
+
+ private List<String> currentAlerts;
+
+ public List<String> getCurrentAlerts() {
+ if (currentAlerts == null) {
+ currentAlerts = new ArrayList<String>();
+ for (RenewableCacheItemOperations<?> rcid : getMonitor().getCacheItemsWithAlerts()) {
+ currentAlerts.add(rcid.getName());
+ }
+ }
+
+ return currentAlerts;
+ }
+
+ public int getCurrentAlertsSize() {
+ return getCurrentAlerts().size();
+ }
+
+ public String clearAlerts() {
+ getMonitor().clearAlerts();
+ currentAlerts = null;
+ return null;
+ }
+
+ /*
+ * Configuration
+ */
+
+ private long newInterval;
+ private int newMaximumNumberOfAlerts;
+ private int newUpdateAlertIntervalMultiplier;
+
+ public long getInterval() {
+ return getMonitor().getInterval();
+ }
+
+ public void setInterval(long interval) {
+ newInterval = interval;
+ }
+
+ public int getMaximumNumberOfAlerts() {
+ return getMonitor().getMaximumNumberOfAlerts();
+ }
+
+ public void setMaximumNumberOfAlerts(int maximumNumberOfAlerts) {
+ newMaximumNumberOfAlerts = maximumNumberOfAlerts;
+ }
+
+ public int getUpdateAlertIntervalMultiplier() {
+ return getMonitor().getUpdateAlertIntervalMultiplier();
+ }
+
+ public void setUpdateAlertIntervalMultiplier(int updateAlertIntervalMultiplier) {
+ newUpdateAlertIntervalMultiplier = updateAlertIntervalMultiplier;
+ }
+
+ public String updateServiceConfig() {
+ getMonitor().setInterval(newInterval);
+ getMonitor().setMaximumNumberOfAlerts(newMaximumNumberOfAlerts);
+ getMonitor().setUpdateAlertIntervalMultiplier(newUpdateAlertIntervalMultiplier);
+
+ CacheFacesTools.addTimedFacesMessage("Monitor configuration changed successfully.");
+
+ return null;
+ }
+}
Modified: labs/shotoku/trunk/shotoku-cache/cache-admin/src/web/WEB-INF/faces-config.xml
===================================================================
--- labs/shotoku/trunk/shotoku-cache/cache-admin/src/web/WEB-INF/faces-config.xml 2007-08-26 08:11:03 UTC (rev 14573)
+++ labs/shotoku/trunk/shotoku-cache/cache-admin/src/web/WEB-INF/faces-config.xml 2007-08-26 09:08:09 UTC (rev 14574)
@@ -12,5 +12,19 @@
<property-name>mbeanName</property-name>
<null-value/>
</managed-property>
+ <managed-property>
+ <property-name>monitorBean</property-name>
+ <value>#{monitor}</value>
+ </managed-property>
</managed-bean>
+
+ <managed-bean>
+ <managed-bean-name>monitor</managed-bean-name>
+ <managed-bean-class>org.jboss.shotoku.cache.admin.MonitorBean</managed-bean-class>
+ <managed-bean-scope>request</managed-bean-scope>
+ <managed-property>
+ <property-name>monitorMbeanName</property-name>
+ <null-value/>
+ </managed-property>
+ </managed-bean>
</faces-config>
\ No newline at end of file
Modified: labs/shotoku/trunk/shotoku-cache/cache-admin/src/web/pages/admin.jsp
===================================================================
--- labs/shotoku/trunk/shotoku-cache/cache-admin/src/web/pages/admin.jsp 2007-08-26 08:11:03 UTC (rev 14573)
+++ labs/shotoku/trunk/shotoku-cache/cache-admin/src/web/pages/admin.jsp 2007-08-26 09:08:09 UTC (rev 14574)
@@ -56,6 +56,7 @@
</h:panelGrid>
</rich:simpleTogglePanel>
+ <h:panelGroup>
<rich:simpleTogglePanel switchType="client" label="Configuration">
<h:form>
<a4j:region id="AdminServiceSubmit">
@@ -82,6 +83,41 @@
</a4j:region>
</h:form>
</rich:simpleTogglePanel>
+
+ <rich:simpleTogglePanel switchType="client" label="Monitor configuration" opened="false"
+ style="margin-top: 5px;">
+ <h:form>
+ <a4j:region id="MonitorServiceSubmit">
+ <h:panelGrid columns="2" columnClasses="left_text,right_text">
+ <h:outputText value="Interval: "/>
+ <h:inputText value="#{monitor.interval}" id="MonitorInterval" required="true">
+ <f:validateLongRange minimum="1000" />
+ </h:inputText>
+
+ <h:outputText value="Max. number of alerts: "/>
+ <h:inputText value="#{monitor.maximumNumberOfAlerts}" id="MonitorMaxAlerts" required="true">
+ <f:validateLongRange maximum="100" minimum="0" />
+ </h:inputText>
+
+ <h:outputText value="Update alert multiplier: "/>
+ <h:inputText value="#{monitor.updateAlertIntervalMultiplier}" id="MonitorUpdateAlertMultiplier"
+ required="true">
+ <f:validateLongRange minimum="2" />
+ </h:inputText>
+
+ <h:outputText value="" />
+ <a4j:commandButton value="Submit" action="#{monitor.updateServiceConfig}"
+ reRender="monitorServiceMessages" />
+ </h:panelGrid>
+
+ <h:panelGroup id="monitorServiceMessages">
+ <a4j:status startText="Sending ..." stopText="" for="MonitorServiceSubmit" />
+ <h:messages showDetail="true" />
+ </h:panelGroup>
+ </a4j:region>
+ </h:form>
+ </rich:simpleTogglePanel>
+ </h:panelGroup>
</h:panelGrid>
<rich:panel styleClass="header_panel" id="cacheitem_messages">
@@ -90,13 +126,21 @@
<h:messages showDetail="true" />
</h:panelGroup>
<h:panelGroup id="alerts" styleClass="header_messages">
- <h:panelGroup rendered="#{admin.currentAlertsSize > 0}">
+ <h:panelGroup rendered="#{monitor.currentAlertsSize > 0}">
+ <h:form>
+ <a4j:region id="ClearAlertsSubmit" renderRegionOnly="false">
<rich:panel styleClass="alert_panel">
<h:outputText value="Current alerts:" styleClass="alert" />
- <rich:dataList var="alert" value="#{admin.currentAlerts}">
+ <rich:dataList var="alert" value="#{monitor.currentAlerts}">
<h:outputText value="#{alert}" />
</rich:dataList>
+ <a4j:commandLink value="Clear all alerts" action="#{monitor.clearAlerts}" limitToList="true"
+ reRender="alerts,cacheitem_information" ajaxSingle="true" />
</rich:panel>
+ </a4j:region>
+
+ <a4j:status for="ClearAlertsSubmit" startText="Wait ..." stopText="" />
+ </h:form>
</h:panelGroup>
</h:panelGroup>
</rich:panel>
@@ -104,23 +148,27 @@
<rich:simpleTogglePanel switchType="client" opened="true" label="Please note" styleClass="note_panel">
<f:verbatim>
<ul>
- <li>only cache items which contain keys that should be updated/ are in update for
- a time that is at least 2*interval are expanded</li>
+ <li>only cache items which contain alerts are expanded</li>
<li>all changes in the settings will be lost on AS restart; remember to modify
the configuration files</li>
<li>checking if there are any new cache items requires a page refresh</li>
+ <li>a 0 interval in cache item configuration means that the cache item is updated on each
+ service update</li>
</ul>
</f:verbatim>
</rich:simpleTogglePanel>
<rich:dataGrid columns="1" var="cacheItem" value="#{admin.cacheItems}" styleClass="cacheitem_table" id="cacheitems">
<rich:simpleTogglePanel switchType="client" label="#{cacheItem.name}"
- opened="#{cacheItem.alerted}">
+ opened="#{cacheItem.alerts != null}">
<h:panelGrid columns="2">
<rich:simpleTogglePanel switchType="client" label="Information">
<h:panelGrid columns="2" columnClasses="left_text,right_text" id="cacheitem_information">
<h:outputText value="Name: "/>
<h:outputText value="#{cacheItem.name}" />
+
+ <h:outputText value="Info: "/>
+ <h:outputText value="#{cacheItem.info}" />
<h:outputText value="FQN: "/>
<h:outputText value="#{cacheItem.fqn}" />
@@ -128,10 +176,13 @@
<h:outputText value="FQN keys count: "/>
<h:outputText value="#{cacheItem.fqnKeysCount}" />
- <h:outputText rendered="#{cacheItem.alerted}" styleClass="alert"
- value="Alert: "/>
- <h:outputText rendered="#{cacheItem.alerted}" styleClass="alert"
- value="Some keys are not updated/ are in update for a too long time" />
+ <h:outputText rendered="#{cacheItem.alerts != null}" styleClass="alert"
+ value="Alert(s): "/>
+ <rich:dataList rendered="#{cacheItem.alerts != null}" styleClass="alert"
+ value="#{cacheItem.alerts}" var="alert">
+ <h:outputText value="#{alert.timeFormatted} (#{alert.key}) #{alert.description}" />
+ <h:outputText rendered="#{alert.cause != null}" value="Show cause" />
+ </rich:dataList>
</h:panelGrid>
</rich:simpleTogglePanel>
Modified: labs/shotoku/trunk/shotoku-cache/cache-base/src/java/org/jboss/shotoku/cache/RenewableCacheItem.java
===================================================================
--- labs/shotoku/trunk/shotoku-cache/cache-base/src/java/org/jboss/shotoku/cache/RenewableCacheItem.java 2007-08-26 08:11:03 UTC (rev 14573)
+++ labs/shotoku/trunk/shotoku-cache/cache-base/src/java/org/jboss/shotoku/cache/RenewableCacheItem.java 2007-08-26 09:08:09 UTC (rev 14574)
@@ -35,8 +35,6 @@
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
-import javax.management.MalformedObjectNameException;
-
/**
* Extend this class if you want to store objects in a cache that
* will be updated on a regular intervals of time, by a service daemon
@@ -58,12 +56,11 @@
*
* @author <a href="mailto:adam.warski at jboss.org">Adam Warski</a>
*/
-public abstract class RenewableCacheItem<K, T> implements RenewableCacheItemData<K> {
+public abstract class RenewableCacheItem<K, T> implements RenewableCacheItemOperations<K> {
private final Logger log = Logger.getLogger(RenewableCacheItem.class);
private Fqn fqn;
private long interval;
- private long timeout;
private String mbeanName;
private int id;
@@ -78,6 +75,10 @@
* some keys may be waiting in a queue.
*/
private ConcurrentSet<K> keysDuringUpdate;
+ /**
+ * Exceptions whih occured on last update of keys.
+ */
+ private ConcurrentMap<K, Throwable> keysExceptions;
private RenewableCacheServiceMBean service;
@@ -97,11 +98,8 @@
* the service update thread interval. The interval should be given in milliseconds.
* If it is 0, the {@link #update()} method will be executed on every service
* thread update.
- *
- * @param timeout How long, at a maximum, an update method for a key can last. If this
- * value is non-zero, and is exceeded, a monitoring thread will interupt the update.
*/
- public RenewableCacheItem(Fqn fqn, String mbeanName, long interval, long timeout) {
+ public RenewableCacheItem(Fqn fqn, String mbeanName, long interval) {
if (mbeanName == null) {
mbeanName = CacheTools.DEFAULT_RENEWABLE_CACHE_MBEAN;
}
@@ -109,11 +107,11 @@
this.mbeanName = mbeanName;
this.interval = interval;
- this.timeout = timeout;
keysUpdates = new ConcurrentHashMap<K, Long>();
keysDuringUpdate = new ConcurrentHashSet<K>();
keysInUpdate = new ConcurrentHashSet<K>();
+ keysExceptions = new ConcurrentHashMap<K, Throwable>();
id = CacheTools.getNextId();
@@ -133,7 +131,7 @@
* update and there will be no limit on the length of a key update.
*/
public RenewableCacheItem() {
- this(null, null, 0, 0);
+ this(null, null, 0);
}
/**
@@ -148,11 +146,12 @@
keysDuringUpdate.clear();
try {
- service = CacheTools.getService(mbeanName);
- } catch (MalformedObjectNameException e) {
+ service = (RenewableCacheServiceMBean)
+ CacheTools.getService(mbeanName, RenewableCacheServiceMBean.class);
+ } catch (Exception e) {
log.error("No RenewableCacheService bound to "
+ mbeanName + " in cache item "
- + this.getClass() + "!");
+ + getName() + "!");
return;
}
@@ -207,25 +206,9 @@
public String getMbeanName() {
return mbeanName;
}
-
- /*
- * (non-Javadoc)
- * @see org.jboss.shotoku.cache.RenewableCacheItemConfiguration#getTimeout()
- */
- public synchronized long getTimeout() {
- return timeout;
- }
/*
* (non-Javadoc)
- * @see org.jboss.shotoku.cache.RenewableCacheItemConfiguration#setTimeout(long)
- */
- public synchronized void setTimeout(long timeout) {
- this.timeout = timeout;
- }
-
- /*
- * (non-Javadoc)
* @see org.jboss.shotoku.cache.RenewableCacheItemConfiguration#getKeysDuringUpdate()
*/
public ConcurrentSet<K> getKeysDuringUpdate() {
@@ -240,9 +223,37 @@
return keysUpdates;
}
+ /*
+ * (non-Javadoc)
+ * @see org.jboss.shotoku.cache.RenewableCacheItemOperations#getKeysExceptions()
+ */
+ public ConcurrentMap<K, Throwable> getKeysExceptions() {
+ return keysExceptions;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.jboss.shotoku.cache.RenewableCacheItemOperations#getId()
+ */
public int getId() {
return id;
}
+
+ /*
+ * (non-Javadoc)
+ * @see org.jboss.shotoku.cache.RenewableCacheItemData#getInfo()
+ */
+ public String getInfo() {
+ return "";
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.jboss.shotoku.cache.RenewableCacheItemData#getName()
+ */
+ public String getName() {
+ return this.getClass().getName();
+ }
/**
* Binds the given key with the given object in the associated TreeCache
@@ -312,7 +323,7 @@
for (final K key : keysUpdates.keySet()) {
if (now - keysUpdates.get(key) >= interval) {
if (keysInUpdate.add(key)) {
- service.addUpdateThreadData(new UpdateThreadData() {
+ service.addUpdateThreadData(new UpdateThreadData<K>(key, this) {
public void execute() {
keysUpdates.put(key, System.currentTimeMillis());
keysDuringUpdate.add(key);
@@ -338,8 +349,28 @@
keysInUpdate.remove(key);
keysDuringUpdate.remove(key);
}
+
+ /*
+ * (non-Javadoc)
+ * @see org.jboss.shotoku.cache.RenewableCacheItemOperations#reportUpdateOk(java.lang.Object)
+ */
+ public void reportUpdateOk(K key) {
+
+ }
- /**
+ /*
+ * (non-Javadoc)
+ * @see org.jboss.shotoku.cache.RenewableCacheItemOperations#reportUpdateWithException(java.lang.Object, java.lang.Throwable)
+ */
+ public void reportUpdateWithException(K key, Throwable t) {
+ if (keysExceptions.put(key, t) == null) {
+ // There was no exception before.
+ log.error("Update of cache item " + getName() + " for key " + key + " threw an exception. Suppressing " +
+ "subsequent exceptions.", t);
+ }
+ }
+
+ /**
* Called by the service periodically to update the object held in the
* cache.
* If the object in the cache should be changed, the implementing
Deleted: labs/shotoku/trunk/shotoku-cache/cache-base/src/java/org/jboss/shotoku/cache/RenewableCacheItemData.java
===================================================================
--- labs/shotoku/trunk/shotoku-cache/cache-base/src/java/org/jboss/shotoku/cache/RenewableCacheItemData.java 2007-08-26 08:11:03 UTC (rev 14573)
+++ labs/shotoku/trunk/shotoku-cache/cache-base/src/java/org/jboss/shotoku/cache/RenewableCacheItemData.java 2007-08-26 09:08:09 UTC (rev 14574)
@@ -1,110 +0,0 @@
-/******************************************************************************
- * JBoss, a division of Red Hat *
- * Copyright 2006, Red Hat Middleware, LLC, and individual *
- * contributors as indicated by the @authors tag. See the *
- * copyright.txt in the distribution for a full listing of *
- * individual contributors. *
- * *
- * This is free software; you can redistribute it and/or modify it *
- * under the terms of the GNU Lesser General Public License as *
- * published by the Free Software Foundation; either version 2.1 of *
- * the License, or (at your option) any later version. *
- * *
- * This software 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 *
- * Lesser General Public License for more details. *
- * *
- * You should have received a copy of the GNU Lesser General Public *
- * License along with this software; if not, write to the Free *
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org. *
- ******************************************************************************/
-package org.jboss.shotoku.cache;
-
-import java.util.Map;
-import java.util.Set;
-
-import org.jboss.cache.Fqn;
-import org.jboss.shotoku.cache.service.RenewableCacheServiceMBean;
-
-/**
- * Configuration data of a cache item.
- * @param <K> Type of the key of the objects held in cache. The keys
- * should bahave well as map keys (most probably, the hashCode() and
- * equals() methods should be overriden).
- * @author <a href="mailto:adam.warski at jboss.org">Adam Warski</a>
- */
-public interface RenewableCacheItemData<K> {
- /**
- *
- * @return A fqn of a TreeCache node associated with this cache item. This is a node in which
- * data will be kept.
- */
- public Fqn getFqn();
-
- /**
- *
- * @return Interval at which the update operation will be executed.
- * Effectively, the interval will be rounded to the nearest multiplicity of
- * the service update thread interval. The interval should be given in milliseconds.
- * If it is 0, the {@link RenewableCacheItem#update()} method will be executed on every service
- * thread update.
- */
- public long getInterval();
- /**
- *
- * @param interval Interval at which the update operation will be executed.
- * Effectively, the interval will be rounded to the nearest multiplicity of
- * the service update thread interval. The interval should be given in milliseconds.
- * If it is 0, the {@link RenewableCacheItem#update()} method will be executed on every service
- * thread update.
- */
- public void setInterval(long interval);
-
- /**
- *
- * @return How long, at a maximum, an update method for a key can last. If this
- * value is non-zero, and is exceeded, a monitoring thread will interupt the update.
- */
- public long getTimeout();
- /**
- *
- * @param timeout How long, at a maximum, an update method for a key can last. If this
- * value is non-zero, and is exceeded, a monitoring thread will interupt the update.
- */
- public void setTimeout(long timeout);
-
- /**
- *
- * @return Name of an mbean implementing the {@link RenewableCacheServiceMBean} interface, associated
- * with this cache item.
- */
- public String getMbeanName();
-
- /**
- *
- * @return A map of keys, which are handeled by this cache item, and corresponding last
- * update times.
- */
- public Map<K, Long> getKeysUpdates();
-
- /**
- *
- * @return A set of keys, which are currently being updated.
- */
- public Set<K> getKeysDuringUpdate();
-
- /**
- *
- * @return A unique id of this instance of cache items.
- */
- public int getId();
-
- /**
- * Resets the given key, that is, it's update status. Hence, if a thread updating a key
- * locks for some reason, it is possible to resume updates of this thread. Use with caution.
- * @param key Key, which update status should be reset.
- */
- public void resetKey(Object key);
-}
Added: labs/shotoku/trunk/shotoku-cache/cache-base/src/java/org/jboss/shotoku/cache/RenewableCacheItemOperations.java
===================================================================
--- labs/shotoku/trunk/shotoku-cache/cache-base/src/java/org/jboss/shotoku/cache/RenewableCacheItemOperations.java (rev 0)
+++ labs/shotoku/trunk/shotoku-cache/cache-base/src/java/org/jboss/shotoku/cache/RenewableCacheItemOperations.java 2007-08-26 09:08:09 UTC (rev 14574)
@@ -0,0 +1,129 @@
+/******************************************************************************
+ * JBoss, a division of Red Hat *
+ * Copyright 2006, Red Hat Middleware, LLC, and individual *
+ * contributors as indicated by the @authors tag. See the *
+ * copyright.txt in the distribution for a full listing of *
+ * individual contributors. *
+ * *
+ * This is free software; you can redistribute it and/or modify it *
+ * under the terms of the GNU Lesser General Public License as *
+ * published by the Free Software Foundation; either version 2.1 of *
+ * the License, or (at your option) any later version. *
+ * *
+ * This software 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 *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this software; if not, write to the Free *
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org. *
+ ******************************************************************************/
+package org.jboss.shotoku.cache;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.jboss.cache.Fqn;
+import org.jboss.shotoku.cache.service.RenewableCacheServiceMBean;
+
+/**
+ * Configuration nad other operations on a cache item ({@link RenewableCacheItem}).
+ * @param <K> Type of the key of the objects held in cache. The keys
+ * should bahave well as map keys (most probably, the hashCode() and
+ * equals() methods should be overriden).
+ * @author <a href="mailto:adam.warski at jboss.org">Adam Warski</a>
+ */
+public interface RenewableCacheItemOperations<K> {
+ /**
+ *
+ * @return A fqn of a TreeCache node associated with this cache item. This is a node in which
+ * data will be kept.
+ */
+ public Fqn getFqn();
+
+ /**
+ *
+ * @return Interval at which the update operation will be executed.
+ * Effectively, the interval will be rounded to the nearest multiplicity of
+ * the service update thread interval. The interval should be given in milliseconds.
+ * If it is 0, the {@link RenewableCacheItem#update()} method will be executed on every service
+ * thread update.
+ */
+ public long getInterval();
+ /**
+ *
+ * @param interval Interval at which the update operation will be executed.
+ * Effectively, the interval will be rounded to the nearest multiplicity of
+ * the service update thread interval. The interval should be given in milliseconds.
+ * If it is 0, the {@link RenewableCacheItem#update()} method will be executed on every service
+ * thread update.
+ */
+ public void setInterval(long interval);
+
+ /**
+ *
+ * @return Name of an mbean implementing the {@link RenewableCacheServiceMBean} interface, associated
+ * with this cache item.
+ */
+ public String getMbeanName();
+
+ /**
+ *
+ * @return A map of keys, which are handeled by this cache item, and corresponding last
+ * update times.
+ */
+ public Map<K, Long> getKeysUpdates();
+
+ /**
+ *
+ * @return A set of keys, which are currently being updated.
+ */
+ public Set<K> getKeysDuringUpdate();
+
+ /**
+ *
+ * @return A map of keys, in which an exception occured during an update.
+ */
+ public Map<K, Throwable> getKeysExceptions();
+
+ /**
+ *
+ * @return A unique id of this instance of cache item.
+ */
+ public int getId();
+
+ /**
+ * Resets the given key, that is, it's update status. Hence, if a thread updating a key
+ * locks for some reason, it is possible to resume updates of this thread. Use with caution.
+ * @param key Key, which update status should be reset.
+ */
+ public void resetKey(Object key);
+
+ /**
+ *
+ * @return Additional information about the state of this object. Defaults to an empty string, but
+ * {@link RenewableCacheItem} implementations can override this method.
+ */
+ public String getInfo();
+
+ /**
+ *
+ * @return Name of this {@link RenewableCacheItem}. Usually the fully qualified class name.
+ */
+ public String getName();
+
+ /**
+ * Reports that an update of a key ended wihtout any exceptions.
+ * @param key Key which has been updated.
+ */
+ public void reportUpdateOk(K key);
+
+ /**
+ * Reports that an update of a key ended with an exception.
+ * @param key Key which has been updated.
+ * @param t Exception which was thrown during the update.
+ */
+ public void reportUpdateWithException(K key, Throwable t);
+}
Modified: labs/shotoku/trunk/shotoku-cache/cache-base/src/java/org/jboss/shotoku/cache/SignalExitUpdateThreadData.java
===================================================================
--- labs/shotoku/trunk/shotoku-cache/cache-base/src/java/org/jboss/shotoku/cache/SignalExitUpdateThreadData.java 2007-08-26 08:11:03 UTC (rev 14573)
+++ labs/shotoku/trunk/shotoku-cache/cache-base/src/java/org/jboss/shotoku/cache/SignalExitUpdateThreadData.java 2007-08-26 09:08:09 UTC (rev 14574)
@@ -27,7 +27,11 @@
*
* @author <a href="mailto:adam.warski at jboss.org">Adam Warski</a>
*/
-public class SignalExitUpdateThreadData extends UpdateThreadData {
+public class SignalExitUpdateThreadData<K> extends UpdateThreadData<K> {
+ public SignalExitUpdateThreadData() {
+ super(null, null);
+ }
+
@Override
public void execute() {
}
Modified: labs/shotoku/trunk/shotoku-cache/cache-base/src/java/org/jboss/shotoku/cache/UpdateThread.java
===================================================================
--- labs/shotoku/trunk/shotoku-cache/cache-base/src/java/org/jboss/shotoku/cache/UpdateThread.java 2007-08-26 08:11:03 UTC (rev 14573)
+++ labs/shotoku/trunk/shotoku-cache/cache-base/src/java/org/jboss/shotoku/cache/UpdateThread.java 2007-08-26 09:08:09 UTC (rev 14574)
@@ -34,10 +34,10 @@
public class UpdateThread extends Thread {
private static final Logger log = Logger.getLogger(UpdateThread.class);
- private BlockingQueue<UpdateThreadData> queue;
+ private BlockingQueue<UpdateThreadData<?>> queue;
private RenewableCacheServiceMBean service;
- public UpdateThread(RenewableCacheServiceMBean service, LinkedBlockingQueue<UpdateThreadData> queue) {
+ public UpdateThread(RenewableCacheServiceMBean service, LinkedBlockingQueue<UpdateThreadData<?>> queue) {
this.queue = queue;
this.service = service;
@@ -48,7 +48,7 @@
service.reportThreadNew();
while (true) {
- UpdateThreadData data;
+ UpdateThreadData<?> data;
try {
data = queue.take();
service.reportThreadBusy();
@@ -56,15 +56,16 @@
long start = System.currentTimeMillis();
service.getStatistics().addPacketWaitingTime(start - data.getCreateTime());
- if (data instanceof SignalExitUpdateThreadData) {
+ if (data instanceof SignalExitUpdateThreadData<?>) {
break;
}
try {
data.execute();
+ data.updateOk();
service.getStatistics().addPacketProcessingTime(System.currentTimeMillis() - start, false);
} catch (Throwable t) {
- log.error("Exception while executing an update thread data.", t);
+ data.updateWithException(t);
service.getStatistics().addPacketProcessingTime(System.currentTimeMillis() - start, true);
}
Modified: labs/shotoku/trunk/shotoku-cache/cache-base/src/java/org/jboss/shotoku/cache/UpdateThreadData.java
===================================================================
--- labs/shotoku/trunk/shotoku-cache/cache-base/src/java/org/jboss/shotoku/cache/UpdateThreadData.java 2007-08-26 08:11:03 UTC (rev 14573)
+++ labs/shotoku/trunk/shotoku-cache/cache-base/src/java/org/jboss/shotoku/cache/UpdateThreadData.java 2007-08-26 09:08:09 UTC (rev 14574)
@@ -23,19 +23,34 @@
package org.jboss.shotoku.cache;
/**
- * Function that should be executed by an update thread.
+ * Function that should be executed by an update thread; updates an associated
+ * key in a cache item.
* @author <a href="mailto:adam.warski at jboss.org">Adam Warski</a>
*/
-public abstract class UpdateThreadData {
+public abstract class UpdateThreadData<K> {
private long createTime;
- public UpdateThreadData() {
+ private K key;
+ private RenewableCacheItemOperations<K> cacheItem;
+
+ public UpdateThreadData(K key, RenewableCacheItemOperations<K> cacheItem) {
createTime = System.currentTimeMillis();
+
+ this.key = key;
+ this.cacheItem = cacheItem;
}
public long getCreateTime() {
return createTime;
}
+ public void updateOk() {
+ cacheItem.reportUpdateOk(key);
+ }
+
+ public void updateWithException(Throwable t) {
+ cacheItem.reportUpdateWithException(key, t);
+ }
+
public abstract void execute();
}
Modified: labs/shotoku/trunk/shotoku-cache/cache-base/src/java/org/jboss/shotoku/cache/service/DummyRenewableCacheService.java
===================================================================
--- labs/shotoku/trunk/shotoku-cache/cache-base/src/java/org/jboss/shotoku/cache/service/DummyRenewableCacheService.java 2007-08-26 08:11:03 UTC (rev 14573)
+++ labs/shotoku/trunk/shotoku-cache/cache-base/src/java/org/jboss/shotoku/cache/service/DummyRenewableCacheService.java 2007-08-26 09:08:09 UTC (rev 14574)
@@ -7,7 +7,7 @@
import org.jboss.cache.Fqn;
import org.jboss.cache.TreeCacheMBean;
import org.jboss.shotoku.cache.RenewableCacheItem;
-import org.jboss.shotoku.cache.RenewableCacheItemData;
+import org.jboss.shotoku.cache.RenewableCacheItemOperations;
import org.jboss.shotoku.cache.UpdateThreadData;
/**
@@ -16,7 +16,7 @@
* @author <a href="mailto:adam.warski at jboss.org">Adam Warski</a>
*/
public class DummyRenewableCacheService implements RenewableCacheServiceMBean {
- public void addUpdateThreadData(UpdateThreadData data) {
+ public void addUpdateThreadData(UpdateThreadData<?> data) {
}
public Fqn generateNextFqn() {
@@ -88,7 +88,7 @@
public void update() {
}
- public Set<? extends RenewableCacheItemData<?>> getCacheItemsData() {
+ public Set<? extends RenewableCacheItemOperations<?>> getCacheItemsOperations() {
return null;
}
Modified: labs/shotoku/trunk/shotoku-cache/cache-base/src/java/org/jboss/shotoku/cache/service/RenewableCacheServiceMBean.java
===================================================================
--- labs/shotoku/trunk/shotoku-cache/cache-base/src/java/org/jboss/shotoku/cache/service/RenewableCacheServiceMBean.java 2007-08-26 08:11:03 UTC (rev 14573)
+++ labs/shotoku/trunk/shotoku-cache/cache-base/src/java/org/jboss/shotoku/cache/service/RenewableCacheServiceMBean.java 2007-08-26 09:08:09 UTC (rev 14574)
@@ -28,7 +28,7 @@
import org.jboss.cache.Fqn;
import org.jboss.cache.TreeCacheMBean;
import org.jboss.shotoku.cache.RenewableCacheItem;
-import org.jboss.shotoku.cache.RenewableCacheItemData;
+import org.jboss.shotoku.cache.RenewableCacheItemOperations;
import org.jboss.shotoku.cache.UpdateThreadData;
/**
@@ -45,7 +45,7 @@
public Fqn generateNextFqn();
- public void addUpdateThreadData(UpdateThreadData data);
+ public void addUpdateThreadData(UpdateThreadData<?> data);
public int getCurrentQueueSize();
public RenewableCacheStatistics getStatistics();
@@ -69,7 +69,7 @@
public int getIdleThreadCount();
public int getBusyThreadCount();
- public Set<? extends RenewableCacheItemData<?>> getCacheItemsData();
+ public Set<? extends RenewableCacheItemOperations<?>> getCacheItemsOperations();
public void update();
Added: labs/shotoku/trunk/shotoku-cache/cache-base/src/java/org/jboss/shotoku/cache/service/monitor/CacheAlert.java
===================================================================
--- labs/shotoku/trunk/shotoku-cache/cache-base/src/java/org/jboss/shotoku/cache/service/monitor/CacheAlert.java (rev 0)
+++ labs/shotoku/trunk/shotoku-cache/cache-base/src/java/org/jboss/shotoku/cache/service/monitor/CacheAlert.java 2007-08-26 09:08:09 UTC (rev 14574)
@@ -0,0 +1,36 @@
+package org.jboss.shotoku.cache.service.monitor;
+
+import org.jboss.shotoku.cache.RenewableCacheItem;
+
+/**
+ * Information about probably incorrect behaviour of cache items, collected
+ * by the monitoring thread.
+ * @author <a href="mailto:adam.warski at jboss.org">Adam Warski</a>
+ */
+public interface CacheAlert {
+ /**
+ *
+ * @return Time on which the represented behaviour was observed.
+ */
+ public long getTime();
+ /**
+ *
+ * @return Time on which the represented behaviour was observed, formatted as a string.
+ */
+ public String getTimeFormatted();
+ /**
+ *
+ * @return Short description of the incorrect behaviour.
+ */
+ public String getDescription();
+ /**
+ *
+ * @return Possible/definite cause of the incorrect behaviour.
+ */
+ public String getCause();
+ /**
+ *
+ * @return {@link RenewableCacheItem} key, for which the incorrect behaviour occured.
+ */
+ public Object getKey();
+}
Added: labs/shotoku/trunk/shotoku-cache/cache-base/src/java/org/jboss/shotoku/cache/service/monitor/CacheAlertFactory.java
===================================================================
--- labs/shotoku/trunk/shotoku-cache/cache-base/src/java/org/jboss/shotoku/cache/service/monitor/CacheAlertFactory.java (rev 0)
+++ labs/shotoku/trunk/shotoku-cache/cache-base/src/java/org/jboss/shotoku/cache/service/monitor/CacheAlertFactory.java 2007-08-26 09:08:09 UTC (rev 14574)
@@ -0,0 +1,15 @@
+package org.jboss.shotoku.cache.service.monitor;
+
+public class CacheAlertFactory {
+ public static CacheAlert createAlertKeyNotUpdated(Object key) {
+ return new CacheAlertImpl(null, "Key hasn't been updated for a long time.", key);
+ }
+
+ public static CacheAlert createAlertKeyTooLongInUpdate(Object key) {
+ return new CacheAlertImpl(null, "Key is too long in update.", key);
+ }
+
+ public static CacheAlert createAlertKeyException(Object key, Throwable t) {
+ return new CacheAlertImpl(t.toString(), "An exception occured during key update.", key);
+ }
+}
Added: labs/shotoku/trunk/shotoku-cache/cache-base/src/java/org/jboss/shotoku/cache/service/monitor/CacheAlertImpl.java
===================================================================
--- labs/shotoku/trunk/shotoku-cache/cache-base/src/java/org/jboss/shotoku/cache/service/monitor/CacheAlertImpl.java (rev 0)
+++ labs/shotoku/trunk/shotoku-cache/cache-base/src/java/org/jboss/shotoku/cache/service/monitor/CacheAlertImpl.java 2007-08-26 09:08:09 UTC (rev 14574)
@@ -0,0 +1,75 @@
+package org.jboss.shotoku.cache.service.monitor;
+
+import java.text.DateFormat;
+import java.util.Date;
+
+
+/**
+ *
+ * @author <a href="mailto:adam.warski at jboss.org">Adam Warski</a>
+ */
+public class CacheAlertImpl implements CacheAlert {
+ private long time;
+ private String cause;
+ private String description;
+ private Object key;
+
+ public CacheAlertImpl(String cause, String description, Object key) {
+ super();
+ this.time = System.currentTimeMillis();
+ this.cause = cause;
+ this.description = description;
+ this.key = key;
+ }
+
+ public String getCause() {
+ return cause;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public long getTime() {
+ return time;
+ }
+
+ public Object getKey() {
+ return key;
+ }
+
+ public String getTimeFormatted() {
+ return DateFormat.getTimeInstance(DateFormat.SHORT).format(new Date(getTime()));
+ }
+
+ @Override
+ public int hashCode() {
+ final int PRIME = 31;
+ int result = 1;
+ result = PRIME * result + ((description == null) ? 0 : description.hashCode());
+ result = PRIME * result + ((key == null) ? 0 : key.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ final CacheAlertImpl other = (CacheAlertImpl) obj;
+ if (description == null) {
+ if (other.description != null)
+ return false;
+ } else if (!description.equals(other.description))
+ return false;
+ if (key == null) {
+ if (other.key != null)
+ return false;
+ } else if (!key.equals(other.key))
+ return false;
+ return true;
+ }
+}
Added: labs/shotoku/trunk/shotoku-cache/cache-base/src/java/org/jboss/shotoku/cache/service/monitor/DummyRenewableCacheMonitorService.java
===================================================================
--- labs/shotoku/trunk/shotoku-cache/cache-base/src/java/org/jboss/shotoku/cache/service/monitor/DummyRenewableCacheMonitorService.java (rev 0)
+++ labs/shotoku/trunk/shotoku-cache/cache-base/src/java/org/jboss/shotoku/cache/service/monitor/DummyRenewableCacheMonitorService.java 2007-08-26 09:08:09 UTC (rev 14574)
@@ -0,0 +1,66 @@
+package org.jboss.shotoku.cache.service.monitor;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.jboss.shotoku.cache.RenewableCacheItemOperations;
+import org.jboss.shotoku.cache.service.RenewableCacheServiceMBean;
+
+public class DummyRenewableCacheMonitorService implements RenewableCacheMonitorServiceMBean {
+ public void clearAlerts() {
+
+ }
+
+ public List<CacheAlert> getAlertsForCacheItem(RenewableCacheItemOperations<?> rcid) {
+ return null;
+ }
+
+ public Set<RenewableCacheItemOperations<?>> getCacheItemsWithAlerts() {
+ return new HashSet<RenewableCacheItemOperations<?>>();
+ }
+
+ public long getInterval() {
+ return 0;
+ }
+
+ public int getMaximumNumberOfAlerts() {
+ return 0;
+ }
+
+ public RenewableCacheServiceMBean getRenewableCacheService() {
+ return null;
+ }
+
+ public int getUpdateAlertIntervalMultiplier() {
+ return 0;
+ }
+
+ public void setInterval(long interval) {
+
+ }
+
+ public void setMaximumNumberOfAlerts(int maximumNumberOfAlerts) {
+
+ }
+
+ public void setRenewableCacheService(RenewableCacheServiceMBean renewableCacheService) {
+
+ }
+
+ public void setUpdateAlertIntervalMultiplier(int updateAlertIntervalMultiplier) {
+
+ }
+
+ public void start() {
+
+ }
+
+ public void stop() {
+
+ }
+
+ public void update() {
+
+ }
+}
Added: labs/shotoku/trunk/shotoku-cache/cache-base/src/java/org/jboss/shotoku/cache/service/monitor/RenewableCacheMonitorServiceMBean.java
===================================================================
--- labs/shotoku/trunk/shotoku-cache/cache-base/src/java/org/jboss/shotoku/cache/service/monitor/RenewableCacheMonitorServiceMBean.java (rev 0)
+++ labs/shotoku/trunk/shotoku-cache/cache-base/src/java/org/jboss/shotoku/cache/service/monitor/RenewableCacheMonitorServiceMBean.java 2007-08-26 09:08:09 UTC (rev 14574)
@@ -0,0 +1,75 @@
+package org.jboss.shotoku.cache.service.monitor;
+
+import java.util.List;
+import java.util.Set;
+
+import org.jboss.shotoku.cache.RenewableCacheItemOperations;
+import org.jboss.shotoku.cache.service.RenewableCacheServiceMBean;
+
+/**
+ *
+ * @author <a href="mailto:adam.warski at jboss.org">Adam Warski</a>
+ */
+public interface RenewableCacheMonitorServiceMBean {
+ public RenewableCacheServiceMBean getRenewableCacheService();
+ public void setRenewableCacheService(RenewableCacheServiceMBean renewableCacheService);
+
+ /**
+ *
+ * @return Interval at which cache items will be checked, if there are no errors.
+ */
+ public long getInterval();
+ /**
+ *
+ * @param interval Interval at which cache items will be checked, if there are no errors.
+ */
+ public void setInterval(long interval);
+
+ /**
+ *
+ * @return Maximum number of alerts stored. After this number is exceeded, no new alerts
+ * are recorded.
+ */
+ public int getMaximumNumberOfAlerts();
+ /**
+ *
+ * @param Maximum number of alerts stored. After this number is exceeded, no new alerts
+ * are recorded.
+ */
+ public void setMaximumNumberOfAlerts(int maximumNumberOfAlerts);
+
+ /**
+ *
+ * @return How many times the interval of a cache item must be exceeded, before an
+ * "key not updated" or "key too long in update" alert is issued.
+ */
+ public int getUpdateAlertIntervalMultiplier();
+ /**
+ *
+ * @param updateAlertIntervalMultiplier How many times the interval of a cache item must be exceeded, before an
+ * "key not updated" or "key too long in update" alert is issued.
+ */
+ public void setUpdateAlertIntervalMultiplier(int updateAlertIntervalMultiplier);
+
+ public void update();
+
+ public void start();
+ public void stop();
+
+ /**
+ *
+ * @param rcid {@link RenewableCacheItem} for which to get alerts.
+ * @return A list of alerts for the given {@link RenewableCacheItem}, sorted from the
+ * newest alert, or null is there are no alerts for the given cache item.
+ */
+ public List<CacheAlert> getAlertsForCacheItem(RenewableCacheItemOperations<?> rcid);
+ /**
+ * Clears all alerts.
+ */
+ public void clearAlerts();
+ /**
+ *
+ * @return A set of {@link RenewableCacheItemOperations}, for which there are any alerts.
+ */
+ public Set<RenewableCacheItemOperations<?>> getCacheItemsWithAlerts();
+}
Modified: labs/shotoku/trunk/shotoku-cache/cache-base/src/java/org/jboss/shotoku/tools/CacheTools.java
===================================================================
--- labs/shotoku/trunk/shotoku-cache/cache-base/src/java/org/jboss/shotoku/tools/CacheTools.java 2007-08-26 08:11:03 UTC (rev 14573)
+++ labs/shotoku/trunk/shotoku-cache/cache-base/src/java/org/jboss/shotoku/tools/CacheTools.java 2007-08-26 09:08:09 UTC (rev 14574)
@@ -27,6 +27,7 @@
import org.jboss.mx.util.MBeanProxyExt;
import org.jboss.mx.util.MBeanServerLocator;
import org.jboss.shotoku.cache.service.RenewableCacheServiceMBean;
+import org.jboss.shotoku.cache.service.monitor.RenewableCacheMonitorServiceMBean;
/**
* Utility, helper functions used internally.
@@ -45,15 +46,20 @@
public static final String DEFAULT_RENEWABLE_CACHE_MBEAN = "shotoku:service=RenewableCache";
/**
+ * Name of the default {@link RenewableCacheMonitorServiceMBean} mbean.
+ */
+ public static final String DEFAULT_CACHE_MONITOR_MBEAN = "shotoku:service=RenewableCacheMonitor";
+
+ /**
* Gets a reference to an mbean with the given name.
* @param mbeanName Name of the mbean to get.
+ * @param c Class of the mbean to get.
* @return A reference to the mbean.
* @throws MalformedObjectNameException
*/
- public static RenewableCacheServiceMBean getService(String mbeanName) throws MalformedObjectNameException {
- return (RenewableCacheServiceMBean) MBeanProxyExt.create(
- RenewableCacheServiceMBean.class, mbeanName,
- MBeanServerLocator.locate());
+ public static Object getService(String mbeanName,
+ Class<?> c) throws MalformedObjectNameException {
+ return MBeanProxyExt.create(c, mbeanName, MBeanServerLocator.locate());
}
/**
Modified: labs/shotoku/trunk/shotoku-cache/cache-service/src/etc/META-INF/jboss-service.xml
===================================================================
--- labs/shotoku/trunk/shotoku-cache/cache-service/src/etc/META-INF/jboss-service.xml 2007-08-26 08:11:03 UTC (rev 14573)
+++ labs/shotoku/trunk/shotoku-cache/cache-service/src/etc/META-INF/jboss-service.xml 2007-08-26 09:08:09 UTC (rev 14574)
@@ -12,6 +12,17 @@
shotoku:service=TreeCache
</depends>
</mbean>
+
+ <mbean code="org.jboss.shotoku.cache.service.monitor.RenewableCacheMonitorService"
+ name="shotoku:service=RenewableCacheMonitor">
+ <attribute name="Interval">30000</attribute>
+ <attribute name="MaximumNumberOfAlerts">20</attribute>
+ <attribute name="UpdateAlertIntervalMultiplier">2</attribute>
+ <depends optional-attribute-name="RenewableCacheService"
+ proxy-type="attribute">
+ shotoku:service=RenewableCache
+ </depends>
+ </mbean>
<mbean code="org.jboss.cache.TreeCache"
name="shotoku:service=TreeCache">
Modified: labs/shotoku/trunk/shotoku-cache/cache-service/src/java/org/jboss/shotoku/cache/service/RenewableCacheService.java
===================================================================
--- labs/shotoku/trunk/shotoku-cache/cache-service/src/java/org/jboss/shotoku/cache/service/RenewableCacheService.java 2007-08-26 08:11:03 UTC (rev 14573)
+++ labs/shotoku/trunk/shotoku-cache/cache-service/src/java/org/jboss/shotoku/cache/service/RenewableCacheService.java 2007-08-26 09:08:09 UTC (rev 14574)
@@ -26,7 +26,7 @@
import org.jboss.cache.Fqn;
import org.jboss.cache.TreeCacheMBean;
import org.jboss.shotoku.cache.RenewableCacheItem;
-import org.jboss.shotoku.cache.RenewableCacheItemData;
+import org.jboss.shotoku.cache.RenewableCacheItemOperations;
import org.jboss.shotoku.cache.SignalExitUpdateThreadData;
import org.jboss.shotoku.cache.UpdateThread;
import org.jboss.shotoku.cache.UpdateThreadData;
@@ -114,7 +114,7 @@
*
*/
- public void startUpdateThread() {
+ private void startUpdateThread() {
Thread ut = new Thread() {
{
setDaemon(true);
@@ -126,7 +126,7 @@
sleep(getInterval());
} catch (InterruptedException e) {
// Quit.
- log.info("Stopping update thread for " + getName() + " (interrupted).");
+ log.info("Stopping update thread (interrupted).");
return;
}
@@ -134,7 +134,7 @@
update();
} catch (Throwable t) {
// Making sure that an exception won't stop the thread.
- log.error("Update method for " + getName() + " threw an exception.", t);
+ log.error("Update method threw an exception.", t);
}
setLastUpdate(Calendar.getInstance().getTimeInMillis());
@@ -177,7 +177,7 @@
}
}
- public Set<? extends RenewableCacheItemData<?>> getCacheItemsData() {
+ public Set<? extends RenewableCacheItemOperations<?>> getCacheItemsOperations() {
return cacheItems;
}
@@ -195,8 +195,8 @@
* Update threads management.
*/
- private final LinkedBlockingQueue<UpdateThreadData> updateThreadDataQueue =
- new LinkedBlockingQueue<UpdateThreadData>();
+ private final LinkedBlockingQueue<UpdateThreadData<?>> updateThreadDataQueue =
+ new LinkedBlockingQueue<UpdateThreadData<?>>();
private int updateThreadCount;
private int busyThreads;
@@ -204,7 +204,7 @@
private final Object threadCounterSynchronizer = new Object();
- public void addUpdateThreadData(UpdateThreadData data) {
+ public void addUpdateThreadData(UpdateThreadData<?> data) {
updateThreadDataQueue.offer(data);
}
@@ -220,7 +220,7 @@
}
} else if (n < updateThreadCount) {
for (int i = updateThreadCount; i > n; i--) {
- updateThreadDataQueue.offer(new SignalExitUpdateThreadData());
+ updateThreadDataQueue.offer(new SignalExitUpdateThreadData<Object>());
}
}
Added: labs/shotoku/trunk/shotoku-cache/cache-service/src/java/org/jboss/shotoku/cache/service/monitor/RenewableCacheMonitorService.java
===================================================================
--- labs/shotoku/trunk/shotoku-cache/cache-service/src/java/org/jboss/shotoku/cache/service/monitor/RenewableCacheMonitorService.java (rev 0)
+++ labs/shotoku/trunk/shotoku-cache/cache-service/src/java/org/jboss/shotoku/cache/service/monitor/RenewableCacheMonitorService.java 2007-08-26 09:08:09 UTC (rev 14574)
@@ -0,0 +1,208 @@
+package org.jboss.shotoku.cache.service.monitor;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.log4j.Logger;
+import org.jboss.shotoku.cache.RenewableCacheItemOperations;
+import org.jboss.shotoku.cache.service.RenewableCacheServiceMBean;
+
+/**
+ *
+ * @author <a href="mailto:adam.warski at jboss.org">Adam Warski</a>
+ */
+public class RenewableCacheMonitorService implements RenewableCacheMonitorServiceMBean {
+ private final static Logger log = Logger.getLogger(RenewableCacheMonitorServiceMBean.class);
+
+ private long interval;
+ private RenewableCacheServiceMBean renewableCacheService;
+ private int maximumNumberOfAlerts;
+ private int updateAlertIntervalMultiplier;
+
+ public long getInterval() {
+ return interval;
+ }
+
+ public void setInterval(long interval) {
+ this.interval = interval;
+ }
+
+ public int getMaximumNumberOfAlerts() {
+ return maximumNumberOfAlerts;
+ }
+
+ public void setMaximumNumberOfAlerts(int maximumNumberOfAlerts) {
+ this.maximumNumberOfAlerts = maximumNumberOfAlerts;
+ }
+
+ public RenewableCacheServiceMBean getRenewableCacheService() {
+ return renewableCacheService;
+ }
+
+ public void setRenewableCacheService(
+ RenewableCacheServiceMBean renewableCacheService) {
+ this.renewableCacheService = renewableCacheService;
+ }
+
+ public int getUpdateAlertIntervalMultiplier() {
+ return updateAlertIntervalMultiplier;
+ }
+
+ public void setUpdateAlertIntervalMultiplier(int updateAlertIntervalMultiplier) {
+ this.updateAlertIntervalMultiplier = updateAlertIntervalMultiplier;
+ }
+
+ //
+
+ private Thread monitorThread;
+
+ public void start() {
+ monitorThread = new Thread() {
+ {
+ setDaemon(true);
+ }
+
+ public void run() {
+ while (true) {
+ try {
+ sleep(getInterval());
+ } catch (InterruptedException e) {
+ // Quit.
+ log.info("Stopping monitor thread (interrupted).");
+ return;
+ }
+
+ try {
+ update();
+ } catch (Throwable t) {
+ // Making sure that an exception won't stop the thread.
+ log.error("Monitor update method threw an exception.", t);
+ }
+ }
+ }
+ };
+
+ log.info("Starting monitor thread.");
+ monitorThread.start();
+ }
+
+ public void stop() {
+ if (monitorThread != null) {
+ log.info("Signalling monitor thread to stop.");
+ monitorThread.interrupt();
+ }
+ }
+
+ //
+
+ private Set<RenewableCacheItemOperations<?>> cacheItemsWithAlerts = new HashSet<RenewableCacheItemOperations<?>>();
+ private Map<RenewableCacheItemOperations<?>, Set<CacheAlert>> alertsForCacheItems =
+ new HashMap<RenewableCacheItemOperations<?>, Set<CacheAlert>>();
+
+ private int currentNumberOfAlerts;
+
+ private synchronized int getCurrentNumberOfAlerts() {
+ return currentNumberOfAlerts;
+ }
+
+ public void update() {
+ long now = System.currentTimeMillis();
+
+ if (getCurrentNumberOfAlerts() == getMaximumNumberOfAlerts()) {
+ // We can't add an alert anyway.
+ return;
+ }
+
+ for (RenewableCacheItemOperations<?> rcid : getRenewableCacheService().getCacheItemsOperations()) {
+ // Checking for keys that are in update for too long/ haven't been updated for a long
+ // time.
+ Set<?> keysDuringUpdate = rcid.getKeysDuringUpdate();
+ Map<?, Long> keysUpdates = rcid.getKeysUpdates();
+ // Calculating the effective interval of updates of the cache item.
+ long interval = rcid.getInterval();
+ if (interval == 0) {
+ interval = getRenewableCacheService().getInterval();
+ }
+
+ for (Object key : keysUpdates.keySet()) {
+ if (now - keysUpdates.get(key) > interval*getUpdateAlertIntervalMultiplier()) {
+ // Issuing an alert.
+ if (keysDuringUpdate.contains(key)) {
+ addAlertForCacheItem(rcid, CacheAlertFactory.createAlertKeyTooLongInUpdate(key));
+ } else {
+ addAlertForCacheItem(rcid, CacheAlertFactory.createAlertKeyNotUpdated(key));
+ }
+ }
+ }
+
+ // Checking for exceptions.
+ Map<?, Throwable> keysExceptions = rcid.getKeysExceptions();
+ for (Object key : keysExceptions.keySet()) {
+ addAlertForCacheItem(rcid, CacheAlertFactory.createAlertKeyException(key, keysExceptions.get(key)));
+ }
+ }
+ }
+
+ private synchronized void addAlertForCacheItem(RenewableCacheItemOperations<?> rcid, CacheAlert alert) {
+ Set<CacheAlert> alertsForCacheItem = alertsForCacheItems.get(rcid);
+
+ if (alertsForCacheItem == null) {
+ alertsForCacheItem = new HashSet<CacheAlert>();
+ alertsForCacheItems.put(rcid, alertsForCacheItem);
+ }
+
+ if (alertsForCacheItem.add(alert)) {
+ currentNumberOfAlerts++;
+ }
+
+ cacheItemsWithAlerts.add(rcid);
+ }
+
+ private static Comparator<CacheAlert> cacheAlertComparator = new Comparator<CacheAlert>() {
+ public int compare(CacheAlert ca1, CacheAlert ca2) {
+ if (ca1.getTime() == ca2.getTime()) {
+ return 0;
+ }
+
+ if (ca1.getTime() < ca2.getTime()) {
+ return 1;
+ }
+
+ return -1;
+ }
+ };
+
+ public synchronized List<CacheAlert> getAlertsForCacheItem(RenewableCacheItemOperations<?> rcid) {
+ Set<CacheAlert> alertsForCacheItem = alertsForCacheItems.get(rcid);
+ if (alertsForCacheItem == null) {
+ return null;
+ }
+
+ // Turning the set into a list and sorting it.
+ List<CacheAlert> alertsList = new ArrayList<CacheAlert>(alertsForCacheItem);
+ Collections.sort(alertsList, cacheAlertComparator);
+ return alertsList;
+ }
+
+ public synchronized Set<RenewableCacheItemOperations<?>> getCacheItemsWithAlerts() {
+ return cacheItemsWithAlerts;
+ }
+
+ public synchronized void clearAlerts() {
+ currentNumberOfAlerts = 0;
+
+ cacheItemsWithAlerts.clear();
+ alertsForCacheItems.clear();
+
+ // Clearing all exceptions in cache items.
+ for (RenewableCacheItemOperations<?> rcid : getRenewableCacheService().getCacheItemsOperations()) {
+ rcid.getKeysExceptions().clear();
+ }
+ }
+}
Modified: labs/shotoku/trunk/shotoku-cache/cache-test/src/java/org/jboss/shotoku/cache/test/TestServlet.java
===================================================================
--- labs/shotoku/trunk/shotoku-cache/cache-test/src/java/org/jboss/shotoku/cache/test/TestServlet.java 2007-08-26 08:11:03 UTC (rev 14573)
+++ labs/shotoku/trunk/shotoku-cache/cache-test/src/java/org/jboss/shotoku/cache/test/TestServlet.java 2007-08-26 09:08:09 UTC (rev 14574)
@@ -13,6 +13,7 @@
private TestCacheItem2 tci2;
private TestCacheItem tci3;
private TestCacheItem2 tci4;
+ private TestCacheItem3 tci5;
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
@@ -24,6 +25,7 @@
System.out.println(tci3.get("F"));
System.out.println(tci4.get("G"));
System.out.println(tci4.get("H"));
+ System.out.println(tci5.get("I"));
}
@Override
@@ -32,8 +34,8 @@
tci2 = new TestCacheItem2();
tci3 = new TestCacheItem();
tci4 = new TestCacheItem2();
+ tci5 = new TestCacheItem3();
super.init(config);
}
-
}
More information about the jboss-svn-commits
mailing list