long time0 = System.currentTimeMillis();
Object[] componentList = componentMap.values().toArray();
for (int i = 0; i < componentList.length; i++) {
ComponentInfo cInfo = (ComponentInfo) componentList[i];
MobileComponentID cid =
new MobileComponentIDClientImpl(cInfo.getInstanceName(),
cInfo.getInstanceHandle());
cid.freezeComponent(getGSH());
}
long time1 = System.currentTimeMillis();
logger.info("Freeze request: " + (time1 - time0));
// wait till all components are frozen
if (outstandingFrozenComps < componentList.length) {
synchronized(this) {
try {
wait();
} catch (InterruptedException ie) {
logger.severe("Exception when waiting for component to be frozen",
ie);
throw new NonstandardException("Exception when waiting for component to be frozen",
ie);
}
// set the number of outstanding frozen components to 0
outstandingFrozenComps = 0;
// check if the above call was successful
if (checkpointStatus == AppCoordinatorCallback.EXCEPTION)
throw new NonstandardException("Exception while freezing components");
}
}
long time2 = System.currentTimeMillis();
logger.info("Time for components to freeze: " + (time2 - time1));
// send request to store the state of the components
MasterStorageService mss = (MasterStorageService)
URLToReference.createReference(masterStorageServiceURL,
MasterStorageService.class.getName());
for (int i = 0; i < componentList.length; i++) {
String individualStorageServiceURL = mss.getIndividualStorageServiceLocation();
ComponentInfo cInfo = (ComponentInfo) componentList[i];
MobileComponentID cid =
new MobileComponentIDClientImpl(cInfo.getInstanceName(),
cInfo.getInstanceHandle());
cid.appendStateToCheckpoint(individualStorageServiceURL, getGSH());
}
// wait till all components have stored their states
if (numComponentsStateStored < componentList.length) {
synchronized(this) {
try {
wait();
} catch (InterruptedException ie) {
logger.severe("Exception when waiting for components to store states",
ie);
throw new NonstandardException("Exception when waiting for components to store states",
ie);
}
// set the number of outstanding frozen components to 0
numComponentsStateStored = 0;
// check if the above call was successful
if (checkpointStatus == AppCoordinatorCallback.EXCEPTION)
throw new NonstandardException("Exception while storing component state");
}
}
long time3 = System.currentTimeMillis();
logger.info("Storing checkpoints: " + (time3 - time2));
// Atomically update locations of checkpoints in the database
Hashtable oldCheckpointMap = checkpointMap;
checkpointMap = tempCheckpointMap;
tempCheckpointMap = new Hashtable();
if (dburl != null) {
// Commit component information into database
Connection conn = null;
try {
// connect to the database
conn = DriverManager.getConnection(dburl,
dbuser,
dbpasswd);
// set autocommit to false so that all of the following is atomic
conn.setAutoCommit(false);
} catch (Exception e) {
logger.severe("Error while connecting to database", e);
throw new NonstandardException("Error while connecting to database", e);
}
try {
// for every component, update the distributed_checkpoint_table
for (int i = 0; i < componentList.length; i++) {
ComponentInfo cInfo = (ComponentInfo) componentList[i];
CheckpointInfo cpInfo =
(CheckpointInfo) checkpointMap.get(cInfo.getInstanceName());
// update the entry into the table
// have to delete + insert since MySQL 4.0.x doesn't support
// ON DUPLICATE KEY UPDATE
String sqlStmt0 =
"delete from distributed_checkpoint_table where " +
"instance_handle = '" + cInfo.getInstanceHandle() + "';";
PreparedStatement stmt0 = conn.prepareStatement(sqlStmt0);
stmt0.executeUpdate();
String sqlStmt1 =
"insert into distributed_checkpoint_table" +
"(instance_handle, application_id, " +
"individual_storage_service_url, " +
"storage_id) values (" +
"'" + cInfo.getInstanceHandle() + "', " +
"'" + applicationID + "', " +
"'" + cpInfo.getStorageServiceURL() + "', " +
"'" + cpInfo.getStorageID() + "');";
PreparedStatement stmt1 = conn.prepareStatement(sqlStmt1);
stmt1.executeUpdate();
}
// commit all inserts
conn.commit();
// clean up
conn.close();
} catch (Exception e) {
logger.severe("Error while trying to store checkpoint locations into database: " +
" Trying to rollback", e);
// try to rollback
try {
conn.rollback();
} catch (Exception re) {
logger.severe("Error while trying to store checkpoint locations into database: " +
" Rollback failed", re);
throw new NonstandardException("Error while trying to store checkpoint locations " +
"into database: Rollback failed", re);
}
throw new NonstandardException("Error while trying to store checkpoint locations " +
"into database: Rollback successful", e);
}
}
// delete old checkpoints
Object[] cpList = oldCheckpointMap.values().toArray();
for (int i = 0; i < cpList.length; i++) {
CheckpointInfo cpInfo = (CheckpointInfo) cpList[i];
IndividualStorageService iss = (IndividualStorageService)
URLToReference.createReference(cpInfo.getStorageServiceURL(),
IndividualStorageService.class.getName());
iss.deleteState(cpInfo.getStorageID());
}
long time4 = System.currentTimeMillis();
logger.info("Committing checkpoints: " + (time4 - time3));
// send a notification to components that checkpointing is complete
for (int i = 0; i < componentList.length; i++) {
ComponentInfo cInfo = (ComponentInfo) componentList[i];
MobileComponentID cid =
new MobileComponentIDClientImpl(cInfo.getInstanceName(),
cInfo.getInstanceHandle());
cid.unfreezeComponent();
}
long time5 = System.currentTimeMillis();
logger.info("Unfreezing components: " + (time5 - time4));
}