[jboss-cvs] JBossBlog SVN: r208 - in trunk: src/action/org/jboss/blog/session/update and 1 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Fri Feb 8 10:39:07 EST 2008


Author: adamw
Date: 2008-02-08 10:39:07 -0500 (Fri, 08 Feb 2008)
New Revision: 208

Added:
   trunk/src/action/org/jboss/blog/session/update/UpdateThread.java
   trunk/view/manage/update_manager.xhtml
Modified:
   trunk/src/action/org/jboss/blog/session/merge/MergeServiceBean.java
   trunk/src/action/org/jboss/blog/session/update/UpdateHandler.java
   trunk/src/action/org/jboss/blog/session/update/UpdateManager.java
   trunk/view/manage/index.xhtml
Log:


Modified: trunk/src/action/org/jboss/blog/session/merge/MergeServiceBean.java
===================================================================
--- trunk/src/action/org/jboss/blog/session/merge/MergeServiceBean.java	2008-02-08 11:53:06 UTC (rev 207)
+++ trunk/src/action/org/jboss/blog/session/merge/MergeServiceBean.java	2008-02-08 15:39:07 UTC (rev 208)
@@ -70,10 +70,8 @@
      * Doesn't check for changes in:
      * - categories.
      *
-     * Also, in case of a title change, the titleAsId is not chagned.
+     * Also, in case of a title change, the titleAsId is not changed.
      *
-     * TODO: check only some fields
-     *
      * @param feed Feed to which the posts belong
      * @param mergeTo Post to which to merge the changes.
      * @param mergeFrom Post from which to merge the changes.

Modified: trunk/src/action/org/jboss/blog/session/update/UpdateHandler.java
===================================================================
--- trunk/src/action/org/jboss/blog/session/update/UpdateHandler.java	2008-02-08 11:53:06 UTC (rev 207)
+++ trunk/src/action/org/jboss/blog/session/update/UpdateHandler.java	2008-02-08 15:39:07 UTC (rev 208)
@@ -30,6 +30,9 @@
     @In
     private FeedTypes feedTypes;
 
