forked from Qortal/qortal
Add periodic system-tray pop-up if Windows Time service not running
This commit is contained in:
parent
9c1ca8de04
commit
82910b6524
@ -1,5 +1,6 @@
|
||||
package org.qora.controller;
|
||||
|
||||
import java.awt.TrayIcon.MessageType;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.security.SecureRandom;
|
||||
@ -15,6 +16,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Random;
|
||||
import java.util.Scanner;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
@ -33,6 +35,7 @@ import org.qora.data.block.BlockSummaryData;
|
||||
import org.qora.data.network.PeerData;
|
||||
import org.qora.data.transaction.ArbitraryTransactionData;
|
||||
import org.qora.data.transaction.ArbitraryTransactionData.DataType;
|
||||
import org.qora.globalization.Translator;
|
||||
import org.qora.data.transaction.TransactionData;
|
||||
import org.qora.gui.Gui;
|
||||
import org.qora.gui.SysTray;
|
||||
@ -87,6 +90,7 @@ public class Controller extends Thread {
|
||||
private static final String repositoryUrlTemplate = "jdbc:hsqldb:file:%s/blockchain;create=true;hsqldb.full_log_replay=true";
|
||||
private static final long ARBITRARY_REQUEST_TIMEOUT = 5 * 1000; // ms
|
||||
private static final long REPOSITORY_BACKUP_PERIOD = 123 * 60 * 1000; // ms
|
||||
private static final long NTP_NAG_PERIOD = 5 * 60 * 1000; // ms
|
||||
|
||||
private static volatile boolean isStopping = false;
|
||||
private static BlockGenerator blockGenerator = null;
|
||||
@ -97,6 +101,7 @@ public class Controller extends Thread {
|
||||
private final long buildTimestamp; // seconds
|
||||
|
||||
private long repositoryBackupTimestamp = startTime + REPOSITORY_BACKUP_PERIOD;
|
||||
private long ntpNagTimestamp = startTime + NTP_NAG_PERIOD;
|
||||
|
||||
/**
|
||||
* Map of recent requests for ARBITRARY transaction data payloads.
|
||||
@ -307,6 +312,12 @@ public class Controller extends Thread {
|
||||
repositoryBackupTimestamp += REPOSITORY_BACKUP_PERIOD;
|
||||
RepositoryManager.backup(true);
|
||||
}
|
||||
|
||||
// Potentially nag end-user about NTP
|
||||
if (System.currentTimeMillis() >= ntpNagTimestamp) {
|
||||
ntpNagTimestamp += NTP_NAG_PERIOD;
|
||||
ntpNag();
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
// Fall-through to exit
|
||||
@ -383,6 +394,48 @@ public class Controller extends Thread {
|
||||
}
|
||||
}
|
||||
|
||||
/** Nag Windows users that don't have many/any peers and not using Windows' auto time sync. */
|
||||
private void ntpNag() {
|
||||
// Only for Windows users
|
||||
if (!System.getProperty("os.name").toLowerCase().contains("win"))
|
||||
return;
|
||||
|
||||
// Suffering from lack of peers?
|
||||
final int numberOfPeers = Network.getInstance().getUniqueHandshakedPeers().size();
|
||||
if (numberOfPeers > 0)
|
||||
return;
|
||||
|
||||
// Do we actually know any peers to connect to?
|
||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||
final int numberOfKnownPeers = repository.getNetworkRepository().getAllPeers().size();
|
||||
if (numberOfKnownPeers == 0)
|
||||
return;
|
||||
} catch (DataException e) {
|
||||
// Not important
|
||||
return;
|
||||
}
|
||||
|
||||
String[] detectCmd = new String[] { "net", "start" };
|
||||
try {
|
||||
Process process = new ProcessBuilder(Arrays.asList(detectCmd)).start();
|
||||
try (InputStream in = process.getInputStream(); Scanner scanner = new Scanner(in, "UTF8")) {
|
||||
scanner.useDelimiter("\\A");
|
||||
String output = scanner.hasNext() ? scanner.next() : "";
|
||||
boolean isRunning = output.contains("Windows Time");
|
||||
if (isRunning)
|
||||
return;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// Not important
|
||||
return;
|
||||
}
|
||||
|
||||
// Time to nag
|
||||
String caption = Translator.INSTANCE.translate("SysTray", "NTP_NAG_CAPTION");
|
||||
String text = Translator.INSTANCE.translate("SysTray", "NTP_NAG_TEXT");
|
||||
SysTray.getInstance().showMessage(caption, text, MessageType.INFO);
|
||||
}
|
||||
|
||||
public void updateSysTray() {
|
||||
final int numberOfPeers = Network.getInstance().getUniqueHandshakedPeers().size();
|
||||
|
||||
|
3
src/main/resources/i18n/SysTray_en.properties
Normal file
3
src/main/resources/i18n/SysTray_en.properties
Normal file
@ -0,0 +1,3 @@
|
||||
# Nagging about lack of NTP time sync
|
||||
NTP_NAG_CAPTION=No connections?
|
||||
NTP_NAG_TEXT=Please enable Windows automatic time synchronization
|
3
src/main/resources/i18n/SysTray_zh.properties
Normal file
3
src/main/resources/i18n/SysTray_zh.properties
Normal file
@ -0,0 +1,3 @@
|
||||
# Nagging about lack of NTP time sync
|
||||
NTP_NAG_CAPTION=No connections?
|
||||
NTP_NAG_TEXT=Please enable Windows automatic time synchronization
|
49
src/test/java/org/qora/test/WindowsTimeServiceTests.java
Normal file
49
src/test/java/org/qora/test/WindowsTimeServiceTests.java
Normal file
@ -0,0 +1,49 @@
|
||||
package org.qora.test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.Scanner;
|
||||
|
||||
public class WindowsTimeServiceTests {
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println("Detecting Windows Time Service...");
|
||||
String[] detectCmd = new String[] { "net", "start" };
|
||||
try {
|
||||
Process process = new ProcessBuilder(Arrays.asList(detectCmd)).start();
|
||||
try (InputStream in = process.getInputStream(); Scanner scanner = new Scanner(in, "UTF8")) {
|
||||
scanner.useDelimiter("\\A");
|
||||
String output = scanner.hasNext() ? scanner.next() : "";
|
||||
boolean isRunning = output.contains("Windows Time");
|
||||
|
||||
System.out.println(String.format("Windows Time Service running: %s", isRunning ? "yes" : "no"));
|
||||
}
|
||||
int exitStatus = process.waitFor();
|
||||
System.out.println(String.format("Exit status: %d", exitStatus));
|
||||
} catch (IOException | InterruptedException e) {
|
||||
System.err.println(String.format("Failed to detect Windows Time Service: %s", e.getMessage()));
|
||||
}
|
||||
|
||||
System.out.println("Starting Windows Time Service...");
|
||||
String[] startCmd = new String[] { "net", "start", "w32time" };
|
||||
try {
|
||||
Process process = new ProcessBuilder(Arrays.asList(startCmd)).start();
|
||||
int exitStatus = process.waitFor();
|
||||
System.out.println(String.format("Exit status: %d", exitStatus));
|
||||
} catch (IOException | InterruptedException e) {
|
||||
System.err.println(String.format("Failed to start Windows Time Service: %s", e.getMessage()));
|
||||
}
|
||||
|
||||
System.out.println("Force syncing Windows Time Service...");
|
||||
String[] resyncCmd = new String[] { "w32tm", "/resync" };
|
||||
try {
|
||||
Process process = new ProcessBuilder(Arrays.asList(resyncCmd)).start();
|
||||
int exitStatus = process.waitFor();
|
||||
System.out.println(String.format("Exit status: %d", exitStatus));
|
||||
} catch (IOException | InterruptedException e) {
|
||||
System.err.println(String.format("Failed to force sync Windows Time Service: %s", e.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user