File Source: HitCountQueue.java
1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. The ASF licenses this file to You
4 * under the Apache License, Version 2.0 (the "License"); you may not
5 * use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License. For additional information regarding
15 * copyright in this work, please see the NOTICE file in the top level
16 * directory of this distribution.
17 */
18
19 package org.apache.roller.weblogger.business;
20
21 import java.util.ArrayList;
22 import java.util.Collections;
23 import java.util.List;
24 import org.apache.commons.logging.Log;
25 import org.apache.commons.logging.LogFactory;
26 import org.apache.roller.weblogger.business.runnable.ContinuousWorkerThread;
27 import org.apache.roller.weblogger.business.runnable.HitCountProcessingJob;
28 import org.apache.roller.weblogger.business.runnable.WorkerThread;
29 import org.apache.roller.weblogger.config.WebloggerConfig;
30 import org.apache.roller.weblogger.pojos.Weblog;
31
32
33 /**
34 * Queue's up incoming hit counts so that they can be recorded to the db in
35 * an asynchronous manner at give intervals.
36 *
37 * We also start up a single thread which runs continously to take the queued
38 * hit counts, tally them, and record them into the db.
39 *
40 * TODO: we may want to make this an interface that is pluggable if there is
41 * some indication that users want to override this implementation.
42 */
43 public class HitCountQueue {
44
/*
P/P * Method: org.apache.roller.weblogger.business.HitCountQueue__static_init
*
* Preconditions:
* org/apache/roller/weblogger/config/WebloggerConfig.config != null
* org/apache/roller/weblogger/config/WebloggerConfig.log != null
*
* Presumptions:
* org.apache.commons.logging.LogFactory:getLog(...)@45 != null
*
* Postconditions:
* instance == &new HitCountQueue(HitCountQueue__static_init#1)
* (soft) log != null
* new ContinuousWorkerThread(HitCountQueue#4) num objects == 1
* new HitCountProcessingJob(HitCountQueue#3) num objects == 1
* new HitCountQueue(HitCountQueue__static_init#1) num objects == 1
* instance.numWorkers == 1
* new ContinuousWorkerThread(HitCountQueue#4).id == &"HitCountQueueProcessor"
* new ContinuousWorkerThread(HitCountQueue#4).job == &new HitCountProcessingJob(HitCountQueue#3)
* new ContinuousWorkerThread(HitCountQueue#4).sleepTime in -2_147_483_000..4_294_967_000
* instance.sleepTime == new ContinuousWorkerThread(HitCountQueue#4).sleepTime
* ...
*/
45 private static Log log = LogFactory.getLog(HitCountQueue.class);
46
47 private static HitCountQueue instance = null;
48
49 private int numWorkers = 1;
50 private int sleepTime = 180000;
51 private WorkerThread worker = null;
52 private List queue = null;
53
54
55 static {
56 instance = new HitCountQueue();
57 }
58
59
60 // non-instantiable because we are a singleton
/*
P/P * Method: void org.apache.roller.weblogger.business.HitCountQueue()
*
* Preconditions:
* org/apache/roller/weblogger/config/WebloggerConfig.config != null
* org/apache/roller/weblogger/config/WebloggerConfig.log != null
* (soft) log != null
*
* Presumptions:
* java.lang.Integer:parseInt(...)@67 in -2_147_483..4_294_967
*
* Postconditions:
* this.numWorkers == 1
* new ContinuousWorkerThread(HitCountQueue#4) num objects == 1
* new HitCountProcessingJob(HitCountQueue#3) num objects == 1
* init'ed(this.queue)
* this.sleepTime in -2_147_483_000..4_294_967_000
* this.worker.sleepTime == this.sleepTime
* this.worker == &new ContinuousWorkerThread(HitCountQueue#4)
* this.worker.id == &"HitCountQueueProcessor"
* this.worker.job == &new HitCountProcessingJob(HitCountQueue#3)
*/
61 private HitCountQueue() {
62
63 String sleep = WebloggerConfig.getProperty("hitcount.queue.sleepTime", "180");
64
65 try {
66 // multiply by 1000 because we expect input in seconds
67 this.sleepTime = Integer.parseInt(sleep) * 1000;
68 } catch(NumberFormatException nfe) {
69 log.warn("Invalid sleep time ["+sleep+"], using default");
70 }
71
72 // create the hits queue
73 this.queue = Collections.synchronizedList(new ArrayList());
74
75 // start up a worker to process the hits at intervals
76 HitCountProcessingJob job = new HitCountProcessingJob();
77 worker = new ContinuousWorkerThread("HitCountQueueProcessor", job, this.sleepTime);
78 worker.start();
79 }
80
81
82 public static HitCountQueue getInstance() {
/*
P/P * Method: HitCountQueue getInstance()
*
* Preconditions:
* init'ed(instance)
*
* Postconditions:
* return_value == instance
* init'ed(return_value)
*/
83 return instance;
84 }
85
86
87 public void processHit(Weblog weblog, String url, String referrer) {
88
89 // if the weblog isn't null then just drop it's handle in the queue
90 // each entry in the queue is a weblog handle and indicates a single hit
/*
P/P * Method: void processHit(Weblog, String, String)
*
* Preconditions:
* (soft) this.queue != null
*
* Test Vectors:
* weblog: Addr_Set{null}, Inverse{null}
*/
91 if(weblog != null) {
92 this.queue.add(weblog.getHandle());
93 }
94 }
95
96
97 public List getHits() {
/*
P/P * Method: List getHits()
*
* Preconditions:
* init'ed(this.queue)
*
* Postconditions:
* return_value == &new ArrayList(getHits#1)
* new ArrayList(getHits#1) num objects == 1
*/
98 return new ArrayList(this.queue);
99 }
100
101
102 /**
103 * Reset the queued hits.
104 */
105 public synchronized void resetHits() {
/*
P/P * Method: void resetHits()
*
* Postconditions:
* init'ed(this.queue)
*/
106 this.queue = Collections.synchronizedList(new ArrayList());
107 }
108
109
110 /**
111 * clean up.
112 */
113 public void shutdown() {
114
/*
P/P * Method: void shutdown()
*
* Preconditions:
* init'ed(this.worker)
* (soft) log != null
*
* Test Vectors:
* this.worker: Addr_Set{null}, Inverse{null}
*/
115 if(this.worker != null) {
116 log.info("stopping worker "+this.worker.getName());
117 worker.interrupt();
118 }
119
120 }
121
122 }
SofCheck Inspector Build Version : 2.18479
| HitCountQueue.java |
2009-Jan-02 14:25:24 |
| HitCountQueue.class |
2009-Sep-04 03:12:30 |