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 */
017package org.apache.activemq.usage;
018
019import java.util.List;
020import java.util.concurrent.CopyOnWriteArrayList;
021import java.util.concurrent.ThreadPoolExecutor;
022import org.apache.activemq.Service;
023import org.apache.activemq.store.PersistenceAdapter;
024import 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 */
033public 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}