mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-20 14:49:53 +01:00
KeyRotatorImpl looks a *lot* like DatabaseCleanerImpl.
This commit is contained in:
@@ -19,9 +19,9 @@ interface DatabaseCleaner {
|
|||||||
/**
|
/**
|
||||||
* Checks how much free storage space is available to the database, and
|
* Checks how much free storage space is available to the database, and
|
||||||
* if necessary expires old messages until the free space is at least
|
* if necessary expires old messages until the free space is at least
|
||||||
* DatabaseConstants.MIN_FREE_SPACE. While the free space is less than
|
* DatabaseConstants.MIN_FREE_SPACE. If the free space is less than
|
||||||
* DatabaseConstants.CRITICAL_FREE_SPACE, operations that attempt to
|
* DatabaseConstants.CRITICAL_FREE_SPACE and there are no more messages
|
||||||
* store messages in the database will block.
|
* to expire, an Error will be thrown.
|
||||||
*/
|
*/
|
||||||
void checkFreeSpaceAndClean() throws DbException;
|
void checkFreeSpaceAndClean() throws DbException;
|
||||||
|
|
||||||
|
|||||||
@@ -33,12 +33,10 @@ class DatabaseCleanerImpl extends TimerTask implements DatabaseCleaner {
|
|||||||
callback.checkFreeSpaceAndClean();
|
callback.checkFreeSpaceAndClean();
|
||||||
}
|
}
|
||||||
} catch(DbException e) {
|
} catch(DbException e) {
|
||||||
if(LOG.isLoggable(Level.WARNING))
|
if(LOG.isLoggable(Level.WARNING)) LOG.warning(e.toString());
|
||||||
LOG.warning(e.toString());
|
|
||||||
throw new Error(e); // Kill the application
|
throw new Error(e); // Kill the application
|
||||||
} catch(RuntimeException e) {
|
} catch(RuntimeException e) {
|
||||||
if(LOG.isLoggable(Level.WARNING))
|
if(LOG.isLoggable(Level.WARNING)) LOG.warning(e.toString());
|
||||||
LOG.warning(e.toString());
|
|
||||||
throw new Error(e); // Kill the application
|
throw new Error(e); // Kill the application
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1548,8 +1548,7 @@ DatabaseCleaner.Callback {
|
|||||||
if(freeSpace < CRITICAL_FREE_SPACE && !expired) {
|
if(freeSpace < CRITICAL_FREE_SPACE && !expired) {
|
||||||
// FIXME: Work out what to do here - the amount of free space
|
// FIXME: Work out what to do here - the amount of free space
|
||||||
// is critically low and there are no messages left to expire
|
// is critically low and there are no messages left to expire
|
||||||
System.err.println("Disk space is critical - shutting down");
|
throw new Error("Disk space is critical");
|
||||||
System.exit(1);
|
|
||||||
}
|
}
|
||||||
Thread.yield();
|
Thread.yield();
|
||||||
freeSpace = db.getFreeSpace();
|
freeSpace = db.getFreeSpace();
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ interface DatabaseConstants {
|
|||||||
/**
|
/**
|
||||||
* The minimum amount of space in bytes that must be kept free on the device
|
* The minimum amount of space in bytes that must be kept free on the device
|
||||||
* where the database is stored. If less than this much space is free and
|
* where the database is stored. If less than this much space is free and
|
||||||
* there are no more messages to expire, the program will shut down.
|
* there are no more messages to expire, an Error will be thrown.
|
||||||
*/
|
*/
|
||||||
static final long CRITICAL_FREE_SPACE = 100 * 1024 * 1024; // 100 MiB
|
static final long CRITICAL_FREE_SPACE = 100 * 1024 * 1024; // 100 MiB
|
||||||
|
|
||||||
|
|||||||
24
components/net/sf/briar/db/KeyRotator.java
Normal file
24
components/net/sf/briar/db/KeyRotator.java
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
package net.sf.briar.db;
|
||||||
|
|
||||||
|
import net.sf.briar.api.db.DbException;
|
||||||
|
|
||||||
|
interface KeyRotator {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts a new thread to rotate keys periodically. The rotator will pause
|
||||||
|
* for the given number of milliseconds between rotations.
|
||||||
|
*/
|
||||||
|
void startRotating(Callback callback, long msBetweenRotations);
|
||||||
|
|
||||||
|
/** Tells the rotator thread to exit. */
|
||||||
|
void stopRotating();
|
||||||
|
|
||||||
|
interface Callback {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rotates keys, replacing and destroying any keys that have passed the
|
||||||
|
* ends of their respective retention periods.
|
||||||
|
*/
|
||||||
|
void rotateKeys() throws DbException;
|
||||||
|
}
|
||||||
|
}
|
||||||
41
components/net/sf/briar/db/KeyRotatorImpl.java
Normal file
41
components/net/sf/briar/db/KeyRotatorImpl.java
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
package net.sf.briar.db;
|
||||||
|
|
||||||
|
import java.util.Timer;
|
||||||
|
import java.util.TimerTask;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import net.sf.briar.api.db.DbException;
|
||||||
|
|
||||||
|
class KeyRotatorImpl extends TimerTask implements KeyRotator {
|
||||||
|
|
||||||
|
private static final Logger LOG =
|
||||||
|
Logger.getLogger(KeyRotatorImpl.class.getName());
|
||||||
|
|
||||||
|
private volatile Callback callback = null;
|
||||||
|
private volatile Timer timer = null;
|
||||||
|
|
||||||
|
public void startRotating(Callback callback, long msBetweenRotations) {
|
||||||
|
this.callback = callback;
|
||||||
|
timer = new Timer();
|
||||||
|
timer.scheduleAtFixedRate(this, 0L, msBetweenRotations);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stopRotating() {
|
||||||
|
if(timer == null) throw new IllegalStateException();
|
||||||
|
timer.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
if(callback == null) throw new IllegalStateException();
|
||||||
|
try {
|
||||||
|
callback.rotateKeys();
|
||||||
|
} catch(DbException e) {
|
||||||
|
if(LOG.isLoggable(Level.WARNING)) LOG.warning(e.toString());
|
||||||
|
throw new Error(e); // Kill the application
|
||||||
|
} catch(RuntimeException e) {
|
||||||
|
if(LOG.isLoggable(Level.WARNING)) LOG.warning(e.toString());
|
||||||
|
throw new Error(e); // Kill the application
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
53
test/net/sf/briar/db/KeyRotatorImplTest.java
Normal file
53
test/net/sf/briar/db/KeyRotatorImplTest.java
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
package net.sf.briar.db;
|
||||||
|
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import net.sf.briar.BriarTestCase;
|
||||||
|
import net.sf.briar.api.db.DbException;
|
||||||
|
import net.sf.briar.db.KeyRotator.Callback;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class KeyRotatorImplTest extends BriarTestCase {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCleanerRunsPeriodically() throws Exception {
|
||||||
|
final CountDownLatch latch = new CountDownLatch(5);
|
||||||
|
Callback callback = new Callback() {
|
||||||
|
|
||||||
|
public void rotateKeys() throws DbException {
|
||||||
|
latch.countDown();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
KeyRotatorImpl cleaner = new KeyRotatorImpl();
|
||||||
|
// Start the rotator
|
||||||
|
cleaner.startRotating(callback, 10L);
|
||||||
|
// The keys should be rotated five times (allow 5 secs for system load)
|
||||||
|
assertTrue(latch.await(5, TimeUnit.SECONDS));
|
||||||
|
// Stop the rotator
|
||||||
|
cleaner.stopRotating();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStoppingCleanerWakesItUp() throws Exception {
|
||||||
|
final CountDownLatch latch = new CountDownLatch(1);
|
||||||
|
Callback callback = new Callback() {
|
||||||
|
|
||||||
|
public void rotateKeys() throws DbException {
|
||||||
|
latch.countDown();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
KeyRotatorImpl cleaner = new KeyRotatorImpl();
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
// Start the rotator
|
||||||
|
cleaner.startRotating(callback, 10L * 1000L);
|
||||||
|
// The keys should be rotated once at startup
|
||||||
|
assertTrue(latch.await(5, TimeUnit.SECONDS));
|
||||||
|
// Stop the rotator (it should be waiting between rotations)
|
||||||
|
cleaner.stopRotating();
|
||||||
|
long end = System.currentTimeMillis();
|
||||||
|
// Check that much less than 10 seconds expired
|
||||||
|
assertTrue(end - start < 10L * 1000L);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user