/**
* Copyright 2011 multibit.org
*
* Licensed under the MIT license (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://opensource.org/licenses/mit-license.php
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.multibit.viewsystem.swing;
import org.multibit.controller.Controller;
import org.multibit.controller.bitcoin.BitcoinController;
import org.multibit.file.WalletSaveException;
import org.multibit.message.Message;
import org.multibit.message.MessageManager;
import org.multibit.model.bitcoin.WalletData;
import org.multibit.store.WalletVersionException;
import org.multibit.viewsystem.swing.action.ExitAction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Iterator;
import java.util.List;
import java.util.TimerTask;
/**
* TimerTask to regularly check the 'health' of MultiBit.
* It detects whether wallet files have been changed by some external process and to save dirty files.
* It checks the ping times of the peers to see if they are up.
*
* @see java.util.Timer
* @see java.util.TimerTask
*/
public class HealthCheckTimerTask extends TimerTask {
public static final int INITIAL_DELAY = 30000; // milliseconds
public static final int DEFAULT_REPEAT_RATE = 90000; // milliseconds
private static Logger log = LoggerFactory.getLogger(HealthCheckTimerTask.class);
private final Controller controller;
private final BitcoinController bitcoinController;
private boolean isRunning = false;
/**
* Constructs the object, sets the string to be output in function run()
*
* @param bitcoinController Controller giving access to Bitcoin object model
*/
public HealthCheckTimerTask(BitcoinController bitcoinController) {
this.bitcoinController = bitcoinController;
this.controller = bitcoinController;
}
/**
* When the timer executes, this code is run.
*/
@Override
public void run() {
isRunning = true;
try {
log.debug("Start of HealthCheckTimerTask");
// See if the ExitAction is running - if so let that persist dirty wallets
if (ExitAction.isRunning()) {
log.debug("Skipping HealthCheckTimerTask#run as the ExitAction is already running");
} else {
log.debug("Checking if wallets are dirty . . .");
List<WalletData> perWalletModelDataList = bitcoinController.getModel().getPerWalletModelDataList();
if (perWalletModelDataList != null) {
Iterator<WalletData> iterator = perWalletModelDataList.iterator();
while (iterator.hasNext()) {
WalletData loopModelData = iterator.next();
if (bitcoinController.getFileHandler() != null) {
// See if they are dirty - write out if so.
if (loopModelData.isDirty()) {
log.debug("Saving dirty wallet '" + loopModelData.getWalletFilename() + "'...");
try {
bitcoinController.getFileHandler().savePerWalletModelData(loopModelData, false);
log.debug("... done.");
} catch (WalletSaveException | WalletVersionException e) {
String message = controller.getLocaliser().getString(
"createNewWalletAction.walletCouldNotBeCreated",
new Object[]{loopModelData.getWalletFilename(), e.getMessage()});
log.error(message);
MessageManager.INSTANCE.addMessage(new Message(message));
}
}
}
}
}
log.debug("End of HealthCheckTimerTask");
}
} catch (java.util.ConcurrentModificationException cme) {
log.error("The list of open wallets was changed whilst files were being written.");
} finally {
isRunning = false;
}
}
public boolean isRunning() {
return isRunning;
}
}