001package org.apache.commons.jcs3.engine.control.event; 002 003/* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022import java.io.IOException; 023import java.util.concurrent.ExecutorService; 024import java.util.concurrent.atomic.AtomicBoolean; 025 026import org.apache.commons.jcs3.engine.control.event.behavior.IElementEvent; 027import org.apache.commons.jcs3.engine.control.event.behavior.IElementEventHandler; 028import org.apache.commons.jcs3.engine.control.event.behavior.IElementEventQueue; 029import org.apache.commons.jcs3.log.Log; 030import org.apache.commons.jcs3.log.LogManager; 031import org.apache.commons.jcs3.utils.threadpool.PoolConfiguration; 032import org.apache.commons.jcs3.utils.threadpool.PoolConfiguration.WhenBlockedPolicy; 033import org.apache.commons.jcs3.utils.threadpool.ThreadPoolManager; 034 035/** 036 * An event queue is used to propagate ordered cache events to one and only one target listener. 037 */ 038public class ElementEventQueue 039 implements IElementEventQueue 040{ 041 private static final String THREAD_PREFIX = "JCS-ElementEventQueue-"; 042 043 /** The logger */ 044 private static final Log log = LogManager.getLog( ElementEventQueue.class ); 045 046 /** shutdown or not */ 047 private final AtomicBoolean destroyed = new AtomicBoolean(false); 048 049 /** The worker thread pool. */ 050 private final ExecutorService queueProcessor; 051 052 /** 053 * Constructor for the ElementEventQueue object 054 */ 055 public ElementEventQueue() 056 { 057 queueProcessor = ThreadPoolManager.getInstance().createPool( 058 new PoolConfiguration(false, 0, 1, 1, 0, WhenBlockedPolicy.RUN, 1), THREAD_PREFIX); 059 060 log.debug( "Constructed: {0}", this ); 061 } 062 063 /** 064 * Dispose queue 065 */ 066 @Override 067 public void dispose() 068 { 069 if (destroyed.compareAndSet(false, true)) 070 { 071 // Pool will be shut down by the ThreadPoolManager 072 // queueProcessor.shutdownNow(); 073 log.info( "Element event queue destroyed: {0}", this ); 074 } 075 } 076 077 /** 078 * Adds an ElementEvent to be handled 079 * @param hand The IElementEventHandler 080 * @param event The IElementEventHandler IElementEvent event 081 * @throws IOException 082 */ 083 @Override 084 public <T> void addElementEvent( final IElementEventHandler hand, final IElementEvent<T> event ) 085 throws IOException 086 { 087 088 log.debug("Adding Event Handler to QUEUE, !destroyed = {0}", !destroyed.get()); 089 090 if (destroyed.get()) 091 { 092 log.warn("Event submitted to disposed element event queue {0}", event); 093 } 094 else 095 { 096 queueProcessor.execute(() -> hand.handleElementEvent(event)); 097 } 098 } 099 100 // /////////////////////////// Inner classes ///////////////////////////// 101 102 /** 103 * Retries before declaring failure. 104 * @deprecated No longer used 105 */ 106 @Deprecated 107 protected abstract class AbstractElementEventRunner 108 implements Runnable 109 { 110 /** 111 * Main processing method for the AbstractElementEvent object 112 */ 113 @Override 114 public void run() 115 { 116 try 117 { 118 doRun(); 119 // happy and done. 120 } 121 catch ( final IOException e ) 122 { 123 // Too bad. The handler has problems. 124 log.warn( "Giving up element event handling {0}", ElementEventQueue.this, e ); 125 } 126 } 127 128 /** 129 * This will do the work or trigger the work to be done. 130 * <p> 131 * @throws IOException 132 */ 133 protected abstract void doRun() 134 throws IOException; 135 } 136}