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