This is an automated email from the ASF dual-hosted git repository.
heneveld pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/brooklyn-server.git
The following commit(s) were added to refs/heads/master by this push:
new 4c39d30207 skip intermediate service not up indicators triggering
failure if cleared soon after
4c39d30207 is described below
commit 4c39d30207947433bb994094070581570913e688
Author: Alex Heneveld <[email protected]>
AuthorDate: Mon Jul 15 14:45:49 2024 +0100
skip intermediate service not up indicators triggering failure if cleared
soon after
and more logging for service up false
---
.../brooklyn/core/entity/AbstractApplication.java | 1 -
.../core/entity/lifecycle/ServiceStateLogic.java | 61 +++++++++++++++-------
2 files changed, 43 insertions(+), 19 deletions(-)
diff --git
a/core/src/main/java/org/apache/brooklyn/core/entity/AbstractApplication.java
b/core/src/main/java/org/apache/brooklyn/core/entity/AbstractApplication.java
index 1c3d73f6a1..ced6112d03 100644
---
a/core/src/main/java/org/apache/brooklyn/core/entity/AbstractApplication.java
+++
b/core/src/main/java/org/apache/brooklyn/core/entity/AbstractApplication.java
@@ -205,7 +205,6 @@ public abstract class AbstractApplication extends
AbstractEntity implements Star
ServiceStateLogic.ServiceNotUpLogic.clearNotUpIndicator(this,
Attributes.SERVICE_STATE_ACTUAL);
}
- ServiceStateLogic.setExpectedState(this, Lifecycle.RUNNING);
setExpectedStateAndRecordLifecycleEvent(Lifecycle.RUNNING);
logApplicationLifecycle("Started");
diff --git
a/core/src/main/java/org/apache/brooklyn/core/entity/lifecycle/ServiceStateLogic.java
b/core/src/main/java/org/apache/brooklyn/core/entity/lifecycle/ServiceStateLogic.java
index 55cbc23745..e64b6a7f86 100644
---
a/core/src/main/java/org/apache/brooklyn/core/entity/lifecycle/ServiceStateLogic.java
+++
b/core/src/main/java/org/apache/brooklyn/core/entity/lifecycle/ServiceStateLogic.java
@@ -68,6 +68,7 @@ import
org.apache.brooklyn.util.collections.QuorumCheck.QuorumChecks;
import org.apache.brooklyn.util.core.task.ValueResolver;
import org.apache.brooklyn.util.exceptions.Exceptions;
import org.apache.brooklyn.util.guava.Functionals;
+import org.apache.brooklyn.util.guava.IfFunctions;
import org.apache.brooklyn.util.guava.Maybe;
import org.apache.brooklyn.util.repeat.Repeater;
import org.apache.brooklyn.util.text.Strings;
@@ -166,7 +167,7 @@ public class ServiceStateLogic {
private static void setExpectedState(Entity entity, Lifecycle state,
boolean waitBrieflyForServiceUpIfRunning) {
if (waitBrieflyForServiceUpIfRunning) {
- waitBrieflyForServiceUpIfStateIsRunning(entity, state);
+ waitBrieflyForServiceUpIfStateIsRunning("setting expected state",
entity, state);
}
((EntityInternal)entity).sensors().set(Attributes.SERVICE_STATE_EXPECTED, new
Lifecycle.Transition(state, new Date()));
@@ -182,26 +183,34 @@ public class ServiceStateLogic {
return expected.getState();
}
- private static void waitBrieflyForServiceUpIfStateIsRunning(Entity entity,
Lifecycle state) {
+ private static void waitBrieflyForServiceUpIfStateIsRunning(String when,
Entity entity, Lifecycle state) {
if (state==Lifecycle.RUNNING) {
+ log.debug("Service is not up when setting "+ state +" when
"+when+" on " + entity+", but possibly just needs a recompute; doing recompute
now");
+
Boolean up = entity.getAttribute(Attributes.SERVICE_UP);
if (!Boolean.TRUE.equals(up) && Entities.isManagedActive(entity)) {
try {
Iterables.filter(entity.enrichers(), x -> x instanceof
ComputeServiceIndicatorsFromChildrenAndMembers).forEach(
x -> {
ComputeServiceIndicatorsFromChildrenAndMembers
mx = (ComputeServiceIndicatorsFromChildrenAndMembers) x;
- if (mx.isRunning()) mx.onUpdated();
+ if (mx.isRunning()) {
+ log.debug("Service not up pre-check
recompute rerunning "+mx);
+ mx.onUpdated();
+ }
}
);
Map<String, Object> notUpIndicators =
entity.sensors().get(Attributes.SERVICE_NOT_UP_INDICATORS);
- if (notUpIndicators != null && notUpIndicators.isEmpty()) {
- Optional<Enricher> css =
Iterables.tryFind(entity.enrichers(), x ->
ServiceNotUpLogic.DEFAULT_ENRICHER_UNIQUE_TAG.equals(x.getUniqueTag()));
+ if (notUpIndicators == null || notUpIndicators.isEmpty()) {
+ Maybe<Enricher> css =
EntityAdjuncts.tryFindWithUniqueTag(entity.enrichers(),
ServiceNotUpLogic.DEFAULT_ENRICHER_UNIQUE_TAG);
if (css.isPresent()) {
+ log.debug("Service not up pre-check recompute
rerunning "+css);
SensorEvent<Map<String, Object>> pseudoEvent = new
BasicSensorEvent<>(Attributes.SERVICE_NOT_UP_INDICATORS, entity,
notUpIndicators);
((SensorEventListener)
css.get()).onEvent(pseudoEvent);
up = entity.getAttribute(Attributes.SERVICE_UP);
}
+ } else {
+ log.debug("Service not up pre-check recompute not
running because not up indicators are: " + notUpIndicators);
}
} catch (Exception e) {
Exceptions.propagateIfFatal(e);
@@ -222,7 +231,7 @@ public class ServiceStateLogic {
log.debug("Had to wait " + Duration.of(timer) + " for
" + entity + " " + Attributes.SERVICE_UP + " to be true before setting " +
state);
} else {
if (Entities.isManagedActive(entity)) {
- log.warn("Service is not up when setting " + state
+ " on " + entity + "; delayed " + Duration.of(timer) + " "
+ log.warn("Service is not up when "+when+" on " +
entity + "; delayed " + Duration.of(timer) + " "
+ "but " + Attributes.SERVICE_UP + " did
not recover from " + up + "; not-up-indicators=" +
entity.getAttribute(Attributes.SERVICE_NOT_UP_INDICATORS));
}
}
@@ -239,10 +248,9 @@ public class ServiceStateLogic {
return getExpectedState(entity)==state;
}
- public static class ServiceNotUpLogic {
+ public static class ServiceNotUpLogic implements
Function<SensorEvent<Map<String, Object>>, Object> {
public static final String DEFAULT_ENRICHER_UNIQUE_TAG = "service.isUp
if no service.notUp.indicators";
- /** static only; not for instantiation */
private ServiceNotUpLogic() {}
public static final EnricherSpec<?>
newEnricherForServiceUpIfNotUpIndicatorsEmpty() {
@@ -251,10 +259,7 @@ public class ServiceStateLogic {
return Enrichers.builder()
.transforming(SERVICE_NOT_UP_INDICATORS).<Object>publishing(Attributes.SERVICE_UP)
.suppressDuplicates(true)
- .computing(
- Functionals.<Map<String,?>>
-
ifNotEquals(null).<Object>apply(Functions.forPredicate(CollectionFunctionals.<String>mapSizeEquals(0)))
- .defaultValue(Entities.UNCHANGED) )
+ .computingFromEvent(new ServiceNotUpLogic())
.uniqueTag(DEFAULT_ENRICHER_UNIQUE_TAG)
.build();
}
@@ -288,6 +293,24 @@ public class ServiceStateLogic {
else ServiceNotUpLogic.clearNotUpIndicator(entity, mapSensor);
}
+ @Override
+ public Object apply(SensorEvent<Map<String, Object>> input) {
+ Entity entity = input.getSource();
+ Map<String, Object> currentInput =
entity.sensors().get(SERVICE_NOT_UP_INDICATORS);
+ if (!Objects.equal(input.getValue(), currentInput)) {
+ log.debug("Skipping computation of
'"+DEFAULT_ENRICHER_UNIQUE_TAG+"' for "+entity+" because indicators are stale:
received "+input+", but current is "+currentInput);
+ return Entities.UNCHANGED;
+ }
+ Object result = Functionals.<Map<String,
?>>ifNotEquals(null).<Object>apply(Functions.forPredicate(CollectionFunctionals.<String>mapSizeEquals(0)))
+ .defaultValue(Entities.UNCHANGED).apply(input.getValue());
+ if (!Objects.equal(result, Entities.UNCHANGED)) {
+ Boolean prevValue = entity.sensors().get(SERVICE_UP);
+ if (!Objects.equal(result, prevValue)) {
+ log.debug("Enricher '" + DEFAULT_ENRICHER_UNIQUE_TAG + "'
for " + entity + " determined service up changed from " + prevValue + " to " +
result + " due to indicators: " + input);
+ }
+ }
+ return result;
+ }
}
/** Enricher which sets {@link Attributes#SERVICE_STATE_ACTUAL} on changes
to
@@ -298,7 +321,7 @@ public class ServiceStateLogic {
* {@link
#computeActualStateWhenNotExpectedRunning(org.apache.brooklyn.core.entity.lifecycle.Lifecycle.Transition)}
otherwise.
* If these methods return null, the {@link
Attributes#SERVICE_STATE_ACTUAL} sensor will be cleared (removed).
* Either of these methods can be overridden for custom logic, and that
custom enricher can be created using
- * {@link ServiceStateLogic#newEnricherForServiceState(Class)} and added
to an entity.
+ * newEnricher... methods on this class, and added to an entity.
*/
public static class ComputeServiceState extends AbstractEnricher
implements SensorEventListener<Object> {
private static final Logger log =
LoggerFactory.getLogger(ComputeServiceState.class);
@@ -348,27 +371,29 @@ public class ServiceStateLogic {
int count=0;
while (true) {
Map<String, Object> problems =
entity.getAttribute(SERVICE_PROBLEMS);
+ boolean noProblems = problems == null || problems.isEmpty();
+
Boolean serviceUp = entity.getAttribute(SERVICE_UP);
- if (Boolean.TRUE.equals(serviceUp) && (problems == null ||
problems.isEmpty())) {
+ if (Boolean.TRUE.equals(serviceUp) && noProblems) {
return Maybe.of(Lifecycle.RUNNING);
} else {
if (!Entities.isManagedActive(entity)) {
return Maybe.absent("entity not managed active");
}
- if
(!Lifecycle.ON_FIRE.equals(entity.getAttribute(SERVICE_STATE_ACTUAL))) {
+ if
(!Lifecycle.ON_FIRE.equals(entity.getAttribute(SERVICE_STATE_ACTUAL)) &&
noProblems) {
if (count==0) {
// very occasional race here; might want to give a
grace period if entity has just transitioned; allow children to catch up
// we probably did the wait when expected running,
but possibly in some cases we don't (seen once, 2024-07, not reproduced)
- log.debug("Entity "+entity+" would be on-fire duet
to problems (up="+serviceUp+", problems="+problems+"), will attempt one
re-check");
- waitBrieflyForServiceUpIfStateIsRunning(entity,
Lifecycle.RUNNING);
+ log.debug("Entity "+entity+" would be on-fire due
to problems (up="+serviceUp+", problems="+problems+"), will attempt re-check");
+ waitBrieflyForServiceUpIfStateIsRunning("computing
actual state", entity, Lifecycle.RUNNING);
count++;
continue;
}
BrooklynLogging.log(log,
BrooklynLogging.levelDependingIfReadOnly(entity, LoggingLevel.WARN,
LoggingLevel.TRACE, LoggingLevel.DEBUG),
"Setting " + entity + " " + Lifecycle.ON_FIRE
+ " due to problems when expected running, up=" + serviceUp + ", " +
- (problems == null ||
problems.isEmpty() ? "not-up-indicators: " +
entity.getAttribute(SERVICE_NOT_UP_INDICATORS) : "problems: " + problems));
+ (noProblems ? "not-up-indicators: " +
entity.getAttribute(SERVICE_NOT_UP_INDICATORS) : "problems: " + problems));
}
return Maybe.of(Lifecycle.ON_FIRE);
}