+    @In
+    private UpdateManager updateManager;
+
     public void update() {
         for (Group group : feedsService.getAllGroups()) {
             for (Feed feed : groupsService.acceptedFeeds(group)) {
@@ -42,8 +45,7 @@
         try {
             feedTypes.getFeedDao(feed).update();
         } catch (UpdateException e) {
-            // TODO: log this somewhere
-            System.out.println("Exception when updating feed: " + feed.getName() + "; " + e.getMessage());
+            updateManager.addFeedUpdateException(feed.getName(), e);
         }
     }
 

Modified: trunk/src/action/org/jboss/blog/session/update/UpdateManager.java
===================================================================
--- trunk/src/action/org/jboss/blog/session/update/UpdateManager.java	2008-02-08 11:53:06 UTC (rev 207)
+++ trunk/src/action/org/jboss/blog/session/update/UpdateManager.java	2008-02-08 15:39:07 UTC (rev 208)
@@ -1,19 +1,17 @@
 package org.jboss.blog.session.update;
 
 import org.jboss.seam.ScopeType;
-import org.jboss.seam.Component;
-import org.jboss.seam.log.Logging;
-import org.jboss.seam.contexts.Contexts;
-import org.jboss.seam.contexts.Lifecycle;
 import org.jboss.seam.annotations.*;
+import org.jboss.seam.annotations.Observer;
 
-import javax.transaction.UserTransaction;
-import javax.transaction.Status;
-import javax.transaction.SystemException;
-import javax.persistence.EntityManager;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.*;
+import java.text.DateFormat;
+import java.io.ByteArrayOutputStream;
+import java.io.PrintWriter;
 
 /**
  * @author <a href="mailto:adam at warski.org">Adam Warski</a>
@@ -21,56 +19,117 @@
 @Name("updateManager")
 @Scope(ScopeType.APPLICATION)
 public class UpdateManager {
+    private long lastUpdateStart;
+    private long lastUpdateEnd;
+
+    private AtomicBoolean updateInProgress;
+
+    private int updatesInterval;
+
+    private List<Exception> globalExceptions;
+    private Map<String, List<UpdateException>> feedUpdateExceptions;
+
     private ScheduledExecutorService executor;
 
     @Observer("org.jboss.blog.postBlogInit")
     public void register() {
+        updatesInterval = 900;
+
+        globalExceptions = new ArrayList<Exception>();
+        feedUpdateExceptions = new LinkedHashMap<String, List<UpdateException>>();
+
+        updateInProgress = new AtomicBoolean(false);
+
+        createAndStartExcutor();
+    }
+
+    public void restartUpdateThread() {
+        executor.shutdown();
+        createAndStartExcutor();
+    }
+
+    private void createAndStartExcutor() {
         executor = Executors.newScheduledThreadPool(1);
+        executor.scheduleAtFixedRate(new UpdateThread(), 10, updatesInterval, TimeUnit.SECONDS);
+    }
 
-        // TODO: add monitor and configurable intervals
+    public void addFeedUpdateException(String feedName, UpdateException exception) {
+        List<UpdateException> exceptions = feedUpdateExceptions.get(feedName);
+        if (exceptions == null) {
+            exceptions = new ArrayList<UpdateException>();
+            feedUpdateExceptions.put(feedName, exceptions);
+        }
 
-        executor.scheduleAtFixedRate(new UpdateRunnable(), 10, 900, TimeUnit.SECONDS);
+        exceptions.add(exception);
     }
 
-    private static class UpdateRunnable implements Runnable {
-        public void run() {
-            boolean createContexts = !Contexts.isEventContextActive() && !Contexts.isApplicationContextActive();
-            if (createContexts) {
-                Lifecycle.beginCall();
-            }
-            
-            try {
-                UserTransaction tx = null;
-                boolean txStarted = false;
-                try {
-                    tx = (UserTransaction) Component.getInstance("org.jboss.seam.transaction.transaction");
-                    if (tx.getStatus() != Status.STATUS_ACTIVE) {
-                        txStarted = true;
-                        tx.begin();
-                    }
+    public List<UpdateException> getFeedUpdateExceptionsForFeed(String feedName) {
+        return feedUpdateExceptions.get(feedName);
+    }
 
-                    ((EntityManager) Component.getInstance("entityManager")).joinTransaction();
-                    ((UpdateHandler) Component.getInstance("updateHandler")).update();
+    public List<String> getFeedUpdateExceptionNames() {
+        return new ArrayList<String>(feedUpdateExceptions.keySet());
+    }
 
-                    if (txStarted) {
-                        tx.commit();
-                    }
-                }  catch (Exception e) {
-                    try {
-                        if (txStarted) {
-                            tx.rollback();
-                        }
-                    } catch (SystemException e1) {
-                        Logging.getLog(UpdateManager.class).error("Exception when rolling back the transaction", e1);
-                    }
+    public void clearFeedsExceptions() {
+        feedUpdateExceptions.clear();
+    }
 
-                    e.printStackTrace();
-                }
-            } finally {
-                if (createContexts) {
-                    Lifecycle.endCall();
-                }
-            }
-        }
+    public List<Exception> getGlobalExceptions() {
+        return globalExceptions;
     }
+
+    public void clearGlobalExceptions() {
+        globalExceptions.clear();
+    }
+
+    public long getLastUpdateEnd() {
+        return lastUpdateEnd;
+    }
+
+    public void setLastUpdateEnd(long lastUpdateEnd) {
+        this.lastUpdateEnd = lastUpdateEnd;
+    }
+
+    public String getLastUpdateEndDate() {
+        return DateFormat.getDateTimeInstance().format(getLastUpdateEnd());
+    }
+
+    public long getLastUpdateStart() {
+        return lastUpdateStart;
+    }
+
+    public void setLastUpdateStart(long lastUpdateStart) {
+        this.lastUpdateStart = lastUpdateStart;
+    }
+
+    public String getLastUpdateStartDate() {
+        return DateFormat.getDateTimeInstance().format(getLastUpdateStart());
+    }
+
+    public int getUpdatesInterval() {
+        return updatesInterval;
+    }
+
+    public void setUpdatesInterval(int updatesInterval) {
+        this.updatesInterval = updatesInterval;
+    }
+
+    public AtomicBoolean getUpdateInProgress() {
+        return updateInProgress;
+    }
+
+    public String getNow() {
+        return DateFormat.getDateTimeInstance().format(System.currentTimeMillis());
+    }
+
+    public String getExceptionStackTrace(Exception e) {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        PrintWriter pw = new PrintWriter(baos);
+
+        e.printStackTrace(pw);
+
+        pw.flush();
+        return baos.toString();
+    }
 }

Added: trunk/src/action/org/jboss/blog/session/update/UpdateThread.java
===================================================================
--- trunk/src/action/org/jboss/blog/session/update/UpdateThread.java	                        (rev 0)
+++ trunk/src/action/org/jboss/blog/session/update/UpdateThread.java	2008-02-08 15:39:07 UTC (rev 208)
@@ -0,0 +1,72 @@
+package org.jboss.blog.session.update;
+
+import org.jboss.seam.contexts.Contexts;
+import org.jboss.seam.contexts.Lifecycle;
+import org.jboss.seam.Component;
+import org.jboss.seam.log.Logging;
+
+import javax.transaction.UserTransaction;
+import javax.transaction.Status;
+import javax.transaction.SystemException;
+import java.text.DateFormat;
+import java.util.Date;
+
+/**
+ * @author <a href="mailto:adam at warski.org">Adam Warski</a>
+ */
+public class UpdateThread implements Runnable {
+    public void run() {
+        boolean createContexts = !Contexts.isEventContextActive() && !Contexts.isApplicationContextActive();
+        if (createContexts) {
+            Lifecycle.beginCall();
+        }
+
+        try {
+            UserTransaction tx = null;
+            boolean txStarted = false;
+            try {
+                tx = (UserTransaction) Component.getInstance("org.jboss.seam.transaction.transaction");
+                if (tx.getStatus() != Status.STATUS_ACTIVE) {
+                    txStarted = true;
+                    tx.begin();
+                }
+
+                UpdateManager updateManager = (UpdateManager) Component.getInstance("updateManager");
+
+                try {
+                    if (!updateManager.getUpdateInProgress().getAndSet(true)) {
+                        updateManager.setLastUpdateStart(System.currentTimeMillis());
+
+                        ((UpdateHandler) Component.getInstance("updateHandler")).update();
+
+                        updateManager.setLastUpdateEnd(System.currentTimeMillis());
+                        updateManager.getUpdateInProgress().set(false);
+                    } else {
+                        throw new Exception("New update started before the last one finished, at " +
+                            DateFormat.getDateTimeInstance().format(new Date()) + "!");
+                    }
+                } catch (Exception e) {
+                    updateManager.getGlobalExceptions().add(e);
+                }
+
+                if (txStarted) {
+                    tx.commit();
+                }
+            } catch (Exception e) {
+                try {
+                    if (txStarted) {
+                        tx.rollback();
+                    }
+                } catch (SystemException e1) {
+                    Logging.getLog(UpdateManager.class).error("Exception when rolling back the transaction", e1);
+                }
+
+                e.printStackTrace();
+            }
+        } finally {
+            if (createContexts) {
+                Lifecycle.endCall();
+            }
+        }
+    }
+}

Modified: trunk/view/manage/index.xhtml
===================================================================
--- trunk/view/manage/index.xhtml	2008-02-08 11:53:06 UTC (rev 207)
+++ trunk/view/manage/index.xhtml	2008-02-08 15:39:07 UTC (rev 208)
@@ -22,6 +22,7 @@
                 <hr />
                 <dd><s:link value="Manage feed groups" view="/manage/group/group_list.xhtml" /></dd>
                 <dd><s:link value="Manage feed templates" view="/manage/template/template_list.xhtml" /></dd>
+                <dd><s:link value="Manage updates" view="/manage/update_manager.xhtml" /></dd>
                 <dt>Global posts operations:</dt>
                 <hr />
                 <dd><s:link value="Fix html in all posts" action="#{feedView.fixHtml}" /></dd>

Added: trunk/view/manage/update_manager.xhtml
===================================================================
--- trunk/view/manage/update_manager.xhtml	                        (rev 0)
+++ trunk/view/manage/update_manager.xhtml	2008-02-08 15:39:07 UTC (rev 208)
@@ -0,0 +1,96 @@
+<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<ui:composition xmlns="http://www.w3.org/1999/xhtml"
+                xmlns:s="http://jboss.com/products/seam/taglib"
+                xmlns:ui="http://java.sun.com/jsf/facelets"
+                xmlns:f="http://java.sun.com/jsf/core"
+                xmlns:h="http://java.sun.com/jsf/html"
+                xmlns:rich="http://richfaces.org/rich"
+                xmlns:a="http://richfaces.org/a4j"
+                template="../layout/template.xhtml">
+    <ui:define name="header">
+        Update manager
+    </ui:define>
+    <ui:define name="body">
+        <h:form>
+            <a:poll interval="5000" reRender="mainTable" />
+            <a:outputPanel id="mainTable">
+                <table cellspacing="5" class="deftable" width="75%">
+                    <tr>
+                        <td class="term" width="15%">Last page refresh:</td>
+                        <td class="def">#{updateManager.now}</td>
+                    </tr>
+                    <tr>
+                        <td class="term" width="15%">Last update start:</td>
+                        <td class="def">#{updateManager.lastUpdateStartDate}</td>
+                    </tr>
+                    <tr>
+                        <td class="term" width="15%">Last update end:</td>
+                        <td class="def">#{updateManager.lastUpdateEndDate}</td>
+                    </tr>
+                    <tr>
+                        <td class="term" width="15%">Update in progress:</td>
+                        <td class="def">#{updateManager.updateInProgress.get()}</td>
+                    </tr>
+                    <tr>
+                        <td class="term" width="15%">Global exceptions:</td>
+                        <td class="def">
+                            <s:fragment rendered="#{updateManager.globalExceptions.size() == 0}">
+                                None
+                            </s:fragment>
+                            <s:fragment rendered="#{updateManager.globalExceptions.size() > 0}">
+                                <ui:repeat var="exception" value="#{updateManager.globalExceptions}">
+                                    #{exception.message} <br />
+                                </ui:repeat>
+                            </s:fragment>
+                        </td>
+                    </tr>
+                    <tr>
+                        <td class="term" width="15%">Feed exceptions:</td>
+                        <td class="def">
+                            <s:fragment rendered="#{updateManager.feedUpdateExceptionNames.size() == 0}">
+                                None
+                            </s:fragment>
+                            <s:fragment rendered="#{updateManager.feedUpdateExceptionNames.size() > 0}">
+                                <ui:repeat var="feedName" value="#{updateManager.feedUpdateExceptionNames}">
+                                    <strong>#{feedName}</strong> <br />
+                                    <ui:repeat var="exception"
+                                               value="#{updateManager.getFeedUpdateExceptionsForFeed(feedName)}">
+                                        <rich:togglePanel id="stackTracePanel" initialState="nothing" switchType="client"
+                                                          stateOrder="nothing,stackTrace">
+                                            <f:facet name="nothing">
+                                                <s:fragment>
+                                                    #{exception.message}
+                                                </s:fragment>
+                                            </f:facet>
+                                            <f:facet name="stackTrace">
+                                                <s:fragment>
+                                                    #{exception.message} <br />
+                                                    #{updateManager.getExceptionStackTrace(exception)}
+                                                </s:fragment>
+                                            </f:facet>
+                                        </rich:togglePanel>
+                                        <rich:toggleControl for="stackTracePanel" value="Toggle stack trace"/>
+                                        <br />
+                                    </ui:repeat>
+                                    <br />
+                                </ui:repeat>
+                            </s:fragment>
+                        </td>
+                    </tr>
+                    <tr>
+                        <td class="term" width="15%">Actions:</td>
+                        <td class="def">
+                            <h:commandLink action="#{updateManager.clearGlobalExceptions}"
+                                           value="Clear global exceptions" /><br />
+                            <h:commandLink action="#{updateManager.clearFeedsExceptions}"
+                                           value="Clear feeds exceptions"/><br />
+                            <h:commandLink action="#{updateManager.restartUpdateThread}"
+                                           value="Restart the update thread"/><br />
+                        </td>
+                    </tr>
+                </table>
+            </a:outputPanel>
+        </h:form>
+    </ui:define>
+</ui:composition>




More information about the jboss-cvs-commits mailing list