mirror of https://github.com/apache/activemq.git
[AMQ-6441] add option to specify the hard limits on a usage such that spurious values from the file system can be overridden. this closes #202 thanks William Crowell for the patch with test
This commit is contained in:
parent
41bec0d658
commit
8a28c06555
|
@ -111,9 +111,9 @@ import org.apache.activemq.thread.TaskRunnerFactory;
|
|||
import org.apache.activemq.transport.TransportFactorySupport;
|
||||
import org.apache.activemq.transport.TransportServer;
|
||||
import org.apache.activemq.transport.vm.VMTransportFactory;
|
||||
import org.apache.activemq.usage.PercentLimitUsage;
|
||||
import org.apache.activemq.usage.StoreUsage;
|
||||
import org.apache.activemq.usage.SystemUsage;
|
||||
import org.apache.activemq.usage.Usage;
|
||||
import org.apache.activemq.util.BrokerSupport;
|
||||
import org.apache.activemq.util.DefaultIOExceptionHandler;
|
||||
import org.apache.activemq.util.IOExceptionHandler;
|
||||
|
@ -2048,18 +2048,19 @@ public class BrokerService implements Service {
|
|||
}
|
||||
}
|
||||
|
||||
protected void checkUsageLimit(File dir, Usage<?> storeUsage, int percentLimit) throws ConfigurationException {
|
||||
protected void checkUsageLimit(File dir, PercentLimitUsage<?> storeUsage, int percentLimit) throws ConfigurationException {
|
||||
if (dir != null) {
|
||||
dir = StoreUtil.findParentDirectory(dir);
|
||||
String storeName = storeUsage instanceof StoreUsage ? "Store" : "Temporary Store";
|
||||
long storeLimit = storeUsage.getLimit();
|
||||
long storeCurrent = storeUsage.getUsage();
|
||||
long totalSpace = dir.getTotalSpace();
|
||||
if (totalSpace < 0) {
|
||||
totalSpace = Long.MAX_VALUE;
|
||||
LOG.info("Total space was negative. Setting to " + totalSpace);
|
||||
long totalSpace = storeUsage.getTotal() > 0 ? storeUsage.getTotal() : dir.getTotalSpace();
|
||||
long totalUsableSpace = (storeUsage.getTotal() > 0 ? storeUsage.getTotal() : dir.getUsableSpace()) + storeCurrent;
|
||||
if (totalUsableSpace < 0 || totalSpace < 0) {
|
||||
final String message = "File system space reported by: " + dir + " was negative, possibly a huge file system, set a sane usage.total to provide some guidance";
|
||||
LOG.error(message);
|
||||
throw new ConfigurationException(message);
|
||||
}
|
||||
long totalUsableSpace = dir.getUsableSpace() + storeCurrent;
|
||||
//compute byte value of the percent limit
|
||||
long bytePercentLimit = totalSpace * percentLimit / 100;
|
||||
int oneMeg = 1024 * 1024;
|
||||
|
@ -2069,6 +2070,7 @@ public class BrokerService implements Service {
|
|||
//Changes in partition size (total space) as well as changes in usable space should
|
||||
//be detected here
|
||||
if (diskUsageCheckRegrowThreshold > -1 && percentLimit > 0
|
||||
&& storeUsage.getTotal() == 0
|
||||
&& storeLimit < bytePercentLimit && storeLimit < totalUsableSpace){
|
||||
|
||||
// set the limit to be bytePercentLimit or usableSpace if
|
||||
|
|
|
@ -17,9 +17,14 @@
|
|||
package org.apache.activemq.usage;
|
||||
|
||||
|
||||
import org.apache.activemq.util.StoreUtil;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public abstract class PercentLimitUsage <T extends Usage> extends Usage<T> {
|
||||
|
||||
protected int percentLimit = 0;
|
||||
protected long total = 0;
|
||||
|
||||
/**
|
||||
* @param parent
|
||||
|
@ -49,5 +54,27 @@ public abstract class PercentLimitUsage <T extends Usage> extends Usage<T> {
|
|||
}
|
||||
}
|
||||
|
||||
public void setTotal(long max) {
|
||||
this.total = max;
|
||||
}
|
||||
|
||||
public long getTotal() {
|
||||
return total;
|
||||
}
|
||||
|
||||
|
||||
protected void percentLimitFromFile(File directory) {
|
||||
if (percentLimit > 0) {
|
||||
if (total > 0) {
|
||||
this.setLimit(total * percentLimit / 100);
|
||||
} else if (directory != null) {
|
||||
File dir = StoreUtil.findParentDirectory(directory);
|
||||
if (dir != null) {
|
||||
this.setLimit(dir.getTotalSpace() * percentLimit / 100);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void updateLimitBasedOnPercent();
|
||||
}
|
||||
|
|
|
@ -16,10 +16,7 @@
|
|||
*/
|
||||
package org.apache.activemq.usage;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.apache.activemq.store.PersistenceAdapter;
|
||||
import org.apache.activemq.util.StoreUtil;
|
||||
|
||||
/**
|
||||
* Used to keep track of how much of something is being used so that a
|
||||
|
@ -96,14 +93,7 @@ public class StoreUsage extends PercentLimitUsage<StoreUsage> {
|
|||
protected void updateLimitBasedOnPercent() {
|
||||
usageLock.writeLock().lock();
|
||||
try {
|
||||
|
||||
if (percentLimit > 0 && store != null) {
|
||||
File dir = StoreUtil.findParentDirectory(store.getDirectory());
|
||||
|
||||
if (dir != null) {
|
||||
this.setLimit(dir.getTotalSpace() * percentLimit / 100);
|
||||
}
|
||||
}
|
||||
percentLimitFromFile(store != null ? store.getDirectory() : null);
|
||||
} finally {
|
||||
usageLock.writeLock().unlock();
|
||||
}
|
||||
|
|
|
@ -17,10 +17,7 @@
|
|||
package org.apache.activemq.usage;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.apache.activemq.store.PListStore;
|
||||
import org.apache.activemq.util.StoreUtil;
|
||||
|
||||
/**
|
||||
* Used to keep track of how much of something is being used so that a
|
||||
|
@ -89,15 +86,10 @@ public class TempUsage extends PercentLimitUsage<TempUsage> {
|
|||
protected void updateLimitBasedOnPercent() {
|
||||
usageLock.writeLock().lock();
|
||||
try {
|
||||
if (percentLimit > 0 && store != null) {
|
||||
File dir = StoreUtil.findParentDirectory(store.getDirectory());
|
||||
|
||||
if (dir != null) {
|
||||
this.setLimit(dir.getTotalSpace() * percentLimit / 100);
|
||||
}
|
||||
}
|
||||
percentLimitFromFile(store != null ? store.getDirectory() : null);
|
||||
} finally {
|
||||
usageLock.writeLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -103,20 +103,29 @@ public class BrokerServiceTest extends TestCase {
|
|||
PersistenceAdapter persistenceAdapter = service.createPersistenceAdapter();
|
||||
persistenceAdapter.setDirectory(dataDirectory);
|
||||
service.setPersistenceAdapter(persistenceAdapter);
|
||||
service.setUseJmx(false);
|
||||
|
||||
mockStatic(StoreUtil.class);
|
||||
|
||||
// Return a simulated handle to a very large file system that will return a negative totalSpace.
|
||||
when(StoreUtil.findParentDirectory(dataDirectory)).thenReturn(new LargeFile(dataDirectory.getParentFile(), "KahaDB"));
|
||||
when(StoreUtil.findParentDirectory(tmpDataDirectory)).thenReturn(tmpDataDirectory);
|
||||
when(StoreUtil.findParentDirectory(tmpDataDirectory)).thenReturn(tmpDataDirectory.getParentFile());
|
||||
|
||||
service.setPersistent(false);
|
||||
service.setUseJmx(false);
|
||||
TransportConnector connector = service.addConnector("tcp://localhost:0");
|
||||
service.start();
|
||||
try {
|
||||
service.start();
|
||||
fail("Expect error on negative totalspace");
|
||||
} catch (Exception expected) {
|
||||
// verify message
|
||||
assertTrue(expected.getLocalizedMessage().contains("negative"));
|
||||
}
|
||||
finally {
|
||||
service.stop();
|
||||
}
|
||||
|
||||
service.removeConnector(connector);
|
||||
connector.stop();
|
||||
// configure a 2x value for the fs limit so it can start
|
||||
service.getSystemUsage().getStoreUsage().setTotal( service.getSystemUsage().getStoreUsage().getLimit() * 2);
|
||||
|
||||
service.start(true);
|
||||
service.stop();
|
||||
|
||||
verifyStatic();
|
||||
|
|
|
@ -22,4 +22,9 @@ public class LargeFile extends File {
|
|||
public long getTotalSpace() {
|
||||
return Long.MAX_VALUE + 4193L;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getUsableSpace() {
|
||||
return getTotalSpace() - 1024L;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue