Skip to content

Commit 57cd739

Browse files
committed
FELIX-6448 : Simplify result cache for components check
1 parent ef866c1 commit 57cd739

File tree

1 file changed

+69
-74
lines changed

1 file changed

+69
-74
lines changed

healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/DsComponentsCheck.java

Lines changed: 69 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import java.util.Collection;
2424
import java.util.LinkedList;
2525
import java.util.List;
26+
import java.util.concurrent.atomic.AtomicBoolean;
2627
import java.util.concurrent.atomic.AtomicReference;
2728

2829
import org.apache.felix.hc.annotation.HealthCheckService;
@@ -56,8 +57,6 @@ public class DsComponentsCheck implements HealthCheck {
5657
public static final String HC_NAME = "DS Components Ready Check";
5758
public static final String HC_DEFAULT_TAG = "systemalive";
5859

59-
private static final Result INVALID = new Result(Result.Status.CRITICAL, "invalid");
60-
6160
@ObjectClassDefinition(name = "Health Check: "
6261
+ HC_NAME, description = "System ready check that checks a list of DS components and provides root cause analysis in case of errors")
6362
public @interface Config {
@@ -87,100 +86,96 @@ public class DsComponentsCheck implements HealthCheck {
8786

8887
volatile ServiceComponentRuntime scr;
8988

89+
private final AtomicBoolean refreshCache = new AtomicBoolean();
90+
9091
private final AtomicReference<Result> cache = new AtomicReference<>();
9192

9293
@Activate
9394
public void activate(final BundleContext ctx, final Config config) throws InterruptedException {
9495
componentsList = Arrays.asList(config.components_list());
9596
statusForMissing = config.statusForMissing();
96-
this.cache.set(INVALID);
97+
this.refreshCache.set(false); // cache is empty
9798
LOG.debug("Activated DS Components HC for componentsList={}", componentsList);
9899
}
99100

100101
@Override
101102
public Result execute() {
102-
Result result = null;
103-
while ( result == null ) {
104-
this.cache.compareAndSet(INVALID, null);
105-
result = this.cache.get();
106-
if ( result == INVALID ) {
107-
result = null; // repeat
108-
} else if ( result == null ) {
109-
FormattingResultLog log = new FormattingResultLog();
110-
111-
Collection<ComponentDescriptionDTO> componentDescriptionDTOs = null;
112-
try {
113-
componentDescriptionDTOs = scr.getComponentDescriptionDTOs();
114-
} catch ( final Throwable e) {
115-
log.temporarilyUnavailable("Exception while getting ds component dtos {}", e.getMessage(), e);
116-
}
117-
if ( componentDescriptionDTOs != null ) {
118-
final List<ComponentDescriptionDTO> watchedComps = new LinkedList<ComponentDescriptionDTO>();
119-
final List<String> missingComponents = new LinkedList<String>(componentsList);
120-
for (final ComponentDescriptionDTO desc : componentDescriptionDTOs) {
121-
if (componentsList.contains(desc.name)) {
122-
watchedComps.add(desc);
123-
missingComponents.remove(desc.name);
124-
}
125-
}
126-
for (final String missingComp : missingComponents) {
127-
log.info("No component with name {} is registered in SCR runtime", missingComp);
103+
Result result = this.cache.get();
104+
if ( result == null || this.refreshCache.compareAndSet(true, false) ) {
105+
FormattingResultLog log = new FormattingResultLog();
106+
107+
Collection<ComponentDescriptionDTO> componentDescriptionDTOs = null;
108+
try {
109+
componentDescriptionDTOs = scr.getComponentDescriptionDTOs();
110+
} catch ( final Throwable e) {
111+
log.temporarilyUnavailable("Exception while getting ds component dtos {}", e.getMessage(), e);
112+
}
113+
if ( componentDescriptionDTOs != null ) {
114+
final List<ComponentDescriptionDTO> watchedComps = new LinkedList<ComponentDescriptionDTO>();
115+
final List<String> missingComponents = new LinkedList<String>(componentsList);
116+
for (final ComponentDescriptionDTO desc : componentDescriptionDTOs) {
117+
if (componentsList.contains(desc.name)) {
118+
watchedComps.add(desc);
119+
missingComponents.remove(desc.name);
128120
}
121+
}
122+
for (final String missingComp : missingComponents) {
123+
log.info("No component with name {} is registered in SCR runtime", missingComp);
124+
}
129125

130-
int countEnabled = 0;
131-
int countDisabled = 0;
132-
for (final ComponentDescriptionDTO dsComp : watchedComps) {
126+
int countEnabled = 0;
127+
int countDisabled = 0;
128+
for (final ComponentDescriptionDTO dsComp : watchedComps) {
133129

134-
boolean isActive;
130+
boolean isActive;
135131

136-
boolean componentEnabled = scr.isComponentEnabled(dsComp);
137-
if (componentEnabled) {
132+
boolean componentEnabled = scr.isComponentEnabled(dsComp);
133+
if (componentEnabled) {
138134

139-
try {
140-
Collection<ComponentConfigurationDTO> componentConfigurationDTOs = scr.getComponentConfigurationDTOs(dsComp);
141-
List<String> idStateTuples = new ArrayList<>();
142-
boolean foundActiveOrSatisfiedConfig = false;
143-
for (ComponentConfigurationDTO configDto : componentConfigurationDTOs) {
144-
idStateTuples.add("id " + configDto.id + ":" + toStateString(configDto.state));
145-
if (configDto.state == ComponentConfigurationDTO.ACTIVE || configDto.state == ComponentConfigurationDTO.SATISFIED) {
146-
foundActiveOrSatisfiedConfig = true;
147-
}
135+
try {
136+
Collection<ComponentConfigurationDTO> componentConfigurationDTOs = scr.getComponentConfigurationDTOs(dsComp);
137+
List<String> idStateTuples = new ArrayList<>();
138+
boolean foundActiveOrSatisfiedConfig = false;
139+
for (ComponentConfigurationDTO configDto : componentConfigurationDTOs) {
140+
idStateTuples.add("id " + configDto.id + ":" + toStateString(configDto.state));
141+
if (configDto.state == ComponentConfigurationDTO.ACTIVE || configDto.state == ComponentConfigurationDTO.SATISFIED) {
142+
foundActiveOrSatisfiedConfig = true;
148143
}
149-
log.debug(dsComp.name + " (" + String.join(",", idStateTuples) + ")");
150-
151-
if (componentConfigurationDTOs.isEmpty() || foundActiveOrSatisfiedConfig) {
152-
countEnabled++;
153-
isActive = true;
154-
} else {
155-
countDisabled++;
156-
isActive = false;
157-
}
158-
} catch ( final Throwable e) {
159-
log.temporarilyUnavailable("Exception while getting ds component dtos {}", e.getMessage(), e);
160-
isActive = true; // no info available, doesn't make sense to report as inactive
161144
}
162-
163-
} else {
164-
countDisabled++;
165-
isActive = false;
145+
log.debug(dsComp.name + " (" + String.join(",", idStateTuples) + ")");
146+
147+
if (componentConfigurationDTOs.isEmpty() || foundActiveOrSatisfiedConfig) {
148+
countEnabled++;
149+
isActive = true;
150+
} else {
151+
countDisabled++;
152+
isActive = false;
153+
}
154+
} catch ( final Throwable e) {
155+
log.temporarilyUnavailable("Exception while getting ds component dtos {}", e.getMessage(), e);
156+
isActive = true; // no info available, doesn't make sense to report as inactive
166157
}
167158

168-
if (!isActive) {
169-
analyzer.logNotEnabledComponent(log, dsComp, componentDescriptionDTOs);
170-
}
159+
} else {
160+
countDisabled++;
161+
isActive = false;
171162
}
172163

173-
if (!missingComponents.isEmpty()) {
174-
log.add(new Entry(statusForMissing, missingComponents.size() + " required components are missing in SCR runtime"));
164+
if (!isActive) {
165+
analyzer.logNotEnabledComponent(log, dsComp, componentDescriptionDTOs);
175166
}
176-
if (countDisabled > 0) {
177-
log.add(new Entry(statusForMissing, countDisabled + " required components are not active"));
178-
}
179-
log.info("{} required components are active", countEnabled);
180167
}
181-
result = new Result(log);
182-
this.cache.compareAndSet(null, result);
168+
169+
if (!missingComponents.isEmpty()) {
170+
log.add(new Entry(statusForMissing, missingComponents.size() + " required components are missing in SCR runtime"));
171+
}
172+
if (countDisabled > 0) {
173+
log.add(new Entry(statusForMissing, countDisabled + " required components are not active"));
174+
}
175+
log.info("{} required components are active", countEnabled);
183176
}
177+
result = new Result(log);
178+
this.cache.set(result);
184179
}
185180
return result;
186181
}
@@ -205,7 +200,7 @@ static final String toStateString(int state) {
205200
}
206201
}
207202

208-
@Reference(policyOption = ReferencePolicyOption.GREEDY, updated = "updatedServiceComponentRuntime")
203+
@Reference(updated = "updatedServiceComponentRuntime")
209204
private void setServiceComponentRuntime(final ServiceComponentRuntime c) {
210205
this.scr = c;
211206
}
@@ -215,7 +210,7 @@ private void unsetServiceComponentRuntime(final ServiceComponentRuntime c) {
215210
}
216211

217212
private void updatedServiceComponentRuntime(final ServiceComponentRuntime c) {
218-
// change in DS - clear cache
219-
this.cache.set(INVALID);
213+
// change in DS - mark cache
214+
this.refreshCache.compareAndSet(false, true);
220215
}
221216
}

0 commit comments

Comments
 (0)