001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.activemq.usage;
018    
019    import java.util.List;
020    import java.util.concurrent.CopyOnWriteArrayList;
021    import java.util.concurrent.ThreadPoolExecutor;
022    import org.apache.activemq.Service;
023    import org.apache.activemq.store.PersistenceAdapter;
024    import org.apache.activemq.store.kahadb.plist.PListStore;
025    
026    /**
027     * Holder for Usage instances for memory, store and temp files Main use case is
028     * manage memory usage.
029     * 
030     * @org.apache.xbean.XBean
031     * 
032     */
033    public class SystemUsage implements Service {
034    
035        private SystemUsage parent;
036        private String name;
037        private MemoryUsage memoryUsage;
038        private StoreUsage storeUsage;
039        private TempUsage tempUsage;
040        private ThreadPoolExecutor executor;
041    
042        /**
043         * True if someone called setSendFailIfNoSpace() on this particular usage
044         * manager
045         */
046        private boolean sendFailIfNoSpaceExplicitySet;
047        private boolean sendFailIfNoSpace;
048        private boolean sendFailIfNoSpaceAfterTimeoutExplicitySet;
049        private long sendFailIfNoSpaceAfterTimeout = 0;
050    
051        private final List<SystemUsage> children = new CopyOnWriteArrayList<SystemUsage>();
052    
053        public SystemUsage() {
054            this("default", null, null);
055        }
056    
057        public SystemUsage(String name, PersistenceAdapter adapter, PListStore tempStore) {
058            this.parent = null;
059            this.name = name;
060            this.memoryUsage = new MemoryUsage(name + ":memory");
061            this.storeUsage = new StoreUsage(name + ":store", adapter);
062            this.tempUsage = new TempUsage(name + ":temp", tempStore);
063            this.memoryUsage.setExecutor(getExecutor());
064            this.storeUsage.setExecutor(getExecutor());
065            this.tempUsage.setExecutor(getExecutor());
066        }
067    
068        public SystemUsage(SystemUsage parent, String name) {
069            this.parent = parent;
070            this.executor = parent.getExecutor();
071            this.name = name;
072            this.memoryUsage = new MemoryUsage(parent.memoryUsage, name + ":memory");
073            this.storeUsage = new StoreUsage(parent.storeUsage, name + ":store");
074            this.tempUsage = new TempUsage(parent.tempUsage, name + ":temp");
075            this.memoryUsage.setExecutor(getExecutor());
076            this.storeUsage.setExecutor(getExecutor());
077            this.tempUsage.setExecutor(getExecutor());
078        }
079    
080        public String getName() {
081            return name;
082        }
083    
084        /**
085         * @return the memoryUsage
086         */
087        public MemoryUsage getMemoryUsage() {
088            return this.memoryUsage;
089        }
090    
091        /**
092         * @return the storeUsage
093         */
094        public StoreUsage getStoreUsage() {
095            return this.storeUsage;
096        }
097    
098        /**
099         * @return the tempDiskUsage
100         */
101        public TempUsage getTempUsage() {
102            return this.tempUsage;
103        }
104    
105        @Override
106        public String toString() {
107            return "UsageManager(" + getName() + ")";
108        }
109    
110        public void start() {
111            if (parent != null) {
112                parent.addChild(this);
113            }
114            this.memoryUsage.start();
115            this.storeUsage.start();
116            this.tempUsage.start();
117        }
118    
119        public void stop() {
120            if (parent != null) {
121                parent.removeChild(this);
122            }
123            this.memoryUsage.stop();
124            this.storeUsage.stop();
125            this.tempUsage.stop();
126        }
127    
128        /**
129         * Sets whether or not a send() should fail if there is no space free. The
130         * default value is false which means to block the send() method until space
131         * becomes available
132         */
133        public void setSendFailIfNoSpace(boolean failProducerIfNoSpace) {
134            sendFailIfNoSpaceExplicitySet = true;
135            this.sendFailIfNoSpace = failProducerIfNoSpace;
136        }
137    
138        public boolean isSendFailIfNoSpace() {
139            if (sendFailIfNoSpaceExplicitySet || parent == null) {
140                return sendFailIfNoSpace;
141            } else {
142                return parent.isSendFailIfNoSpace();
143            }
144        }
145    
146        private void addChild(SystemUsage child) {
147            children.add(child);
148        }
149    
150        private void removeChild(SystemUsage child) {
151            children.remove(child);
152        }
153    
154        public SystemUsage getParent() {
155            return parent;
156        }
157    
158        public void setParent(SystemUsage parent) {
159            this.parent = parent;
160        }
161    
162        public boolean isSendFailIfNoSpaceExplicitySet() {
163            return sendFailIfNoSpaceExplicitySet;
164        }
165    
166        public void setSendFailIfNoSpaceExplicitySet(boolean sendFailIfNoSpaceExplicitySet) {
167            this.sendFailIfNoSpaceExplicitySet = sendFailIfNoSpaceExplicitySet;
168        }
169    
170        public long getSendFailIfNoSpaceAfterTimeout() {
171            if (sendFailIfNoSpaceAfterTimeoutExplicitySet || parent == null) {
172                return sendFailIfNoSpaceAfterTimeout;
173            } else {
174                return parent.getSendFailIfNoSpaceAfterTimeout();
175            }
176        }
177    
178        public void setSendFailIfNoSpaceAfterTimeout(long sendFailIfNoSpaceAfterTimeout) {
179            this.sendFailIfNoSpaceAfterTimeoutExplicitySet = true;
180            this.sendFailIfNoSpaceAfterTimeout = sendFailIfNoSpaceAfterTimeout;
181        }
182    
183        public void setName(String name) {
184            this.name = name;
185            this.memoryUsage.setName(name + ":memory");
186            this.storeUsage.setName(name + ":store");
187            this.tempUsage.setName(name + ":temp");
188        }
189    
190        public void setMemoryUsage(MemoryUsage memoryUsage) {
191            if (memoryUsage.getName() == null) {
192                memoryUsage.setName(this.memoryUsage.getName());
193            }
194            if (parent != null) {
195                memoryUsage.setParent(parent.memoryUsage);
196            }
197            this.memoryUsage = memoryUsage;
198            this.memoryUsage.setExecutor(getExecutor());
199        }
200    
201        public void setStoreUsage(StoreUsage storeUsage) {
202            if (storeUsage.getStore() == null) {
203                storeUsage.setStore(this.storeUsage.getStore());
204            }
205            if (storeUsage.getName() == null) {
206                storeUsage.setName(this.storeUsage.getName());
207            }
208            if (parent != null) {
209                storeUsage.setParent(parent.storeUsage);
210            }
211            this.storeUsage = storeUsage;
212            this.storeUsage.setExecutor(executor);
213    
214        }
215    
216        public void setTempUsage(TempUsage tempDiskUsage) {
217            if (tempDiskUsage.getStore() == null) {
218                tempDiskUsage.setStore(this.tempUsage.getStore());
219            }
220            if (tempDiskUsage.getName() == null) {
221                tempDiskUsage.setName(this.tempUsage.getName());
222            }
223            if (parent != null) {
224                tempDiskUsage.setParent(parent.tempUsage);
225            }
226            this.tempUsage = tempDiskUsage;
227            this.tempUsage.setExecutor(getExecutor());
228        }
229    
230        /**
231         * @return the executor
232         */
233        public ThreadPoolExecutor getExecutor() {
234            return this.executor;
235        }
236    
237        /**
238         * @param executor
239         *            the executor to set
240         */
241        public void setExecutor(ThreadPoolExecutor executor) {
242            this.executor = executor;
243            if (this.memoryUsage != null) {
244                this.memoryUsage.setExecutor(this.executor);
245            }
246            if (this.storeUsage != null) {
247                this.storeUsage.setExecutor(this.executor);
248            }
249            if (this.tempUsage != null) {
250                this.tempUsage.setExecutor(this.executor);
251            }
252        }
253    }