@Override public void onEvent(SensorEvent<Object> event) { if (firstUpTime == null) { if (event != null && Attributes.SERVICE_UP.equals(event.getSensor()) && Boolean.TRUE.equals(event.getValue())) { firstUpTime = event.getTimestamp(); } else if (event == null && Boolean.TRUE.equals(entity.getAttribute(Attributes.SERVICE_UP))) { // If this enricher is registered after the entity is up, then we'll get a "synthetic" // onEvent(null) firstUpTime = System.currentTimeMillis(); } } super.onEvent(event); }
@Override protected void setActualState(Lifecycle state) { long now = System.currentTimeMillis(); synchronized (mutex) { if (state == Lifecycle.ON_FIRE) { if (lastPublished == LastPublished.FAILED) { if (currentRecoveryStartTime != null) { if (LOG.isDebugEnabled()) LOG.debug( "{} health-check for {}, component was recovering, now failing: {}", new Object[] {this, entity, getExplanation(state)}); currentRecoveryStartTime = null; publishEntityRecoveredTime = null; } else { if (LOG.isTraceEnabled()) LOG.trace( "{} health-check for {}, component still failed: {}", new Object[] {this, entity, getExplanation(state)}); } } else { if (firstUpTime == null && getConfig(ENTITY_FAILED_ONLY_IF_PREVIOUSLY_UP)) { // suppress; won't publish } else if (currentFailureStartTime == null) { if (LOG.isDebugEnabled()) LOG.debug( "{} health-check for {}, component now failing: {}", new Object[] {this, entity, getExplanation(state)}); currentFailureStartTime = now; publishEntityFailedTime = currentFailureStartTime + getConfig(ENTITY_FAILED_STABILIZATION_DELAY).toMilliseconds(); } else { if (LOG.isTraceEnabled()) LOG.trace( "{} health-check for {}, component continuing failing: {}", new Object[] {this, entity, getExplanation(state)}); } } if (setEntityOnFireTime == null) { setEntityOnFireTime = now + getConfig(SERVICE_ON_FIRE_STABILIZATION_DELAY).toMilliseconds(); } currentRecoveryStartTime = null; publishEntityRecoveredTime = null; } else if (state == Lifecycle.RUNNING) { if (lastPublished == LastPublished.FAILED) { if (currentRecoveryStartTime == null) { if (LOG.isDebugEnabled()) LOG.debug( "{} health-check for {}, component now recovering: {}", new Object[] {this, entity, getExplanation(state)}); currentRecoveryStartTime = now; publishEntityRecoveredTime = currentRecoveryStartTime + getConfig(ENTITY_RECOVERED_STABILIZATION_DELAY).toMilliseconds(); } else { if (LOG.isTraceEnabled()) LOG.trace( "{} health-check for {}, component continuing recovering: {}", new Object[] {this, entity, getExplanation(state)}); } } else { if (currentFailureStartTime != null) { if (LOG.isDebugEnabled()) LOG.debug( "{} health-check for {}, component was failing, now healthy: {}", new Object[] {this, entity, getExplanation(state)}); } else { if (LOG.isTraceEnabled()) LOG.trace( "{} health-check for {}, component still healthy: {}", new Object[] {this, entity, getExplanation(state)}); } } currentFailureStartTime = null; publishEntityFailedTime = null; setEntityOnFireTime = null; } else { if (LOG.isTraceEnabled()) LOG.trace( "{} health-check for {}, in unconfirmed sate: {}", new Object[] {this, entity, getExplanation(state)}); } long recomputeIn = Long.MAX_VALUE; // For whether to call recomputeAfterDelay if (publishEntityFailedTime != null) { long delayBeforeCheck = publishEntityFailedTime - now; if (delayBeforeCheck <= 0) { if (LOG.isDebugEnabled()) LOG.debug( "{} publishing failed (state={}; currentFailureStartTime={}; now={}", new Object[] { this, state, Time.makeDateString(currentFailureStartTime), Time.makeDateString(now) }); publishEntityFailedTime = null; lastPublished = LastPublished.FAILED; entity.emit( HASensors.ENTITY_FAILED, new HASensors.FailureDescriptor(entity, getFailureDescription(now))); } else { recomputeIn = Math.min(recomputeIn, delayBeforeCheck); } } else if (publishEntityRecoveredTime != null) { long delayBeforeCheck = publishEntityRecoveredTime - now; if (delayBeforeCheck <= 0) { if (LOG.isDebugEnabled()) LOG.debug( "{} publishing recovered (state={}; currentRecoveryStartTime={}; now={}", new Object[] { this, state, Time.makeDateString(currentRecoveryStartTime), Time.makeDateString(now) }); publishEntityRecoveredTime = null; lastPublished = LastPublished.RECOVERED; entity.emit(HASensors.ENTITY_RECOVERED, new HASensors.FailureDescriptor(entity, null)); } else { recomputeIn = Math.min(recomputeIn, delayBeforeCheck); } } if (setEntityOnFireTime != null) { long delayBeforeCheck = setEntityOnFireTime - now; if (delayBeforeCheck <= 0) { if (LOG.isDebugEnabled()) LOG.debug( "{} setting on-fire, now that deferred period has passed (state={})", new Object[] {this, state}); setEntityOnFireTime = null; super.setActualState(state); } else { recomputeIn = Math.min(recomputeIn, delayBeforeCheck); } } else { super.setActualState(state); } if (recomputeIn < Long.MAX_VALUE) { recomputeAfterDelay(recomputeIn); } } }