KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > roller > presentation > pings > PingQueueProcessor


1 /*
2  * Copyright (c) 2005
3  * Anil R. Gangolli. All rights reserved.
4  *
5  * Distributed with the Roller Weblogger Project under the terms of the Roller Software
6  * License
7  */

8
9 package org.roller.presentation.pings;
10
11 import org.apache.commons.logging.Log;
12 import org.apache.commons.logging.LogFactory;
13 import org.roller.RollerException;
14 import org.roller.config.PingConfig;
15 import org.roller.model.PingQueueManager;
16 import org.roller.model.RollerFactory;
17 import org.roller.pojos.PingQueueEntryData;
18 import org.roller.pojos.PingTargetData;
19 import org.roller.pojos.WebsiteData;
20 import org.roller.presentation.RollerContext;
21
22 import java.util.Iterator JavaDoc;
23 import java.util.List JavaDoc;
24
25 /**
26  * Ping Queue Processor. Singleton encapsulating logic for processing the weblog update ping queue.
27  */

28 public class PingQueueProcessor
29 {
30     private static final Log logger = LogFactory.getLog(PingQueueProcessor.class);
31
32     private static PingQueueProcessor theInstance;
33
34
35     private RollerContext rollerContext;
36     private PingQueueManager pingQueueMgr;
37
38     public static PingQueueProcessor getInstance()
39     {
40         return theInstance;
41     }
42
43     private PingQueueProcessor(RollerContext rc) throws RollerException
44     {
45         rollerContext = rc;
46         pingQueueMgr = RollerFactory.getRoller().getPingQueueManager();
47     }
48
49     /**
50      * Initialize the singleton. This is called during <code>RollerContext</code> initialization.
51      *
52      * @param rc the Roller context
53      * @throws RollerException
54      */

55     public static synchronized void init(RollerContext rc) throws RollerException
56     {
57         if (theInstance != null)
58         {
59             logger.warn("Ignoring duplicate initialization of PingQueueProcessor!");
60             return;
61         }
62         theInstance = new PingQueueProcessor(rc);
63         if (logger.isDebugEnabled()) logger.debug("Ping queue processor initialized.");
64     }
65
66     /**
67      * Process the ping queue. Performs one pass through the ping queue, processing every entry once. On ping failure
68      * an entry is requeued for processing on subsequent passes until the configured maximum number of attempts is
69      * reached.
70      */

71     public synchronized void processQueue()
72     {
73         if (PingConfig.getSuspendPingProcessing()) {
74             logger.info("Ping processing has been suspended. Skipping current round of ping queue processing.");
75             return;
76         }
77
78         String JavaDoc absoluteContextUrl = rollerContext.getAbsoluteContextUrl();
79         if (absoluteContextUrl == null)
80         {
81             logger.warn("WARNING: Skipping current ping queue processing round because we cannot yet determine the site's absolute context url.");
82             return;
83         }
84
85         // TODO: Group by ping target and ping all sites for that target?
86
// We're currently not taking advantage of grouping by ping target site and then sending
87
// all of the pings for that target at once. If it becomes an efficiency issue, we should do
88
// that.
89

90         try
91         {
92             if (logger.isDebugEnabled()) logger.debug("Started processing ping queue.");
93             // Get all of the entries
94
List JavaDoc entries = pingQueueMgr.getAllQueueEntries();
95
96             // Process each entry
97
for (Iterator JavaDoc i = entries.iterator(); i.hasNext();)
98             {
99                 PingQueueEntryData pingQueueEntry = (PingQueueEntryData) i.next();
100                 processQueueEntry(absoluteContextUrl, pingQueueEntry);
101             }
102             if (logger.isDebugEnabled()) logger.debug("Finished processing ping queue.");
103         }
104         catch (Exception JavaDoc ex)
105         {
106             logger.error("Unexpected exception processing ping queue! Aborting this pass of ping queue processing.", ex);
107         }
108     }
109
110     /**
111      * Process an individual ping queue entry.
112      *
113      * @param absoluteContextUrl absolute context URL of the Roller site
114      * @param pingQueueEntry the ping queue entry
115      * @throws RollerException only if there are problems processing the queue. Exceptions from sending pings are
116      * handled, not thrown.
117      */

118     private void processQueueEntry(String JavaDoc absoluteContextUrl, PingQueueEntryData pingQueueEntry)
119         throws RollerException
120     {
121         if (logger.isDebugEnabled()) logger.debug("Processing ping queue entry: " + pingQueueEntry);
122
123         PingTargetData pingTarget = pingQueueEntry.getPingTarget();
124         WebsiteData website = pingQueueEntry.getWebsite();
125         boolean pingSucceeded = false;
126         if (PingConfig.getLogPingsOnly())
127         {
128             // Just log the ping and pretend it succeeded.
129
logger.info("Logging simulated ping for ping queue entry " + pingQueueEntry);
130             pingSucceeded = true;
131         }
132         else
133         {
134             // Actually process the ping
135
try
136             {
137                 // Send the ping
138
WeblogUpdatePinger.sendPing(absoluteContextUrl, pingTarget, website);
139                 // Consider successful ping transmission if we didn't get an exception. We don't care here
140
// about the result of the ping if it was transmitted.
141
pingSucceeded = true;
142             }
143             catch (Exception JavaDoc ex)
144             {
145                 // Handle the ping error, either removing or requeuing the ping queue entry.
146
handlePingError(pingQueueEntry, ex);
147             }
148         }
149         // We do this outside of the previous try-catch because we don't want an exception here to be considered a ping error.
150
if (pingSucceeded)
151         {
152             if (logger.isDebugEnabled()) logger.debug("Processed ping: " + pingQueueEntry);
153             pingQueueMgr.removeQueueEntry(pingQueueEntry);
154         }
155     }
156
157     /**
158      * Handle any ping error.
159      *
160      * @param pingQueueEntry the ping queue entry
161      * @param ex the exception that occurred on the ping attempt
162      * @throws RollerException
163      */

164     private void handlePingError(PingQueueEntryData pingQueueEntry, Exception JavaDoc ex)
165         throws RollerException
166     {
167         if ((pingQueueEntry.incrementAttempts() < PingConfig.getMaxPingAttempts()) &&
168             WeblogUpdatePinger.shouldRetry(ex))
169         {
170             // We have attempts remaining, and it looks like we should retry,
171
// so requeue the entry for processing on subsequent rounds
172
logger.warn("Error on ping attempt (" + pingQueueEntry.getAttempts() + ") for " + pingQueueEntry +
173                 ": [" + ex.getMessage() + "]. Will re-queue for later attempts.");
174             if (logger.isDebugEnabled()) logger.debug("Error on last ping attempt was: ", ex);
175             pingQueueMgr.storeQueueEntry(pingQueueEntry);
176         }
177         else
178         {
179             // Remove the entry
180
logger.warn("Error on ping attempt (" + pingQueueEntry.getAttempts() + ") for " + pingQueueEntry +
181                 ": [" + ex.getMessage() + "]. Entry will be REMOVED from ping queue.");
182             if (logger.isDebugEnabled()) logger.debug("Error on last ping attempt was: ", ex);
183             pingQueueMgr.removeQueueEntry(pingQueueEntry);
184             // TODO: mark ping target invalid?
185
}
186     }
187
188
189 }
190
Popular Tags