Skip to content

Commit 841cc40

Browse files
committed
fix: implement state management and error handling in MonitorService
1 parent 79bd807 commit 841cc40

File tree

1 file changed

+50
-53
lines changed

1 file changed

+50
-53
lines changed

src/main/java/org/springframework/samples/petclinic/errors/MonitorService.java

Lines changed: 50 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -7,48 +7,68 @@
77
import org.springframework.context.SmartLifecycle;
88
import org.springframework.stereotype.Component;
99

10+
import java.util.InvalidPropertiesFormatException;
11+
import java.util.concurrent.atomic.AtomicInteger;
12+
1013
@Component
1114
public class MonitorService implements SmartLifecycle {
1215

13-
public enum ServiceState {
14-
STOPPED,
16+
public enum SystemStatus {
1517
STARTING,
1618
RUNNING,
1719
STOPPING,
20+
STOPPED,
1821
ERROR
1922
}
2023

21-
private ServiceState currentState = ServiceState.STOPPED;
24+
private volatile SystemStatus currentStatus = SystemStatus.STOPPED;
25+
private volatile boolean running = false;
2226
private Thread backgroundThread;
23-
private static final int MAX_RETRIES = 3;
24-
private static final long RETRY_DELAY_MS = 1000;
27+
private final AtomicInteger retryCount = new AtomicInteger(0);
28+
private final int MAX_RETRIES = 3;
29+
private final long RETRY_DELAY_MS = 1000;
30+
private volatile Exception lastError;
2531

2632
@Autowired
2733
private OpenTelemetry openTelemetry;
2834

2935
@Override
3036
public void start() {
3137
var otelTracer = openTelemetry.getTracer("MonitorService");
32-
currentState = ServiceState.STARTING;
33-
38+
currentStatus = SystemStatus.STARTING;
39+
running = true;
40+
retryCount.set(0);
41+
lastError = null;
42+
3443
backgroundThread = new Thread(() -> {
35-
currentState = ServiceState.RUNNING;
36-
while (currentState == ServiceState.RUNNING) {
44+
while (running) {
3745
try {
3846
Thread.sleep(5000);
3947
} catch (InterruptedException e) {
4048
Thread.currentThread().interrupt();
4149
break;
4250
}
43-
51+
4452
Span span = otelTracer.spanBuilder("monitor").startSpan();
4553
try {
46-
System.out.println("Background service is running...");
47-
monitorWithRetry();
54+
currentStatus = SystemStatus.RUNNING;
55+
monitor();
56+
retryCount.set(0);
4857
} catch (Exception e) {
58+
lastError = e;
4959
span.recordException(e);
5060
span.setStatus(StatusCode.ERROR);
51-
currentState = ServiceState.ERROR;
61+
currentStatus = SystemStatus.ERROR;
62+
63+
if (retryCount.incrementAndGet() <= MAX_RETRIES) {
64+
try {
65+
Thread.sleep(RETRY_DELAY_MS * retryCount.get());
66+
continue;
67+
} catch (InterruptedException ie) {
68+
Thread.currentThread().interrupt();
69+
break;
70+
}
71+
}
5272
} finally {
5373
span.end();
5474
}
@@ -59,63 +79,40 @@ public void start() {
5979
System.out.println("Background service started.");
6080
}
6181

62-
private void monitorWithRetry() {
63-
int attempts = 0;
64-
Exception lastException = null;
65-
66-
while (attempts < MAX_RETRIES) {
67-
try {
68-
monitor();
69-
return;
70-
} catch (Exception e) {
71-
lastException = e;
72-
attempts++;
73-
74-
if (attempts < MAX_RETRIES) {
75-
try {
76-
Thread.sleep(RETRY_DELAY_MS * attempts);
77-
} catch (InterruptedException ie) {
78-
Thread.currentThread().interrupt();
79-
break;
80-
}
81-
}
82-
}
83-
}
84-
85-
if (lastException != null) {
86-
currentState = ServiceState.ERROR;
87-
throw new RuntimeException("Monitor failed after " + MAX_RETRIES + " attempts", lastException);
88-
}
89-
}
90-
91-
private void monitor() {
82+
private void monitor() throws InvalidPropertiesFormatException {
9283
try {
93-
performMonitoring();
84+
Utils.throwException(IllegalStateException.class, "monitor failure");
9485
} catch (Exception e) {
95-
throw new RuntimeException("Monitoring operation failed", e);
86+
throw new InvalidPropertiesFormatException("Monitor operation failed: " + e.getMessage());
9687
}
9788
}
9889

99-
private void performMonitoring() {
100-
System.out.println("Performing monitoring checks...");
101-
}
102-
10390
@Override
10491
public void stop() {
105-
currentState = ServiceState.STOPPING;
92+
currentStatus = SystemStatus.STOPPING;
93+
running = false;
10694
if (backgroundThread != null) {
95+
backgroundThread.interrupt();
10796
try {
108-
backgroundThread.join();
97+
backgroundThread.join(5000);
10998
} catch (InterruptedException e) {
11099
Thread.currentThread().interrupt();
111100
}
112101
}
113-
currentState = ServiceState.STOPPED;
102+
currentStatus = SystemStatus.STOPPED;
114103
System.out.println("Background service stopped.");
115104
}
116105

117106
@Override
118107
public boolean isRunning() {
119-
return currentState == ServiceState.RUNNING;
108+
return running && currentStatus == SystemStatus.RUNNING;
109+
}
110+
111+
public SystemStatus getCurrentStatus() {
112+
return currentStatus;
113+
}
114+
115+
public Exception getLastError() {
116+
return lastError;
120117
}
121118
}

0 commit comments

Comments
 (0)