startup report added
This commit is contained in:
parent
1c1709f018
commit
d5fdc9bcee
@ -5,6 +5,7 @@ import vassistent.model.AppState;
|
||||
import vassistent.service.*;
|
||||
import vassistent.util.AppConfigValidator;
|
||||
import vassistent.util.ConfigLoader;
|
||||
import vassistent.util.Logger;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.Properties;
|
||||
@ -99,9 +100,13 @@ public class ApplicationInitializer {
|
||||
|
||||
context.setProcessManagerService(new ProcessManagerService(config));
|
||||
|
||||
Logger.info("PROCESS", "Starting configured external processes");
|
||||
|
||||
ProcessManagerService.StartupReport startupReport =
|
||||
context.getProcessManagerService().startProcesses();
|
||||
|
||||
logProcessStartupReport(startupReport);
|
||||
|
||||
if (startupReport.hasFailures()) {
|
||||
context.getProcessManagerService().shutdown();
|
||||
throw new IllegalStateException(startupReport.buildFailureMessage());
|
||||
@ -144,4 +149,51 @@ public class ApplicationInitializer {
|
||||
|
||||
return trimmed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs startup status for all process components and the global startup result.
|
||||
*
|
||||
* @param startupReport startup status report from {@link ProcessManagerService}
|
||||
*/
|
||||
private static void logProcessStartupReport(
|
||||
ProcessManagerService.StartupReport startupReport
|
||||
) {
|
||||
logProcessStartStatus(startupReport.getMqttSimulator());
|
||||
logProcessStartStatus(startupReport.getUnreal());
|
||||
|
||||
if (startupReport.hasFailures()) {
|
||||
Logger.error("PROCESS", startupReport.buildFailureMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
Logger.info("PROCESS", "External process startup completed successfully");
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs one startup component status from the process startup report.
|
||||
*
|
||||
* @param status startup status for one managed process component
|
||||
*/
|
||||
private static void logProcessStartStatus(
|
||||
ProcessManagerService.ProcessStartStatus status
|
||||
) {
|
||||
String component = status.getComponentName();
|
||||
|
||||
if (!status.isEnabled()) {
|
||||
Logger.info("PROCESS", component + " startup skipped (disabled)");
|
||||
return;
|
||||
}
|
||||
|
||||
if (status.isStarted()) {
|
||||
Logger.info("PROCESS", component + " startup succeeded");
|
||||
return;
|
||||
}
|
||||
|
||||
String error = status.getErrorMessage();
|
||||
if (error == null || error.isBlank()) {
|
||||
Logger.error("PROCESS", component + " startup failed");
|
||||
} else {
|
||||
Logger.error("PROCESS", component + " startup failed: " + error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,6 +8,8 @@ import vassistent.util.Logger;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
/**
|
||||
* Updates the dashboard chart and level bar whenever application state changes.
|
||||
@ -16,6 +18,7 @@ public class DashboardController {
|
||||
|
||||
private final StatisticsService statisticsService;
|
||||
private final DashboardView dashboardView;
|
||||
private final ExecutorService dashboardUpdateExecutor;
|
||||
|
||||
/**
|
||||
* Creates a dashboard controller and subscribes to app state changes.
|
||||
@ -31,6 +34,12 @@ public class DashboardController {
|
||||
) {
|
||||
this.statisticsService = statisticsService;
|
||||
this.dashboardView = dashboardView;
|
||||
this.dashboardUpdateExecutor =
|
||||
Executors.newSingleThreadExecutor(runnable -> {
|
||||
Thread thread = new Thread(runnable, "dashboard-update");
|
||||
thread.setDaemon(true);
|
||||
return thread;
|
||||
});
|
||||
|
||||
appState.addListener(this::onStateChanged);
|
||||
}
|
||||
@ -41,7 +50,7 @@ public class DashboardController {
|
||||
* @param state latest application state
|
||||
*/
|
||||
private void onStateChanged(AppState state) {
|
||||
|
||||
dashboardUpdateExecutor.execute(() -> {
|
||||
List<RatioPoint> points =
|
||||
statisticsService.getLastNAverages(120);
|
||||
|
||||
@ -57,5 +66,6 @@ public class DashboardController {
|
||||
dashboardView.updateProblemLevel(ratio);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,7 +1,11 @@
|
||||
package vassistent.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
@ -9,12 +13,13 @@ import java.util.function.Consumer;
|
||||
*/
|
||||
public class AppState {
|
||||
|
||||
private long dataVersion = 0;
|
||||
private boolean mqttConnected;
|
||||
private ProblemLevel problemLevel = ProblemLevel.NONE;
|
||||
private final AtomicLong dataVersion = new AtomicLong(0);
|
||||
private final AtomicBoolean mqttConnected = new AtomicBoolean(false);
|
||||
private final AtomicReference<ProblemLevel> problemLevel =
|
||||
new AtomicReference<>(ProblemLevel.NONE);
|
||||
|
||||
private final List<Consumer<AppState>> listeners =
|
||||
new ArrayList<>();
|
||||
new CopyOnWriteArrayList<>();
|
||||
|
||||
/**
|
||||
* Registers a state listener that is notified on relevant updates.
|
||||
@ -22,14 +27,19 @@ public class AppState {
|
||||
* @param listener callback receiving the current state instance
|
||||
*/
|
||||
public void addListener(Consumer<AppState> listener) {
|
||||
listeners.add(listener);
|
||||
listeners.add(
|
||||
Objects.requireNonNull(
|
||||
listener,
|
||||
"listener must not be null"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies all currently registered listeners.
|
||||
*/
|
||||
private void notifyListeners() {
|
||||
new ArrayList<>(listeners).forEach(l -> l.accept(this));
|
||||
listeners.forEach(listener -> listener.accept(this));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -38,7 +48,7 @@ public class AppState {
|
||||
* @return current problem level
|
||||
*/
|
||||
public ProblemLevel getProblemLevel() {
|
||||
return problemLevel;
|
||||
return problemLevel.get();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -47,8 +57,14 @@ public class AppState {
|
||||
* @param problemLevel new problem level
|
||||
*/
|
||||
public void setProblemLevel(ProblemLevel problemLevel) {
|
||||
this.problemLevel = problemLevel;
|
||||
dataVersion++;
|
||||
this.problemLevel.set(
|
||||
Objects.requireNonNull(
|
||||
problemLevel,
|
||||
"problemLevel must not be null"
|
||||
)
|
||||
);
|
||||
|
||||
dataVersion.incrementAndGet();
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
@ -58,7 +74,7 @@ public class AppState {
|
||||
* @return {@code true} if connected, otherwise {@code false}
|
||||
*/
|
||||
public boolean isMqttConnected() {
|
||||
return mqttConnected;
|
||||
return mqttConnected.get();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -67,8 +83,11 @@ public class AppState {
|
||||
* @param mqttConnected new MQTT connection flag
|
||||
*/
|
||||
public void setMqttConnected(boolean mqttConnected) {
|
||||
if (this.mqttConnected != mqttConnected) {
|
||||
this.mqttConnected = mqttConnected;
|
||||
boolean previous =
|
||||
this.mqttConnected.getAndSet(mqttConnected);
|
||||
|
||||
if (previous != mqttConnected) {
|
||||
dataVersion.incrementAndGet();
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user