public void run() throws ConnectionLostException, InterruptedException{
LSN actual = stage.getBabuDB().getState();
LSN until = (stage.missing == null) ? new LSN(actual.getViewId() + 1,0L) :
stage.missing.end;
MasterClient master = slaveView.getSynchronizationPartner(until);
// make the request and get the result synchronously
Logging.logMessage(Logging.LEVEL_INFO, stage, "Loading DB since %s from %s.",
actual.toString(), master.getDefaultServerAddress().toString());
ClientResponseFuture<DBFileMetaDataSet, DBFileMetaDatas> rp = master.load(actual);
DBFileMetaDataSet result = null;
try {
result = rp.get();
} catch (ErrorCodeException e) {
// connection is lost
throw new ConnectionLostException(e.getMessage(), e.getCode());
} catch (Exception e) {
// failure on transmission --> retry
throw new ConnectionLostException(e.getMessage(), ErrorCode.UNKNOWN);
}
// switch log file by triggering a manual checkpoint,
// if the response was empty
if (result.size() == 0) {
try {
stage.lastOnView.set(stage.getBabuDB().checkpoint());
} catch (BabuDBException e) {
// system failure on switching the lock file --> retry
Logging.logError(Logging.LEVEL_WARN, this, e);
return;
}
Logging.logMessage(Logging.LEVEL_DEBUG, this,
"Logfile switched at LSN %s.", stage.getBabuDB().getState().toString());
finished(false);
return;
}
// backup the old dbs
stage.getBabuDB().stopBabuDB();
try {
fileIO.backupFiles();
} catch (IOException e) {
// file backup failed --> retry
Logging.logError(Logging.LEVEL_WARN, this, e);
if (stage.isInterrupted()) {
try {
stage.getBabuDB().startBabuDB();
} catch (BabuDBException e1) {
Logging.logError(Logging.LEVEL_ERROR, this, e1);
}
}
return;
}
// #chunks >= #files
final AtomicInteger openChunks = new AtomicInteger(result.size());
// request the chunks
LSN lsn = null;
for (DBFileMetaData fileData : result) {
// validate the informations
final String fileName = fileData.file;
String parentName = new File(fileName).getParentFile().getName();
if (LSMDatabase.isSnapshotFilename(parentName)) {
if (lsn == null)
lsn = LSMDatabase.getSnapshotLSNbyFilename(parentName);
else if (!lsn.equals(LSMDatabase.
getSnapshotLSNbyFilename(parentName))){
Logging.logMessage(Logging.LEVEL_WARN, this,
"Indexfiles had ambiguous LSNs: %s",
"LOAD will be retried.");
return;
}
}
long fileSize = fileData.size;
// if we got an empty file, that cannot be right, so try again
if (!(fileSize > 0L)) return;
assert (maxChunkSize > 0L) :
"Empty chunks are not allowed: " + fileName;
synchronized (openChunks) {
if (openChunks.get() != -1)
openChunks.addAndGet((int) (fileSize / maxChunkSize));
}
// calculate chunks, request them and add them to the list
long begin = 0L;
for (long end = maxChunkSize; end < (fileSize+maxChunkSize); end += maxChunkSize) {
// request the chunk
final long pos1 = begin;
final long size = (end > fileSize) ? fileSize : end;
final ClientResponseFuture<ReusableBuffer, ErrorCodeResponse> chunkRp =
master.chunk(fileName, pos1, size);
begin = end;
chunkRp.registerListener(new ClientResponseAvailableListener<ReusableBuffer>() {
@Override
public void responseAvailable(ReusableBuffer buffer) {