separate status from active heartbeat behavior

This commit is contained in:
Jonathan Shook 2024-01-11 00:41:05 -06:00
parent d8add6c225
commit 8d8288e2eb
4 changed files with 105 additions and 35 deletions

View File

@ -20,7 +20,6 @@ import io.nosqlbench.adapters.api.activityimpl.uniform.EmitterOpDispenserWrapper
import io.nosqlbench.adapters.api.activityimpl.uniform.flowtypes.CycleOp;
import io.nosqlbench.engine.core.lifecycle.scenario.container.InvokableResult;
import io.nosqlbench.nb.api.components.core.NBComponent;
import io.nosqlbench.nb.api.components.core.NBBaseComponent;
import io.nosqlbench.nb.api.components.events.ParamChange;
import io.nosqlbench.engine.api.activityapi.core.*;
import io.nosqlbench.engine.api.activityapi.core.progress.ActivityMetricProgressMeter;
@ -34,6 +33,7 @@ import io.nosqlbench.engine.api.activityapi.simrate.CycleRateSpec;
import io.nosqlbench.engine.api.activityapi.simrate.SimRateSpec;
import io.nosqlbench.adapters.api.activityimpl.OpDispenser;
import io.nosqlbench.adapters.api.activityimpl.OpMapper;
import io.nosqlbench.nb.api.components.status.NBStatusComponent;
import io.nosqlbench.nb.api.labels.NBLabels;
import io.nosqlbench.nb.api.engine.activityimpl.ActivityDef;
import io.nosqlbench.nb.api.errors.BasicError;
@ -67,7 +67,7 @@ import java.util.function.Supplier;
/**
* A default implementation of an Activity, suitable for building upon.
*/
public class SimpleActivity extends NBBaseComponent implements Activity, InvokableResult {
public class SimpleActivity extends NBStatusComponent implements Activity, InvokableResult {
private static final Logger logger = LogManager.getLogger("ACTIVITY");
protected ActivityDef activityDef;

View File

@ -17,17 +17,12 @@
package io.nosqlbench.engine.core.lifecycle.session;
import io.nosqlbench.engine.core.lifecycle.scenario.execution.NBInvokableCommand;
import io.nosqlbench.nb.api.components.status.NBLiveComponent;
import io.nosqlbench.nb.api.components.status.NBHeartbeatComponent;
import io.nosqlbench.nb.api.engine.activityimpl.ActivityDef;
import io.nosqlbench.nb.api.engine.metrics.instruments.MetricCategory;
import io.nosqlbench.nb.api.engine.metrics.instruments.NBFunctionGauge;
import io.nosqlbench.nb.api.engine.metrics.instruments.NBMetricGauge;
import io.nosqlbench.nb.api.labels.NBLabeledElement;
import io.nosqlbench.nb.api.labels.NBLabels;
import io.nosqlbench.nb.api.components.core.NBBaseComponent;
import io.nosqlbench.nb.api.components.decorators.NBTokenWords;
import io.nosqlbench.engine.cmdstream.Cmd;
import io.nosqlbench.engine.core.clientload.*;
import io.nosqlbench.engine.core.lifecycle.ExecutionResult;
import io.nosqlbench.engine.core.lifecycle.scenario.container.NBBufferedContainer;
import io.nosqlbench.engine.core.lifecycle.scenario.container.NBContainer;
@ -45,7 +40,7 @@ import java.util.function.Function;
* on.
* All NBScenarios are run within an NBSession.
*/
public class NBSession extends NBLiveComponent implements Function<List<Cmd>, ExecutionResult>, NBTokenWords {
public class NBSession extends NBHeartbeatComponent implements Function<List<Cmd>, ExecutionResult>, NBTokenWords {
private final static Logger logger = LogManager.getLogger(NBSession.class);
// private final ClientSystemMetricChecker clientMetricChecker;

View File

@ -16,9 +16,7 @@
package io.nosqlbench.nb.api.components.status;
import io.nosqlbench.nb.api.components.core.NBBaseComponent;
import io.nosqlbench.nb.api.components.core.NBComponent;
import io.nosqlbench.nb.api.components.core.NBInvokableState;
import io.nosqlbench.nb.api.labels.NBLabels;
import java.util.Map;
@ -27,37 +25,16 @@ import java.util.Map;
* A <EM>live</EM> component is one which provides evidence that it is either
* in a healthy state or that it is not, via a heartbeat mechanism.
*/
public class NBLiveComponent extends NBBaseComponent {
public class NBHeartbeatComponent extends NBStatusComponent {
public NBLiveComponent(NBComponent parentComponent) {
public NBHeartbeatComponent(NBComponent parentComponent) {
super(parentComponent);
}
public NBLiveComponent(NBComponent parentComponent, NBLabels componentSpecificLabelsOnly, Map<String, String> props, String liveLabel) {
public NBHeartbeatComponent(NBComponent parentComponent, NBLabels componentSpecificLabelsOnly, Map<String, String> props, String liveLabel) {
super(parentComponent, componentSpecificLabelsOnly, props);
// attaches, no further reference needed
new ComponentPulse(this, NBLabels.forKV(), liveLabel, Long.parseLong(getComponentProp("heartbeat").orElse("60000")));
}
public Heartbeat heartbeat() {
return new Heartbeat(
getLabels(),
this.getComponentState(),
started_ns,
sessionTimeMs(),
0L,
0L
);
}
private long sessionTimeMs() {
NBInvokableState state = getComponentState();
long nanos = switch (state) {
case ERRORED -> (nanosof_error() - nanosof_start());
case STARTING, RUNNING -> (System.nanoTime() - nanosof_start());
case CLOSING -> (nanosof_close() - nanosof_start());
case STOPPED -> (nanosof_teardown() - nanosof_start());
};
return nanos / 1_000_000L;
}
}

View File

@ -0,0 +1,98 @@
/*
* Copyright (c) 2024 nosqlbench
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.nosqlbench.nb.api.components.status;
import io.nosqlbench.nb.api.components.core.NBBaseComponent;
import io.nosqlbench.nb.api.components.core.NBComponent;
import io.nosqlbench.nb.api.components.core.NBComponentTraversal;
import io.nosqlbench.nb.api.components.core.NBInvokableState;
import io.nosqlbench.nb.api.labels.NBLabels;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class NBStatusComponent extends NBBaseComponent {
public NBStatusComponent(NBComponent parentComponent) {
super(parentComponent);
}
public NBStatusComponent(NBComponent parentComponent, NBLabels componentSpecificLabelsOnly) {
super(parentComponent, componentSpecificLabelsOnly);
}
public NBStatusComponent(NBComponent parentComponent, NBLabels componentSpecificLabelsOnly, Map<String, String> props) {
super(parentComponent, componentSpecificLabelsOnly, props);
}
public Status status() {
List<Status> subbeats = new ArrayList<>();
StatusVisitor statusVisitor = new StatusVisitor(subbeats);
for (NBComponent child : getChildren()) {
NBComponentTraversal.visitDepthFirstLimited(child,statusVisitor,c -> c instanceof NBStatusComponent);
}
// for (NBComponent child : getChildren()) {
// if (child instanceof NBStatusComponent beat) {
// subbeats.add(beat.heartbeat());
// }
// }
return new Status(
getLabels(),
this.getComponentState(),
started_epoch_ms(),
session_time_ms(),
0L,
0L,
subbeats
);
}
public long session_time_ms() {
NBInvokableState state = getComponentState();
long nanos = switch (state) {
case ERRORED -> (nanosof_error() - nanosof_start());
case STARTING, RUNNING -> (System.nanoTime() - nanosof_start());
case CLOSING -> (nanosof_close() - nanosof_start());
case STOPPED -> (nanosof_teardown() - nanosof_start());
};
return nanos / 1_000_000L;
}
private final static class StatusVisitor implements NBComponentTraversal.FilterVisitor {
private final List<Status> statusList;
public StatusVisitor(List<Status> statusList) {
this.statusList = statusList;
}
@Override
public void visitMatching(NBComponent component, int depth) {
if (component instanceof NBStatusComponent sc) {
statusList.add(sc.status());
}
}
@Override
public void visitNonMatching(NBComponent component, int depth) {
}
}
}