| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. The ASF licenses this file to You |
| * under the Apache License, Version 2.0 (the "License"); you may not |
| * use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. For additional information regarding |
| * copyright in this work, please see the NOTICE file in the top level |
| * directory of this distribution. |
| */ |
| |
| package org.apache.roller.weblogger.business; |
| |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.List; |
| import org.apache.commons.logging.Log; |
| import org.apache.commons.logging.LogFactory; |
| import org.apache.roller.util.RollerConstants; |
| import org.apache.roller.weblogger.business.runnable.ContinuousWorkerThread; |
| import org.apache.roller.weblogger.business.runnable.HitCountProcessingJob; |
| import org.apache.roller.weblogger.business.runnable.WorkerThread; |
| import org.apache.roller.weblogger.config.WebloggerConfig; |
| import org.apache.roller.weblogger.pojos.Weblog; |
| |
| |
| /** |
| * Queue's up incoming hit counts so that they can be recorded to the db in |
| * an asynchronous manner at give intervals. |
| * |
| * We also start up a single thread which runs continously to take the queued |
| * hit counts, tally them, and record them into the db. |
| * |
| * TODO: we may want to make this an interface that is pluggable if there is |
| * some indication that users want to override this implementation. |
| */ |
| public final class HitCountQueue { |
| |
| private static Log log = LogFactory.getLog(HitCountQueue.class); |
| |
| private static HitCountQueue instance = null; |
| |
| private WorkerThread worker = null; |
| private List<String> queue = null; |
| |
| |
| static { |
| instance = new HitCountQueue(); |
| } |
| |
| |
| // non-instantiable because we are a singleton |
| private HitCountQueue() { |
| int sleepTime = 3 * RollerConstants.MIN_IN_MS; |
| String sleep = WebloggerConfig.getProperty("hitcount.queue.sleepTime", "180"); |
| |
| try { |
| // convert input in seconds to ms |
| sleepTime = Integer.parseInt(sleep) * RollerConstants.SEC_IN_MS; |
| } catch(NumberFormatException nfe) { |
| log.warn("Invalid sleep time ["+sleep+"], using default"); |
| } |
| |
| // create the hits queue |
| this.queue = Collections.synchronizedList(new ArrayList<String>()); |
| |
| // start up a worker to process the hits at intervals |
| HitCountProcessingJob job = new HitCountProcessingJob(); |
| worker = new ContinuousWorkerThread("HitCountQueueProcessor", job, sleepTime); |
| worker.start(); |
| } |
| |
| |
| public static HitCountQueue getInstance() { |
| return instance; |
| } |
| |
| |
| public void processHit(Weblog weblog) { |
| |
| // if the weblog isn't null then just drop its handle in the queue |
| // each entry in the queue is a weblog handle and indicates a single hit |
| if(weblog != null) { |
| this.queue.add(weblog.getHandle()); |
| } |
| } |
| |
| |
| public List<String> getHits() { |
| return new ArrayList<String>(this.queue); |
| } |
| |
| |
| /** |
| * Reset the queued hits. |
| */ |
| public synchronized void resetHits() { |
| this.queue = Collections.synchronizedList(new ArrayList<String>()); |
| } |
| |
| |
| /** |
| * clean up. |
| */ |
| public void shutdown() { |
| |
| if(this.worker != null) { |
| log.info("stopping worker "+this.worker.getName()); |
| worker.interrupt(); |
| try { |
| worker.join(RollerConstants.GRACEFUL_SHUTDOWN_WAIT_IN_MILLISECONDS); |
| } catch (InterruptedException e) { |
| log.debug(e.getMessage(), e); |
| } |
| } |
| |
| } |
| |
| } |