/**
* This does the actual checkpoint.
* @return
*/
public boolean doCheckpoint() {
CountDownLatch latch = null;
boolean fullCheckpoint;
synchronized(this) {
latch = nextCheckpointCountDownLatch;
nextCheckpointCountDownLatch = new CountDownLatch(1);
fullCheckpoint = this.fullCheckPoint;
this.fullCheckPoint=false;
}
try {
log.debug("Checkpoint started.");
RecordLocation newMark = null;
ArrayList futureTasks = new ArrayList(queues.size()+topics.size());
//
// We do many partial checkpoints (fullCheckpoint==false) to move topic messages
// to long term store as soon as possible.
//
// We want to avoid doing that for queue messages since removes the come in the same
// checkpoint cycle will nullify the previous message add. Therefore, we only
// checkpoint queues on the fullCheckpoint cycles.
//
if( fullCheckpoint ) {
Iterator iterator = queues.values().iterator();
while (iterator.hasNext()) {
try {
final QuickJournalMessageStore ms = (QuickJournalMessageStore) iterator.next();
FutureTask task = new FutureTask(new Callable() {
public Object call() throws Exception {
return ms.checkpoint();
}});
futureTasks.add(task);
checkpointExecutor.execute(task);
}
catch (Exception e) {
log.error("Failed to checkpoint a message store: " + e, e);
}
}
}
Iterator iterator = topics.values().iterator();
while (iterator.hasNext()) {
try {
final QuickJournalTopicMessageStore ms = (QuickJournalTopicMessageStore) iterator.next();
FutureTask task = new FutureTask(new Callable() {
public Object call() throws Exception {
return ms.checkpoint();
}});
futureTasks.add(task);
checkpointExecutor.execute(task);
}
catch (Exception e) {
log.error("Failed to checkpoint a message store: " + e, e);
}
}
try {
for (Iterator iter = futureTasks.iterator(); iter.hasNext();) {
FutureTask ft = (FutureTask) iter.next();
RecordLocation mark = (RecordLocation) ft.get();
// We only set a newMark on full checkpoints.
if( fullCheckpoint ) {
if (mark != null && (newMark == null || newMark.compareTo(mark) < 0)) {
newMark = mark;
}
}
}
} catch (Throwable e) {
log.error("Failed to checkpoint a message store: " + e, e);
}
if( fullCheckpoint ) {
try {
if (newMark != null) {
log.debug("Marking journal at: " + newMark);
journal.setMark(newMark, true);
}
}
catch (Exception e) {
log.error("Failed to mark the Journal: " + e, e);
}
if (longTermPersistence instanceof JDBCPersistenceAdapter) {
// We may be check pointing more often than the checkpointInterval if under high use
// But we don't want to clean up the db that often.
long now = System.currentTimeMillis();
if( now > lastCleanup+checkpointInterval ) {
lastCleanup = now;
((JDBCPersistenceAdapter) longTermPersistence).cleanup();
}
}
}
log.debug("Checkpoint done.");
}
finally {
latch.countDown();
}
synchronized(this) {
return this.fullCheckPoint;
}