From 0357876e918f667763efcc49703cd93d369ae393 Mon Sep 17 00:00:00 2001 From: mxtartaglia Date: Tue, 14 Jan 2025 17:37:14 -0300 Subject: [PATCH 1/6] chore: new module for wiring framework Signed-off-by: mxtartaglia --- .../consensus-wiring/build.gradle.kts | 30 + .../java/com/swirlds/wiring/WiringConfig.java | 51 ++ .../wiring/component/ComponentWiring.java | 780 ++++++++++++++++++ .../wiring/component/InputWireLabel.java | 39 + .../wiring/component/SchedulerLabel.java | 41 + .../component/internal/FilterToBind.java | 32 + .../component/internal/InputWireToBind.java | 48 ++ .../component/internal/TransformerToBind.java | 34 + .../internal/WiringComponentProxy.java | 67 ++ .../counters/BackpressureObjectCounter.java | 199 +++++ .../swirlds/wiring/counters/EmptyBlocker.java | 69 ++ .../wiring/counters/MultiObjectCounter.java | 109 +++ .../wiring/counters/NoOpObjectCounter.java | 79 ++ .../wiring/counters/ObjectCounter.java | 81 ++ .../counters/StandardObjectCounter.java | 101 +++ .../model/DeterministicWiringModel.java | 150 ++++ .../wiring/model/StandardWiringModel.java | 256 ++++++ .../wiring/model/TraceableWiringModel.java | 334 ++++++++ .../com/swirlds/wiring/model/WiringModel.java | 160 ++++ .../wiring/model/WiringModelBuilder.java | 278 +++++++ .../model/diagram/HyperlinkBuilder.java | 81 ++ .../model/diagram/ModelEdgeSubstitution.java | 31 + .../wiring/model/diagram/ModelGroup.java | 40 + .../wiring/model/diagram/ModelManualLink.java | 29 + .../model/internal/analysis/CycleFinder.java | 138 ++++ .../analysis/DirectSchedulerChecks.java | 177 ++++ .../model/internal/analysis/GroupVertex.java | 171 ++++ .../internal/analysis/InputWireChecks.java | 68 ++ .../analysis/InputWireDescriptor.java | 30 + .../analysis/MermaidNameShortener.java | 51 ++ .../analysis/MermaidStyleManager.java | 83 ++ .../model/internal/analysis/ModelEdge.java | 196 +++++ .../model/internal/analysis/ModelVertex.java | 102 +++ .../analysis/ModelVertexMetaType.java | 37 + .../internal/analysis/StandardVertex.java | 267 ++++++ .../internal/analysis/WiringFlowchart.java | 425 ++++++++++ .../DeterministicHeartbeatScheduler.java | 111 +++ .../DeterministicTaskScheduler.java | 138 ++++ .../DeterministicTaskSchedulerBuilder.java | 106 +++ .../model/internal/monitor/HealthMonitor.java | 150 ++++ .../internal/monitor/HealthMonitorLogger.java | 98 +++ .../monitor/HealthMonitorMetrics.java | 71 ++ .../standard/AbstractHeartbeatScheduler.java | 118 +++ .../internal/standard/HeartbeatScheduler.java | 68 ++ .../internal/standard/HeartbeatTask.java | 85 ++ .../model/internal/standard/JvmAnchor.java | 68 ++ .../wiring/schedulers/TaskScheduler.java | 289 +++++++ .../builders/TaskSchedulerBuilder.java | 196 +++++ .../builders/TaskSchedulerConfigOption.java | 46 ++ .../builders/TaskSchedulerConfiguration.java | 237 ++++++ .../builders/TaskSchedulerType.java | 84 ++ .../AbstractTaskSchedulerBuilder.java | 355 ++++++++ .../StandardTaskSchedulerBuilder.java | 184 +++++ .../schedulers/internal/ConcurrentTask.java | 74 ++ .../internal/ConcurrentTaskScheduler.java | 132 +++ .../schedulers/internal/DefaultSquelcher.java | 57 ++ .../internal/DirectTaskScheduler.java | 150 ++++ .../internal/NoOpTaskScheduler.java | 138 ++++ .../schedulers/internal/SequentialTask.java | 105 +++ .../internal/SequentialTaskScheduler.java | 166 ++++ .../internal/SequentialThreadTask.java | 36 + .../SequentialThreadTaskScheduler.java | 204 +++++ .../wiring/schedulers/internal/Squelcher.java | 51 ++ .../internal/ThrowingSquelcher.java | 52 ++ .../swirlds/wiring/tasks/AbstractTask.java | 87 ++ .../transformers/AdvancedTransformation.java | 71 ++ .../wiring/transformers/RoutableData.java | 28 + .../wiring/transformers/WireFilter.java | 126 +++ .../wiring/transformers/WireListSplitter.java | 85 ++ .../wiring/transformers/WireRouter.java | 122 +++ .../wiring/transformers/WireTransformer.java | 119 +++ .../com/swirlds/wiring/wires/SolderType.java | 39 + .../swirlds/wiring/wires/input/Bindable.java | 48 ++ .../wiring/wires/input/BindableInputWire.java | 118 +++ .../swirlds/wiring/wires/input/InputWire.java | 123 +++ .../wiring/wires/input/NoOpInputWire.java | 86 ++ .../wires/input/TaskSchedulerInput.java | 65 ++ .../wiring/wires/output/NoOpOutputWire.java | 124 +++ .../wiring/wires/output/OutputWire.java | 289 +++++++ .../wires/output/StandardOutputWire.java | 79 ++ .../output/internal/ForwardingOutputWire.java | 50 ++ .../internal/TransformingOutputWire.java | 128 +++ .../src/main/java/module-info.java | 11 + 83 files changed, 10231 insertions(+) create mode 100644 platform-sdk/consensus-wiring/build.gradle.kts create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/WiringConfig.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/component/ComponentWiring.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/component/InputWireLabel.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/component/SchedulerLabel.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/component/internal/FilterToBind.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/component/internal/InputWireToBind.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/component/internal/TransformerToBind.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/component/internal/WiringComponentProxy.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/counters/BackpressureObjectCounter.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/counters/EmptyBlocker.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/counters/MultiObjectCounter.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/counters/NoOpObjectCounter.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/counters/ObjectCounter.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/counters/StandardObjectCounter.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/DeterministicWiringModel.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/StandardWiringModel.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/TraceableWiringModel.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/WiringModel.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/WiringModelBuilder.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/diagram/HyperlinkBuilder.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/diagram/ModelEdgeSubstitution.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/diagram/ModelGroup.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/diagram/ModelManualLink.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/CycleFinder.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/DirectSchedulerChecks.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/GroupVertex.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/InputWireChecks.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/InputWireDescriptor.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/MermaidNameShortener.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/MermaidStyleManager.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/ModelEdge.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/ModelVertex.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/ModelVertexMetaType.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/StandardVertex.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/WiringFlowchart.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/deterministic/DeterministicHeartbeatScheduler.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/deterministic/DeterministicTaskScheduler.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/deterministic/DeterministicTaskSchedulerBuilder.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/monitor/HealthMonitor.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/monitor/HealthMonitorLogger.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/monitor/HealthMonitorMetrics.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/standard/AbstractHeartbeatScheduler.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/standard/HeartbeatScheduler.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/standard/HeartbeatTask.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/standard/JvmAnchor.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/TaskScheduler.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/builders/TaskSchedulerBuilder.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/builders/TaskSchedulerConfigOption.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/builders/TaskSchedulerConfiguration.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/builders/TaskSchedulerType.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/builders/internal/AbstractTaskSchedulerBuilder.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/builders/internal/StandardTaskSchedulerBuilder.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/ConcurrentTask.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/ConcurrentTaskScheduler.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/DefaultSquelcher.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/DirectTaskScheduler.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/NoOpTaskScheduler.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/SequentialTask.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/SequentialTaskScheduler.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/SequentialThreadTask.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/SequentialThreadTaskScheduler.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/Squelcher.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/ThrowingSquelcher.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/tasks/AbstractTask.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/transformers/AdvancedTransformation.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/transformers/RoutableData.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/transformers/WireFilter.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/transformers/WireListSplitter.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/transformers/WireRouter.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/transformers/WireTransformer.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/SolderType.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/input/Bindable.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/input/BindableInputWire.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/input/InputWire.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/input/NoOpInputWire.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/input/TaskSchedulerInput.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/output/NoOpOutputWire.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/output/OutputWire.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/output/StandardOutputWire.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/output/internal/ForwardingOutputWire.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/output/internal/TransformingOutputWire.java create mode 100644 platform-sdk/consensus-wiring/src/main/java/module-info.java diff --git a/platform-sdk/consensus-wiring/build.gradle.kts b/platform-sdk/consensus-wiring/build.gradle.kts new file mode 100644 index 00000000000..0031158a1b5 --- /dev/null +++ b/platform-sdk/consensus-wiring/build.gradle.kts @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2025 Hedera Hashgraph, LLC + * + * 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. + */ + +plugins { + id("org.hiero.gradle.module.library") + id("org.hiero.gradle.feature.publish-artifactregistry") +} + +description = "Consensus Wiring" + +// Remove the following line to enable all 'javac' lint checks that we have turned on by default +// and then fix the reported issues. +tasks.withType().configureEach { + options.compilerArgs.add( + "-Xlint:-exports,-lossy-conversions,-overloads,-dep-ann,-text-blocks,-varargs" + ) +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/WiringConfig.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/WiringConfig.java new file mode 100644 index 00000000000..4742c6ac814 --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/WiringConfig.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring; + +import com.swirlds.config.api.ConfigData; +import com.swirlds.config.api.ConfigProperty; +import java.time.Duration; + +/** + * Configuration for the wiring framework. + * + * @param healthMonitorEnabled whether the health monitor is enabled + * @param hardBackpressureEnabled whether hard backpressure is enabled + * @param defaultPoolMultiplier used when calculating the size of the default platform fork join pool. Maximum + * parallelism in this pool is calculated as max(1, (defaultPoolMultiplier * + * [number of processors] + defaultPoolConstant)). + * @param defaultPoolConstant used when calculating the size of the default platform fork join pool. Maximum + * parallelism in this pool is calculated as max(1, (defaultPoolMultiplier * + * [number of processors] + defaultPoolConstant)). It is legal for this constant + * to be a negative number. + * @param healthMonitorSchedulerCapacity the unhandled task capacity of the health monitor's scheduler + * @param healthMonitorHeartbeatPeriod the period between heartbeats sent to the health monitor + * @param healthLogThreshold the amount of time a scheduler may be unhealthy before the platform is + * considered to be unhealthy and starts to write log warnings + * @param healthLogPeriod the minimum amount of time that must pass between health log messages for the + * same scheduler + */ +@ConfigData("platform.wiring") +public record WiringConfig( + @ConfigProperty(defaultValue = "true") boolean healthMonitorEnabled, + @ConfigProperty(defaultValue = "false") boolean hardBackpressureEnabled, + @ConfigProperty(defaultValue = "0") double defaultPoolMultiplier, + @ConfigProperty(defaultValue = "8") int defaultPoolConstant, + @ConfigProperty(defaultValue = "500") int healthMonitorSchedulerCapacity, + @ConfigProperty(defaultValue = "1ms") Duration healthMonitorHeartbeatPeriod, + @ConfigProperty(defaultValue = "1s") Duration healthLogThreshold, + @ConfigProperty(defaultValue = "10m") Duration healthLogPeriod) {} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/component/ComponentWiring.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/component/ComponentWiring.java new file mode 100644 index 00000000000..6cabbb3df1b --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/component/ComponentWiring.java @@ -0,0 +1,780 @@ +/* + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.component; + +import static com.swirlds.wiring.model.diagram.HyperlinkBuilder.platformCoreHyperlink; + +import com.swirlds.wiring.component.internal.FilterToBind; +import com.swirlds.wiring.component.internal.InputWireToBind; +import com.swirlds.wiring.component.internal.TransformerToBind; +import com.swirlds.wiring.component.internal.WiringComponentProxy; +import com.swirlds.wiring.model.WiringModel; +import com.swirlds.wiring.schedulers.TaskScheduler; +import com.swirlds.wiring.schedulers.builders.TaskSchedulerConfiguration; +import com.swirlds.wiring.schedulers.builders.TaskSchedulerType; +import com.swirlds.wiring.transformers.RoutableData; +import com.swirlds.wiring.transformers.WireFilter; +import com.swirlds.wiring.transformers.WireRouter; +import com.swirlds.wiring.transformers.WireTransformer; +import com.swirlds.wiring.wires.input.BindableInputWire; +import com.swirlds.wiring.wires.input.InputWire; +import com.swirlds.wiring.wires.output.OutputWire; +import edu.umd.cs.findbugs.annotations.NonNull; +import edu.umd.cs.findbugs.annotations.Nullable; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.function.BiConsumer; +import java.util.function.BiFunction; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Supplier; +import java.util.function.ToLongFunction; + +/** + * Builds and manages input/output wires for a component. + * + * @param the type of the component + * @param the output type of the component + */ +@SuppressWarnings("unchecked") +public class ComponentWiring { + + private final WiringModel model; + private final TaskScheduler scheduler; + + private final WiringComponentProxy proxy = new WiringComponentProxy(); + private final COMPONENT_TYPE proxyComponent; + + /** + * The component that implements the business logic. Will be null until {@link #bind(Object)} is called. + */ + private COMPONENT_TYPE component; + + /** + * Input wires that have been created for this component. + */ + private final Map> inputWires = new HashMap<>(); + + /** + * Input wires that need to be bound. + */ + private final List> inputsToBind = new ArrayList<>(); + + /** + * Previously created transformers/splitters/filters. + */ + private final Map> alternateOutputs = new HashMap<>(); + + /** + * Transformers that need to be bound. + */ + private final List> transformersToBind = new ArrayList<>(); + + /** + * Filters that need to be bound. + */ + private final List> filtersToBind = new ArrayList<>(); + + /** + * A splitter (if one has been constructed). + */ + private OutputWire splitterOutput; + + /** + * A router (if one has been constructed). + */ + private WireRouter router; + + /** + * A router that consumes the output of a splitter (if one has been constructed). + */ + private WireRouter splitRouter; + + /** + * Create a new component wiring. + * + * @param model the wiring model that will contain the component + * @param clazz the interface class of the component + * @param scheduler the task scheduler that will run the component + * @deprecated use {@link #ComponentWiring(WiringModel, Class, TaskSchedulerConfiguration)} instead. Once all uses + * have been updated, this constructor will be removed. + */ + @Deprecated + public ComponentWiring( + @NonNull final WiringModel model, + @NonNull final Class clazz, + @NonNull final TaskScheduler scheduler) { + + this.model = Objects.requireNonNull(model); + this.scheduler = Objects.requireNonNull(scheduler); + + if (!clazz.isInterface()) { + throw new IllegalArgumentException("Component class " + clazz.getName() + " is not an interface."); + } + + proxyComponent = (COMPONENT_TYPE) Proxy.newProxyInstance(clazz.getClassLoader(), new Class[] {clazz}, proxy); + } + + /** + * Create a new component wiring. + * + * @param model the wiring model that will contain the component + * @param clazz the interface class of the component + * @param schedulerConfiguration for the task scheduler that will run the component + */ + public ComponentWiring( + @NonNull final WiringModel model, + @NonNull final Class clazz, + @NonNull final TaskSchedulerConfiguration schedulerConfiguration) { + this(model, clazz, schedulerConfiguration, data -> 1); + } + + /** + * Create a new component wiring. + * + * @param model the wiring model that will contain the component + * @param clazz the interface class of the component + * @param schedulerConfiguration for the task scheduler that will run the component + * @param dataCounter the function to weight input data objects for health monitoring + */ + public ComponentWiring( + @NonNull final WiringModel model, + @NonNull final Class clazz, + @NonNull final TaskSchedulerConfiguration schedulerConfiguration, + @NonNull final ToLongFunction dataCounter) { + + this.model = Objects.requireNonNull(model); + Objects.requireNonNull(schedulerConfiguration); + + final String schedulerName; + final SchedulerLabel schedulerLabelAnnotation = clazz.getAnnotation(SchedulerLabel.class); + if (schedulerLabelAnnotation == null) { + schedulerName = clazz.getSimpleName(); + } else { + schedulerName = schedulerLabelAnnotation.value(); + } + + this.scheduler = model.schedulerBuilder(schedulerName) + .configure(schedulerConfiguration) + // FUTURE WORK: all components not currently in platform core should move there + .withHyperlink(platformCoreHyperlink(clazz)) + .withDataCounter(dataCounter) + .build() + .cast(); + + if (!clazz.isInterface()) { + throw new IllegalArgumentException("Component class " + clazz.getName() + " is not an interface."); + } + + proxyComponent = (COMPONENT_TYPE) Proxy.newProxyInstance(clazz.getClassLoader(), new Class[] {clazz}, proxy); + } + + /** + * Get the output wire of this component. + * + * @return the output wire + */ + @NonNull + public OutputWire getOutputWire() { + return scheduler.getOutputWire(); + } + + /** + * Get an input wire for this component. + * + * @param handler the component method that will handle the input, e.g. "MyComponent::handleInput". Should be a + * method on the class, not a method on a specific instance. + * @param the type of the input + * @return the input wire + */ + public InputWire getInputWire( + @NonNull final BiFunction handler) { + + Objects.requireNonNull(handler); + + try { + handler.apply(proxyComponent, null); + } catch (final NullPointerException e) { + throw new IllegalStateException( + "Component wiring does not support primitive input types or return types. Use a boxed primitive " + + "instead.", + e); + } + + return getOrBuildInputWire(proxy.getMostRecentlyInvokedMethod(), handler, null, null, null); + } + + /** + * Get an input wire for this component. + * + * @param handler the component method that will handle the input, e.g. "MyComponent::handleInput". Should be a + * method on the class, not a method on a specific instance. + * @param the input type + * @return the input wire + */ + public InputWire getInputWire( + @NonNull final BiConsumer handler) { + + Objects.requireNonNull(handler); + + try { + handler.accept(proxyComponent, null); + } catch (final NullPointerException e) { + throw new IllegalStateException( + "Component wiring does not support primitive input types. Use a boxed primitive instead.", e); + } + + return getOrBuildInputWire(proxy.getMostRecentlyInvokedMethod(), null, handler, null, null); + } + + /** + * Get an input wire for this component. + * + * @param handler the component method that will handle the input, e.g. "MyComponent::handleInput". Should be a + * method on the class, not a method on a specific instance. + * @param the input type + * @return the input wire + */ + @NonNull + public InputWire getInputWire( + @NonNull final Function handler) { + Objects.requireNonNull(handler); + + try { + handler.apply(proxyComponent); + } catch (final NullPointerException e) { + throw new IllegalStateException( + "Component wiring does not support primitive input types. Use a boxed primitive instead.", e); + } + + return getOrBuildInputWire(proxy.getMostRecentlyInvokedMethod(), null, null, handler, null); + } + + /** + * Get an input wire for this component. + * + * @param handler the component method that will handle the input, e.g. "MyComponent::handleInput". Should be a + * method on the class, not a method on a specific instance. + * @param the input type + * @return the input wire + */ + @NonNull + public InputWire getInputWire(@NonNull final Consumer handler) { + Objects.requireNonNull(handler); + + try { + handler.accept(proxyComponent); + } catch (final NullPointerException e) { + throw new IllegalStateException( + "Component wiring does not support primitive input types. Use a boxed primitive instead.", e); + } + + return getOrBuildInputWire(proxy.getMostRecentlyInvokedMethod(), null, null, null, handler); + } + + /** + * Get the output wire of this component, transformed by a function. + * + * @param transformation the function that will transform the output, must be a static method on the component + * @param the type of the transformed output + * @return the transformed output wire + */ + @NonNull + public OutputWire getTransformedOutput( + @NonNull final BiFunction transformation) { + + return getOrBuildTransformer(transformation, getOutputWire()); + } + + /** + * Get the output wire of a splitter of this component, transformed by a function. Automatically constructs the + * splitter if it does not already exist. Intended for use only with components that produce lists of items. + * + * @param transformation the function that will transform the output, must be a static method on the component + * @param the type of the elements in the list, the base type of this component's output is expected + * to be a list of this type + */ + public OutputWire getSplitAndTransformedOutput( + @NonNull final BiFunction transformation) { + return getOrBuildTransformer(transformation, getSplitOutput()); + } + + /** + * Create a filter for the output of this component. + * + * @param predicate the filter predicate + * @return the output wire of the filter + */ + @NonNull + public OutputWire getFilteredOutput( + @NonNull final BiFunction predicate) { + return getOrBuildFilter(predicate, getOutputWire()); + } + + /** + * Create a filter for the output of a splitter of this component. Automatically constructs the splitter if it does + * not already exist. Intended for use only with components that produce lists of items. + * + * @param predicate the filter predicate + * @param the type of the elements in the list, the base type of this component's output is expected to be + * a list of this type + * @return the output wire of the filter + */ + @NonNull + public OutputWire getSplitAndFilteredOutput( + @NonNull final BiFunction predicate) { + + return getOrBuildFilter(predicate, getSplitOutput()); + } + + /** + * Create a splitter for the output of this component. A splitter converts an output wire that produces lists of + * items into an output wire that produces individual items. Note that calling this method on a component that does + * not produce lists will result in a runtime exception. + * + * @param the type of the elements in the list, the base type of this component's output is expected to be + * a list of this type + * @return the output wire + */ + @NonNull + public OutputWire getSplitOutput() { + if (splitterOutput == null) { + + // Future work: there is not a clean way to specify the "splitterInputName" label, so as a short + // term work around we can just call it "data". This is ugly but ok as a temporary place holder. + // The proper way to fix this is to change the way we assign labels to wires in the diagram. + // Instead of defining names for input wires, we should instead define names for output wires, + // and require that any scheduler that has output define the label for its output data. + + splitterOutput = getOutputWire().buildSplitter(scheduler.getName() + "Splitter", "data"); + } + return (OutputWire) splitterOutput; + } + + /** + * Get an output wire that will emit a specific type of routed data. Data routing is when a component has multiple + * outputs, and different things want to receive a subset of that output. Each output is described by a routing + * address, which are implemented by enum values. + *

+ * This method should only be used for components which have an output type of + * {@link RoutableData RoutableData}. Calling this method more than once with + * different enum classes will throw. + * + * @param address an enum value that describes one of the different types of data that can be routed + * @param the enum that describes the different types of data handled by this router + * @param the type of data that travels over the output wire + * @return the output wire + */ + @NonNull + public , DATA_TYPE> OutputWire getRoutedOutput( + @NonNull final ROUTER_ENUM address) { + + final Class clazz = (Class) address.getClass(); + return getOrBuildRouter(clazz).getOutput(address); + } + + /** + * Get an output wire that will receive a specific type of routed data after being split apart. Data routing is when + * a component has multiple outputs, and different things want to receive a subset of that output. Each output is + * described by a routing address, which are implemented by enum values. + *

+ * This method should only be used for components which have an output type of + * {@link RoutableData List<RoutableData>}. Calling this method more + * than once with different enum classes will throw. + * + * @param address an enum value that describes one of the different types of data that can be routed + * @param the enum that describes the different types of data handled by this router + * @param the type of data that travels over the output wire + * @return the output wire + */ + @NonNull + public , DATA_TYPE> OutputWire getSplitAndRoutedOutput( + @NonNull final ROUTER_ENUM address) { + + final Class clazz = (Class) address.getClass(); + return getOrBuildSplitRouter(clazz).getOutput(address); + } + + /** + * Get the router for this component if one has been built. Build and return a new router if one has not been + * built. + * + * @param routerType the type of the router + * @param the type of the router + * @return the router + */ + @NonNull + private > WireRouter getOrBuildRouter( + @NonNull final Class routerType) { + + if (splitRouter != null) { + throw new IllegalStateException("Only one type of router can be constructed per task scheduler. " + + "This task scheduler already has a router that was built using the split output type, " + + "so a router cannot be created with the unmodified output type."); + } + + if (router != null) { + if (!router.getRouterType().equals(routerType)) { + throw new IllegalArgumentException("Only one type of router can be constructed per task scheduler. " + + "This task scheduler already has a router of type " + + router.getRouterType().getName() + "but an attempt was made to construct a router of type " + + routerType.getName()); + } + } else { + router = new WireRouter<>(model, getSchedulerName() + "Router", "data", routerType); + getOutputWire().solderTo((InputWire) router.getInput()); + } + + return (WireRouter) router; + } + + /** + * Get the router for split data for this component if one has been built. Build and return a new splitter and + * router if one has not been built. + * + * @param routerType the type of the router + * @param the type of the router + * @return the router + */ + @NonNull + private > WireRouter getOrBuildSplitRouter( + @NonNull final Class routerType) { + + if (router != null) { + throw new IllegalStateException("Only one type of router can be constructed per task scheduler. " + + "This task scheduler already has a router that was built using the unmodified output type, " + + "so a router cannot be created with the split output type."); + } + + if (splitRouter != null) { + if (!splitRouter.getRouterType().equals(routerType)) { + throw new IllegalArgumentException("Only one type of router can be constructed per task scheduler. " + + "This task scheduler already has a router of type " + + router.getRouterType().getName() + "but an attempt was made to construct a router of type " + + routerType.getName()); + } + } else { + splitRouter = new WireRouter<>(model, getSchedulerName() + "Router", "data", routerType); + final OutputWire> splitOutput = getSplitOutput(); + final InputWire> routerInput = ((WireRouter) splitRouter).getInput(); + splitOutput.solderTo(routerInput); + } + + return (WireRouter) splitRouter; + } + + /** + * Create a transformed output wire or return the existing one if it has already been created. + * + * @param transformation the function that will transform the output, must be a static method on the component + * @param transformerSource the source of the data to transform (i.e. the base output wire or the output wire of + * the splitter) + * @param the type of the elements passed to the transformer + * @param the type of the transformed output + * @return the transformed output wire + */ + @NonNull + private OutputWire getOrBuildTransformer( + @NonNull final BiFunction transformation, + @NonNull final OutputWire transformerSource) { + + Objects.requireNonNull(transformation); + try { + transformation.apply(proxyComponent, null); + } catch (final NullPointerException e) { + throw new IllegalStateException( + "Component wiring does not support primitive input types or return types. " + + "Use a boxed primitive instead.", + e); + } + + final Method method = proxy.getMostRecentlyInvokedMethod(); + if (!method.isDefault()) { + throw new IllegalArgumentException("Method " + method.getName() + " does not have a default."); + } + + if (alternateOutputs.containsKey(method)) { + // We've already created this transformer. + return (OutputWire) alternateOutputs.get(method); + } + + final String wireLabel; + final InputWireLabel inputWireLabel = method.getAnnotation(InputWireLabel.class); + if (inputWireLabel == null) { + wireLabel = "data to transform"; + } else { + wireLabel = inputWireLabel.value(); + } + + final String schedulerLabel; + final SchedulerLabel schedulerLabelAnnotation = method.getAnnotation(SchedulerLabel.class); + if (schedulerLabelAnnotation == null) { + schedulerLabel = method.getName(); + } else { + schedulerLabel = schedulerLabelAnnotation.value(); + } + + final WireTransformer transformer = + new WireTransformer<>(model, schedulerLabel, wireLabel); + transformerSource.solderTo(transformer.getInputWire()); + alternateOutputs.put(method, transformer.getOutputWire()); + + if (component == null) { + // we will bind this later + transformersToBind.add((TransformerToBind) + new TransformerToBind<>(transformer, transformation)); + } else { + // bind this now + transformer.bind(x -> transformation.apply(component, x)); + } + + return transformer.getOutputWire(); + } + + /** + * Create a filtered output wire or return the existing one if it has already been created. + * + * @param predicate the filter predicate + * @param filterSource the source of the data to filter (i.e. the base output wire or the output wire of the + * splitter) + * @param the type of the elements passed to the filter + * @return the output wire of the filter + */ + private OutputWire getOrBuildFilter( + @NonNull final BiFunction predicate, + @NonNull final OutputWire filterSource) { + + Objects.requireNonNull(predicate); + try { + predicate.apply(proxyComponent, null); + } catch (final NullPointerException e) { + throw new IllegalStateException( + "Component wiring does not support primitive input types or return types. " + + "Use a boxed primitive instead.", + e); + } + + final Method method = proxy.getMostRecentlyInvokedMethod(); + if (!method.isDefault()) { + throw new IllegalArgumentException("Method " + method.getName() + " does not have a default."); + } + + if (alternateOutputs.containsKey(method)) { + // We've already created this filter. + return (OutputWire) alternateOutputs.get(method); + } + + final String wireLabel; + final InputWireLabel inputWireLabel = method.getAnnotation(InputWireLabel.class); + if (inputWireLabel == null) { + wireLabel = "data to filter"; + } else { + wireLabel = inputWireLabel.value(); + } + + final String schedulerLabel; + final SchedulerLabel schedulerLabelAnnotation = method.getAnnotation(SchedulerLabel.class); + if (schedulerLabelAnnotation == null) { + schedulerLabel = method.getName(); + } else { + schedulerLabel = schedulerLabelAnnotation.value(); + } + + final WireFilter filter = new WireFilter<>(model, schedulerLabel, wireLabel); + filterSource.solderTo(filter.getInputWire()); + alternateOutputs.put(method, filter.getOutputWire()); + + if (component == null) { + // we will bind this later + filtersToBind.add((FilterToBind) new FilterToBind<>(filter, predicate)); + } else { + // bind this now + filter.bind(x -> predicate.apply(component, x)); + } + + return filter.getOutputWire(); + } + + /** + * Get the input wire for a specified method. + * + * @param method the method that will handle data on the input wire + * @param handlerWithReturn the handler for the method if it has a return type + * @param handlerWithoutReturn the handler for the method if it does not have a return type + * @param handlerWithoutParameter the handler for the method if it does not have a parameter + * @param handlerWithoutReturnAndWithoutParameter the handler for the method if it does not have a return type and + * does not have a parameter + * @param the input type + * @return the input wire + */ + private InputWire getOrBuildInputWire( + @NonNull final Method method, + @Nullable final BiFunction handlerWithReturn, + @Nullable final BiConsumer handlerWithoutReturn, + @Nullable final Function handlerWithoutParameter, + @Nullable final Consumer handlerWithoutReturnAndWithoutParameter) { + + if (inputWires.containsKey(method)) { + // We've already created this wire + return (InputWire) inputWires.get(method); + } + + final String label; + final InputWireLabel inputWireLabel = method.getAnnotation(InputWireLabel.class); + if (inputWireLabel == null) { + label = method.getName(); + } else { + label = inputWireLabel.value(); + } + + final BindableInputWire inputWire = scheduler.buildInputWire(label); + inputWires.put(method, (BindableInputWire) inputWire); + + if (component == null) { + // we will bind this later + inputsToBind.add((InputWireToBind) new InputWireToBind<>( + inputWire, + handlerWithReturn, + handlerWithoutReturn, + handlerWithoutParameter, + handlerWithoutReturnAndWithoutParameter)); + } else { + // bind this now + if (handlerWithReturn != null) { + inputWire.bind(x -> handlerWithReturn.apply(component, x)); + } else if (handlerWithoutReturn != null) { + inputWire.bindConsumer(x -> { + handlerWithoutReturn.accept(component, x); + }); + } else if (handlerWithoutParameter != null) { + inputWire.bind(x -> handlerWithoutParameter.apply(component)); + } else { + assert handlerWithoutReturnAndWithoutParameter != null; + inputWire.bindConsumer(x -> { + handlerWithoutReturnAndWithoutParameter.accept(component); + }); + } + } + + return inputWire; + } + + /** + * Flush all data in the task scheduler. Blocks until all data currently in flight has been processed. + * + * @throws UnsupportedOperationException if the scheduler does not support flushing + */ + public void flush() { + scheduler.flush(); + } + + /** + * Start squelching the output of this component. + * + * @throws UnsupportedOperationException if the scheduler does not support squelching + * @throws IllegalStateException if the scheduler is already squelching + */ + public void startSquelching() { + scheduler.startSquelching(); + } + + /** + * Stop squelching the output of this component. + * + * @throws UnsupportedOperationException if the scheduler does not support squelching + * @throws IllegalStateException if the scheduler is not squelching + */ + public void stopSquelching() { + scheduler.stopSquelching(); + } + + /** + * Bind the component to the input wires. + * + * @param component the component to bind + */ + public void bind(@NonNull final COMPONENT_TYPE component) { + Objects.requireNonNull(component); + + this.component = component; + + // Bind input wires + for (final InputWireToBind wireToBind : inputsToBind) { + if (wireToBind.handlerWithReturn() != null) { + final BiFunction handlerWithReturn = + (BiFunction) wireToBind.handlerWithReturn(); + wireToBind.inputWire().bind(x -> handlerWithReturn.apply(component, x)); + } else if (wireToBind.handlerWithoutReturn() != null) { + final BiConsumer handlerWithoutReturn = + (BiConsumer) wireToBind.handlerWithoutReturn(); + wireToBind.inputWire().bindConsumer(x -> { + handlerWithoutReturn.accept(component, x); + }); + } else if (wireToBind.handlerWithoutParameter() != null) { + wireToBind + .inputWire() + .bind(x -> wireToBind.handlerWithoutParameter().apply(component)); + } else { + assert wireToBind.handlerWithoutReturnAndWithoutParameter() != null; + wireToBind.inputWire().bindConsumer(x -> { + wireToBind.handlerWithoutReturnAndWithoutParameter().accept(component); + }); + } + } + + // Bind transformers + for (final TransformerToBind transformerToBind : transformersToBind) { + final WireTransformer transformer = transformerToBind.transformer(); + final BiFunction transformation = transformerToBind.transformation(); + transformer.bind(x -> transformation.apply(component, x)); + } + + // Bind filters + for (final FilterToBind filterToBind : filtersToBind) { + filterToBind.filter().bind(x -> filterToBind.predicate().apply(component, x)); + } + } + + /** + * Bind to a component. This method is similar to {@link #bind(Object)}, but it allows the component to be created + * if and only if we need to bind to it. This method will invoke the supplier if the task scheduler type is anything + * other than a {@link TaskSchedulerType#NO_OP NO_OP} scheduler. + * + * @param componentBuilder builds or supplies the component + */ + public void bind(@NonNull final Supplier componentBuilder) { + Objects.requireNonNull(componentBuilder); + if (scheduler.getType() != TaskSchedulerType.NO_OP) { + bind(componentBuilder.get()); + } + } + + /** + * Get the name of the scheduler that is running this component. + * + * @return the name of the scheduler + */ + @NonNull + public String getSchedulerName() { + return scheduler.getName(); + } +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/component/InputWireLabel.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/component/InputWireLabel.java new file mode 100644 index 00000000000..01dcf7b3d3d --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/component/InputWireLabel.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.component; + +import edu.umd.cs.findbugs.annotations.NonNull; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Label the input wire that a method is associated with. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface InputWireLabel { + + /** + * The label of the input wire. + * + * @return the label of the input wire + */ + @NonNull + String value(); +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/component/SchedulerLabel.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/component/SchedulerLabel.java new file mode 100644 index 00000000000..f3c3227485a --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/component/SchedulerLabel.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.component; + +import edu.umd.cs.findbugs.annotations.NonNull; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Annotates a name that should be used as an override for the task scheduler's name instead of a component's interface + * name. Can also be used to annotate a method parameter used to implement a transformer/filter (these get turned into + * direct schedulers, which need to be named). + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE, ElementType.METHOD}) +public @interface SchedulerLabel { + + /** + * The label of the task scheduler that will operate the transformer/filter. + * + * @return the label of the task scheduler that will operate the transformer/filter + */ + @NonNull + String value(); +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/component/internal/FilterToBind.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/component/internal/FilterToBind.java new file mode 100644 index 00000000000..526c713ff12 --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/component/internal/FilterToBind.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.component.internal; + +import com.swirlds.wiring.transformers.WireFilter; +import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.function.BiFunction; + +/** + * A filter and the predicate to bind. + * + * @param filter the filter we eventually want to bind + * @param predicate the predicate method + * @param the type of the component + * @param the input type + */ +public record FilterToBind( + @NonNull WireFilter filter, @NonNull BiFunction predicate) {} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/component/internal/InputWireToBind.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/component/internal/InputWireToBind.java new file mode 100644 index 00000000000..993c978f716 --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/component/internal/InputWireToBind.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.component.internal; + +import com.swirlds.wiring.wires.input.BindableInputWire; +import edu.umd.cs.findbugs.annotations.NonNull; +import edu.umd.cs.findbugs.annotations.Nullable; +import java.util.function.BiConsumer; +import java.util.function.BiFunction; +import java.util.function.Consumer; +import java.util.function.Function; + +/** + * Contains information necessary to bind an input wire when we eventually get the implementation of the component. + * + * @param inputWire the input wire to bind + * @param handlerWithReturn null if initially bound. If not initially bound, will be non-null + * if the method has a non-void return type + * @param handlerWithoutReturn null if initially bound. If not initially bound, will be non-null + * if the method has a void return type + * @param handlerWithoutParameter null if initially bound. If not initially bound, will be non-null + * if the method has no parameters + * @param handlerWithoutReturnAndWithoutParameter null if initially bound. If not initially bound, will be non-null if + * the method has no parameters and a void return type + * @param the type of the component + * @param the input type of the input wire + * @param the output type of the component + */ +public record InputWireToBind( + @NonNull BindableInputWire inputWire, + @Nullable BiFunction handlerWithReturn, + @Nullable BiConsumer handlerWithoutReturn, + @Nullable Function handlerWithoutParameter, + @Nullable Consumer handlerWithoutReturnAndWithoutParameter) {} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/component/internal/TransformerToBind.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/component/internal/TransformerToBind.java new file mode 100644 index 00000000000..7c0b1599765 --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/component/internal/TransformerToBind.java @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.component.internal; + +import com.swirlds.wiring.transformers.WireTransformer; +import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.function.BiFunction; + +/** + * A transformer and the transformation to bind to a component. + * + * @param transformer the transformer we eventually want to bind + * @param transformation the transformation method + * @param the type of the component + * @param the input type of the transformer (equal to the output type of the base output wire) + * @param the output type of the transformer + */ +public record TransformerToBind( + @NonNull WireTransformer transformer, + @NonNull BiFunction transformation) {} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/component/internal/WiringComponentProxy.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/component/internal/WiringComponentProxy.java new file mode 100644 index 00000000000..b50a4c8151f --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/component/internal/WiringComponentProxy.java @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.component.internal; + +import com.swirlds.wiring.component.ComponentWiring; +import edu.umd.cs.findbugs.annotations.NonNull; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.util.Objects; + +/** + * This dynamic proxy is used by the {@link ComponentWiring} to capture the most + * recently invoked method. + */ +public class WiringComponentProxy implements InvocationHandler { + + private Method mostRecentlyInvokedMethod = null; + + /** + * {@inheritDoc} + */ + @Override + public Object invoke(@NonNull final Object proxy, @NonNull final Method method, @NonNull final Object[] args) + throws Throwable { + + if (method.getName().equals("toString")) { + // Handle this specially, the debugger likes to call toString() + // on the proxy which disrupts normal behavior when debugging. + return "WiringComponentProxy"; + } + + mostRecentlyInvokedMethod = Objects.requireNonNull(method); + return null; + } + + /** + * Get the most recently invoked method. Calling this method resets the most recently invoked method to null + * as a safety measure. + * + * @return the most recently invoked method + */ + @NonNull + public Method getMostRecentlyInvokedMethod() { + if (mostRecentlyInvokedMethod == null) { + throw new IllegalArgumentException("Provided lambda is not a method on the component interface."); + } + try { + return mostRecentlyInvokedMethod; + } finally { + mostRecentlyInvokedMethod = null; + } + } +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/counters/BackpressureObjectCounter.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/counters/BackpressureObjectCounter.java new file mode 100644 index 00000000000..5c32836570a --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/counters/BackpressureObjectCounter.java @@ -0,0 +1,199 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.counters; + +import static java.util.concurrent.TimeUnit.NANOSECONDS; + +import edu.umd.cs.findbugs.annotations.NonNull; +import java.time.Duration; +import java.util.Objects; +import java.util.concurrent.ForkJoinPool; +import java.util.concurrent.ForkJoinPool.ManagedBlocker; +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.atomic.AtomicLong; + +/** + * A utility for counting the number of objects in various parts of the pipeline. Will apply backpressure if the number + * of objects exceeds a specified capacity. + *

+ * In order to achieve higher performance in high contention environments, this class allows the count returned by + * {@link #getCount()} to temporarily exceed the capacity even if {@link #forceOnRamp()} is not used. This doesn't allow + * objects to be on-ramped in excess of the capacity, but it may add some slight fuzziness to the count. + */ +public class BackpressureObjectCounter extends ObjectCounter { + + private final String name; + private final AtomicLong count = new AtomicLong(0); + private final long capacity; + + /** + * The amount of time to sleep while waiting for capacity to become available, or 0 to not sleep. + */ + private final long sleepNanos; + + /** + * When waiting for the count to reach zero, this object is used to efficiently sleep on the fork join pool. + */ + private final ManagedBlocker waitUntilEmptyBlocker; + + /** + * Constructor. + * + * @param name the name of the object counter, used creating more informative exceptions + * @param capacity the maximum number of objects that can be in the part of the system that this object is + * being used to monitor before backpressure is applied + * @param sleepDuration when a method needs to block, the duration to sleep while blocking + */ + public BackpressureObjectCounter( + @NonNull final String name, final long capacity, @NonNull final Duration sleepDuration) { + if (capacity <= 0) { + throw new IllegalArgumentException("Capacity must be greater than zero"); + } + + this.name = Objects.requireNonNull(name); + this.capacity = capacity; + this.sleepNanos = sleepDuration.toNanos(); + + waitUntilEmptyBlocker = new EmptyBlocker(count, sleepNanos); + } + + /** + * {@inheritDoc} + */ + @Override + public void onRamp(final long delta) { + if (attemptOnRamp(delta)) { + return; + } + + // Slow case. Capacity wasn't reserved, so we need to block. + + while (true) { + try { + // This will block until capacity is available and the count has been incremented. + // + // This is logically equivalent to the following pseudocode. + // Note that the managed block is thread safe when onRamp() is being called from multiple threads, + // even though this pseudocode is not. + // + // while (count >= capacity) { + // Thread.sleep(sleepNanos); + // } + // count++; + // + // The reason why we use the managedBlock() strategy instead of something simpler has to do with + // the fork join pool paradigm. Unlike traditional thread pools where we have more threads than + // CPUs, blocking (e.g. Thread.sleep()) on a fork join pool may monopolize an entire CPU core. + // The managedBlock() pattern allows us to block while yielding the physical CPU core to other + // tasks. + ForkJoinPool.managedBlock(new ManagedBlocker() { + + @Override + public boolean block() throws InterruptedException { + if (sleepNanos > 0) { + try { + NANOSECONDS.sleep(sleepNanos); + } catch (final InterruptedException e) { + // Don't throw an interrupted exception, but allow the thread to maintain its + // interrupted status. + Thread.currentThread().interrupt(); + } + } + + // Although we could technically check the count here and stop the back pressure if the count is + // below the threshold, it's simpler not to. Immediately after this method is called, + // isReleasable() will be called, which will do the checking for us. Easier to just let that + // method do the work, and have this method only be responsible for sleeping. + return false; + } + + @Override + public boolean isReleasable() { + return attemptOnRamp(delta); + } + }); + return; + } catch (final InterruptedException ex) { + // This should be impossible. + Thread.currentThread().interrupt(); + throw new IllegalStateException("Interrupted while blocking on an onRamp() for " + name); + } catch (final RejectedExecutionException ex) { + // We've exhausted our supply of background threads, we have no choice but to busy wait. + Thread.onSpinWait(); + } + } + } + + /** + * {@inheritDoc} + */ + @Override + public boolean attemptOnRamp(final long delta) { + final long resultingCount = count.addAndGet(delta); + if (resultingCount <= capacity) { + // We didn't violate capacity by incrementing the count, so we're done. + return true; + } else { + // We may have violated capacity restrictions by incrementing the count. + // Decrement count and return failure. + count.addAndGet(-delta); + return false; + } + } + + /** + * {@inheritDoc} + */ + @Override + public void forceOnRamp(final long delta) { + count.addAndGet(delta); + } + + /** + * {@inheritDoc} + */ + @Override + public void offRamp(final long delta) { + count.addAndGet(-delta); + } + + /** + * {@inheritDoc} + */ + @Override + public long getCount() { + return count.get(); + } + + /** + * {@inheritDoc} + */ + @Override + public void waitUntilEmpty() { + if (count.get() == 0) { + return; + } + + try { + ForkJoinPool.managedBlock(waitUntilEmptyBlocker); + } catch (final InterruptedException e) { + // This should be impossible. + Thread.currentThread().interrupt(); + throw new IllegalStateException("Interrupted while blocking on an waitUntilEmpty() for " + name); + } + } +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/counters/EmptyBlocker.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/counters/EmptyBlocker.java new file mode 100644 index 00000000000..32d51e3e854 --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/counters/EmptyBlocker.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.counters; + +import static java.util.concurrent.TimeUnit.NANOSECONDS; + +import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Objects; +import java.util.concurrent.ForkJoinPool.ManagedBlocker; +import java.util.concurrent.atomic.AtomicLong; + +/** + * This class is used to implement flushing in a {@link java.util.concurrent.ForkJoinPool} friendly way. Blocks until + * the count reaches zero. + */ +class EmptyBlocker implements ManagedBlocker { + + private final AtomicLong count; + private final long sleepNanos; + + /** + * Constructor. + * + * @param count the counter to use + * @param sleepNanos the number of nanoseconds to sleep while blocking, or 0 to not sleep + */ + public EmptyBlocker(@NonNull final AtomicLong count, final long sleepNanos) { + this.count = Objects.requireNonNull(count); + this.sleepNanos = sleepNanos; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean block() throws InterruptedException { + if (sleepNanos > 0) { + try { + NANOSECONDS.sleep(sleepNanos); + } catch (final InterruptedException e) { + // Don't throw an interrupted exception, but allow the thread to maintain its interrupted status. + Thread.currentThread().interrupt(); + } + } + return false; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isReleasable() { + return count.get() == 0; + } +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/counters/MultiObjectCounter.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/counters/MultiObjectCounter.java new file mode 100644 index 00000000000..0b7227984ef --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/counters/MultiObjectCounter.java @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.counters; + +import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Objects; + +/** + * This object counter combines multiple counters into a single counter. Every time a method on this object is called, + * the same method is also called on all child counters. + */ +public class MultiObjectCounter extends ObjectCounter { + + private final ObjectCounter[] counters; + + /** + * Constructor. + * + * @param counters one or more counters. The first counter in the array is the primary counter. {@link #getCount()} + * always return the count of the primary counter. When {@link #attemptOnRamp()} is called, + * on-ramping is attempted in the primary counter. If that fails, no other counter is on-ramped. If + * that succeeds then on-ramping is forced in all other counters. + */ + public MultiObjectCounter(@NonNull final ObjectCounter... counters) { + this.counters = Objects.requireNonNull(counters); + if (counters.length == 0) { + throw new IllegalArgumentException("Must have at least one counter"); + } + } + + /** + * {@inheritDoc} + */ + @Override + public void onRamp(final long delta) { + for (final ObjectCounter counter : counters) { + counter.onRamp(delta); + } + } + + /** + * {@inheritDoc} + */ + @Override + public boolean attemptOnRamp(final long delta) { + final boolean success = counters[0].attemptOnRamp(delta); + if (!success) { + return false; + } + + for (int i = 1; i < counters.length; i++) { + counters[i].forceOnRamp(delta); + } + + return true; + } + + /** + * {@inheritDoc} + */ + @Override + public void forceOnRamp(final long delta) { + for (final ObjectCounter counter : counters) { + counter.forceOnRamp(delta); + } + } + + /** + * {@inheritDoc} + */ + @Override + public void offRamp(final long delta) { + for (final ObjectCounter counter : counters) { + counter.offRamp(delta); + } + } + + /** + * {@inheritDoc} + */ + @Override + public long getCount() { + return counters[0].getCount(); + } + + /** + * {@inheritDoc} + */ + @Override + public void waitUntilEmpty() { + for (final ObjectCounter counter : counters) { + counter.waitUntilEmpty(); + } + } +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/counters/NoOpObjectCounter.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/counters/NoOpObjectCounter.java new file mode 100644 index 00000000000..dec4a59ec4f --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/counters/NoOpObjectCounter.java @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.counters; + +/** + * A counter that doesn't actually count. Saves us from having to do a (counter == null) check in the standard case. + */ +public class NoOpObjectCounter extends ObjectCounter { + + private static final NoOpObjectCounter INSTANCE = new NoOpObjectCounter(); + + /** + * Get the singleton instance. + * + * @return the singleton instance + */ + public static NoOpObjectCounter getInstance() { + return INSTANCE; + } + + /** + * Constructor. + */ + private NoOpObjectCounter() {} + + /** + * {@inheritDoc} + */ + @Override + public void onRamp(final long delta) {} + + /** + * {@inheritDoc} + */ + @Override + public boolean attemptOnRamp(final long delta) { + return true; + } + + /** + * {@inheritDoc} + */ + @Override + public void forceOnRamp(final long delta) {} + + /** + * {@inheritDoc} + */ + @Override + public void offRamp(final long delta) {} + + /** + * {@inheritDoc} + */ + @Override + public long getCount() { + return COUNT_UNDEFINED; + } + + /** + * {@inheritDoc} + */ + @Override + public void waitUntilEmpty() {} +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/counters/ObjectCounter.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/counters/ObjectCounter.java new file mode 100644 index 00000000000..d954c3b29b6 --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/counters/ObjectCounter.java @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.counters; + +/** + * A class that counts the number of objects in various parts of the pipeline. + */ +public abstract class ObjectCounter { + + /** + * The value returned by {@link #getCount()} if this object counter does not support counting. + */ + public static final long COUNT_UNDEFINED = -1L; + + /** + * Signal that an object is entering the part of the system that this object is being used to monitor. + */ + public abstract void onRamp(long delta); + + public final void onRamp() { + onRamp(1L); + } + + /** + * Signal that an object is entering the part of the system that this object is being used to monitor. Object is not + * "on ramped" if it is not immediately possible to do so without violating capacity constraints. + * + * @return true if there was available capacity to on ramp the object, false otherwise + */ + public abstract boolean attemptOnRamp(long delta); + + public final boolean attemptOnRamp() { + return attemptOnRamp(1L); + } + + /** + * Signal that an object is entering the part of the system that this object is being used to monitor. If there is + * not enough capacity to on ramp the object, on ramp it anyway and ignore all capacity restrictions. + */ + public abstract void forceOnRamp(long delta); + + public final void forceOnRamp() { + forceOnRamp(1L); + } + + /** + * Signal that an object is leaving the part of the system that this object is being used to monitor. + */ + public abstract void offRamp(long delta); + + public final void offRamp() { + offRamp(1L); + } + + /** + * Get the number of objects in the part of the system that this object is being used to monitor. If this object + * counter does not support counting, then {@link #COUNT_UNDEFINED} is returned. + */ + public abstract long getCount(); + + /** + * Blocks until the number of objects off-ramped is equal to the number of objects on-ramped. Does not prevent new + * objects from being on-ramped. If new objects are continuously on-ramped, it is possible that this method may + * block indefinitely. + */ + public abstract void waitUntilEmpty(); +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/counters/StandardObjectCounter.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/counters/StandardObjectCounter.java new file mode 100644 index 00000000000..456f72058e3 --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/counters/StandardObjectCounter.java @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.counters; + +import edu.umd.cs.findbugs.annotations.NonNull; +import java.time.Duration; +import java.util.concurrent.ForkJoinPool; +import java.util.concurrent.ForkJoinPool.ManagedBlocker; +import java.util.concurrent.atomic.AtomicLong; + +/** + * A utility for counting the number of objects in various parts of the pipeline. + */ +public class StandardObjectCounter extends ObjectCounter { + + private final AtomicLong count = new AtomicLong(0); + private final ManagedBlocker waitUntilEmptyBlocker; + + /** + * Constructor. + * + * @param sleepDuration when a method needs to block, the duration to sleep while blocking + */ + public StandardObjectCounter(@NonNull final Duration sleepDuration) { + final long sleepNanos = sleepDuration.toNanos(); + waitUntilEmptyBlocker = new EmptyBlocker(count, sleepNanos); + } + + /** + * {@inheritDoc} + */ + @Override + public void onRamp(final long delta) { + count.addAndGet(delta); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean attemptOnRamp(final long delta) { + count.getAndAdd(delta); + return true; + } + + /** + * {@inheritDoc} + */ + @Override + public void forceOnRamp(final long delta) { + count.getAndAdd(delta); + } + + /** + * {@inheritDoc} + */ + @Override + public void offRamp(final long delta) { + count.addAndGet(-delta); + } + + /** + * {@inheritDoc} + */ + @Override + public long getCount() { + return count.get(); + } + + /** + * {@inheritDoc} + */ + @Override + public void waitUntilEmpty() { + if (count.get() == 0) { + return; + } + + try { + ForkJoinPool.managedBlock(waitUntilEmptyBlocker); + } catch (final InterruptedException e) { + // This should be impossible. + Thread.currentThread().interrupt(); + throw new IllegalStateException("Interrupted while blocking on an waitUntilEmpty()"); + } + } +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/DeterministicWiringModel.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/DeterministicWiringModel.java new file mode 100644 index 00000000000..dddcc575b18 --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/DeterministicWiringModel.java @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.model; + +import com.swirlds.common.context.PlatformContext; +import com.swirlds.wiring.model.internal.deterministic.DeterministicHeartbeatScheduler; +import com.swirlds.wiring.model.internal.deterministic.DeterministicTaskSchedulerBuilder; +import com.swirlds.wiring.schedulers.builders.TaskSchedulerBuilder; +import com.swirlds.wiring.wires.output.NoOpOutputWire; +import com.swirlds.wiring.wires.output.OutputWire; +import edu.umd.cs.findbugs.annotations.NonNull; +import java.time.Duration; +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * A deterministic implementation of a wiring model. Suitable for testing, not intended for production use cases. + */ +public class DeterministicWiringModel extends TraceableWiringModel { + + private final PlatformContext platformContext; + + /** + * Work that we will perform in the current cycle. + */ + private List currentCycleWork = new ArrayList<>(); + + /** + * Work that we will perform in the next cycle. + */ + private List nextCycleWork = new ArrayList<>(); + + private final DeterministicHeartbeatScheduler heartbeatScheduler; + + /** + * Constructor. + * + * @param platformContext the context for this node + */ + DeterministicWiringModel(@NonNull final PlatformContext platformContext) { + super(false); + this.platformContext = Objects.requireNonNull(platformContext); + this.heartbeatScheduler = new DeterministicHeartbeatScheduler(this, platformContext.getTime(), "heartbeat"); + } + + /** + * Advance time. Amount of time that advances depends on how {@link com.swirlds.base.time.Time Time} has been + * advanced. + */ + public void tick() { + for (final Runnable work : currentCycleWork) { + work.run(); + } + + // Note: heartbeats are handled at their destinations during the next cycle. + heartbeatScheduler.tick(); + + currentCycleWork = nextCycleWork; + nextCycleWork = new ArrayList<>(); + } + + /** + * Submit a unit of work to be performed. + * + * @param work the work to be performed + */ + private void submitWork(@NonNull final Runnable work) { + // Work is never handled in the same cycle as when it is submitted. + nextCycleWork.add(work); + } + + /** + * {@inheritDoc} + */ + @NonNull + @Override + public TaskSchedulerBuilder schedulerBuilder(@NonNull final String name) { + return new DeterministicTaskSchedulerBuilder<>(platformContext, this, name, this::submitWork); + } + + /** + * {@inheritDoc} + */ + @NonNull + @Override + public OutputWire buildHeartbeatWire(@NonNull final Duration period) { + return heartbeatScheduler.buildHeartbeatWire(period); + } + + /** + * {@inheritDoc} + */ + @NonNull + @Override + public OutputWire getHealthMonitorWire() { + return new NoOpOutputWire<>(this, "HealthMonitor"); + } + + /** + * {@inheritDoc} + */ + @NonNull + @Override + public Duration getUnhealthyDuration() { + return Duration.ZERO; + } + + /** + * {@inheritDoc} + */ + @NonNull + @Override + public OutputWire buildHeartbeatWire(final double frequency) { + return heartbeatScheduler.buildHeartbeatWire(frequency); + } + + /** + * {@inheritDoc} + */ + @Override + public void start() { + throwIfStarted(); + markAsStarted(); + heartbeatScheduler.start(); + } + + /** + * {@inheritDoc} + */ + @Override + public void stop() { + throwIfNotStarted(); + } +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/StandardWiringModel.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/StandardWiringModel.java new file mode 100644 index 00000000000..889abc672e7 --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/StandardWiringModel.java @@ -0,0 +1,256 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.model; + +import static com.swirlds.wiring.schedulers.builders.TaskSchedulerType.NO_OP; +import static com.swirlds.wiring.schedulers.builders.TaskSchedulerType.SEQUENTIAL; +import static com.swirlds.wiring.schedulers.builders.TaskSchedulerType.SEQUENTIAL_THREAD; + +import com.swirlds.common.context.PlatformContext; +import com.swirlds.wiring.model.diagram.HyperlinkBuilder; +import com.swirlds.wiring.model.internal.monitor.HealthMonitor; +import com.swirlds.wiring.model.internal.standard.HeartbeatScheduler; +import com.swirlds.wiring.model.internal.standard.JvmAnchor; +import com.swirlds.wiring.schedulers.TaskScheduler; +import com.swirlds.wiring.schedulers.builders.TaskSchedulerBuilder; +import com.swirlds.wiring.schedulers.builders.internal.StandardTaskSchedulerBuilder; +import com.swirlds.wiring.schedulers.internal.SequentialThreadTaskScheduler; +import com.swirlds.wiring.wires.input.BindableInputWire; +import com.swirlds.wiring.wires.output.OutputWire; +import edu.umd.cs.findbugs.annotations.NonNull; +import edu.umd.cs.findbugs.annotations.Nullable; +import java.time.Duration; +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.ForkJoinPool; + +/** + * A standard implementation of a wiring model suitable for production use. + */ +public class StandardWiringModel extends TraceableWiringModel { + + /** + * The platform context. + */ + private final PlatformContext platformContext; + + /** + * Schedules heartbeats. Not created unless needed. + */ + private HeartbeatScheduler heartbeatScheduler = null; + + /** + * The scheduler that the health monitor runs on. + */ + private final TaskScheduler healthMonitorScheduler; + + /** + * The health monitor. + */ + private HealthMonitor healthMonitor; + + /** + * The input wire for the health monitor. + */ + private final BindableInputWire healthMonitorInputWire; + + /** + * Thread schedulers need to have their threads started/stopped. + */ + private final List> threadSchedulers = new ArrayList<>(); + + /** + * The default fork join pool, schedulers not explicitly assigned a pool will use this one. + */ + private final ForkJoinPool defaultPool; + + /** + * Used to prevent the JVM from prematurely exiting. + */ + private final JvmAnchor anchor; + + /** + * The amount of time that must pass before we start logging health information. + */ + private final Duration healthLogThreshold; + + /** + * The period at which we log health information. + */ + private final Duration healthLogPeriod; + + /** + * Constructor. + * + * @param builder the builder for this model, contains all needed configuration + */ + StandardWiringModel(@NonNull final WiringModelBuilder builder) { + super(builder.isHardBackpressureEnabled()); + + this.platformContext = Objects.requireNonNull(builder.getPlatformContext()); + this.defaultPool = Objects.requireNonNull(builder.getDefaultPool()); + + final TaskSchedulerBuilder healthMonitorSchedulerBuilder = this.schedulerBuilder("HealthMonitor"); + healthMonitorSchedulerBuilder.withHyperlink(HyperlinkBuilder.platformCoreHyperlink(HealthMonitor.class)); + if (builder.isHealthMonitorEnabled()) { + healthMonitorSchedulerBuilder + .withType(SEQUENTIAL) + .withUnhandledTaskMetricEnabled(true) + .withUnhandledTaskCapacity(builder.getHealthMonitorCapacity()); + } else { + healthMonitorSchedulerBuilder.withType(NO_OP); + } + + healthLogThreshold = builder.getHealthLogThreshold(); + healthLogPeriod = builder.getHealthLogPeriod(); + healthMonitorScheduler = healthMonitorSchedulerBuilder.build(); + healthMonitorInputWire = healthMonitorScheduler.buildInputWire("check system health"); + buildHeartbeatWire(builder.getHealthMonitorPeriod()).solderTo(healthMonitorInputWire); + + if (builder.isJvmAnchorEnabled()) { + anchor = new JvmAnchor(); + } else { + anchor = null; + } + } + + /** + * {@inheritDoc} + */ + @NonNull + @Override + public final TaskSchedulerBuilder schedulerBuilder(@NonNull final String name) { + throwIfStarted(); + return new StandardTaskSchedulerBuilder<>(platformContext, this, name, defaultPool); + } + + /** + * {@inheritDoc} + */ + @Override + @NonNull + public OutputWire buildHeartbeatWire(@NonNull final Duration period) { + throwIfStarted(); + return getHeartbeatScheduler().buildHeartbeatWire(period); + } + + /** + * {@inheritDoc} + */ + @NonNull + @Override + public OutputWire getHealthMonitorWire() { + return healthMonitorScheduler.getOutputWire(); + } + + /** + * {@inheritDoc} + */ + @NonNull + @Override + public Duration getUnhealthyDuration() { + throwIfNotStarted(); + return healthMonitor.getUnhealthyDuration(); + } + + /** + * {@inheritDoc} + */ + @Override + @NonNull + public OutputWire buildHeartbeatWire(final double frequency) { + throwIfStarted(); + return getHeartbeatScheduler().buildHeartbeatWire(frequency); + } + + /** + * {@inheritDoc} + */ + @Override + public void registerScheduler(@NonNull final TaskScheduler scheduler, @Nullable final String hyperlink) { + super.registerScheduler(scheduler, hyperlink); + if (scheduler.getType() == SEQUENTIAL_THREAD) { + threadSchedulers.add((SequentialThreadTaskScheduler) scheduler); + } + } + + /** + * {@inheritDoc} + */ + @Override + public void start() { + throwIfStarted(); + + if (anchor != null) { + anchor.start(); + } + + healthMonitor = new HealthMonitor(platformContext, schedulers, healthLogThreshold, healthLogPeriod); + healthMonitorInputWire.bind(healthMonitor::checkSystemHealth); + + markAsStarted(); + + // We don't have to do anything with the output of these sanity checks. + // The methods below will log errors if they find problems. + checkForCyclicalBackpressure(); + checkForIllegalDirectSchedulerUsage(); + checkForUnboundInputWires(); + + if (heartbeatScheduler != null) { + heartbeatScheduler.start(); + } + + for (final SequentialThreadTaskScheduler threadScheduler : threadSchedulers) { + threadScheduler.start(); + } + } + + /** + * {@inheritDoc} + */ + @Override + public void stop() { + throwIfNotStarted(); + + if (heartbeatScheduler != null) { + heartbeatScheduler.stop(); + } + + for (final SequentialThreadTaskScheduler threadScheduler : threadSchedulers) { + threadScheduler.stop(); + } + + if (anchor != null) { + anchor.stop(); + } + } + + /** + * Get the heartbeat scheduler, creating it if necessary. + * + * @return the heartbeat scheduler + */ + @NonNull + private HeartbeatScheduler getHeartbeatScheduler() { + if (heartbeatScheduler == null) { + heartbeatScheduler = new HeartbeatScheduler(this, platformContext.getTime(), "Heartbeat"); + } + return heartbeatScheduler; + } +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/TraceableWiringModel.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/TraceableWiringModel.java new file mode 100644 index 00000000000..9cabfc3bc5c --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/TraceableWiringModel.java @@ -0,0 +1,334 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.model; + +import static com.swirlds.wiring.model.internal.analysis.ModelVertexMetaType.SCHEDULER; +import static com.swirlds.wiring.schedulers.builders.TaskSchedulerType.DIRECT; +import static com.swirlds.wiring.schedulers.builders.TaskSchedulerType.DIRECT_THREADSAFE; + +import com.swirlds.wiring.model.diagram.ModelEdgeSubstitution; +import com.swirlds.wiring.model.diagram.ModelGroup; +import com.swirlds.wiring.model.diagram.ModelManualLink; +import com.swirlds.wiring.model.internal.analysis.CycleFinder; +import com.swirlds.wiring.model.internal.analysis.DirectSchedulerChecks; +import com.swirlds.wiring.model.internal.analysis.InputWireChecks; +import com.swirlds.wiring.model.internal.analysis.InputWireDescriptor; +import com.swirlds.wiring.model.internal.analysis.ModelEdge; +import com.swirlds.wiring.model.internal.analysis.ModelVertex; +import com.swirlds.wiring.model.internal.analysis.StandardVertex; +import com.swirlds.wiring.model.internal.analysis.WiringFlowchart; +import com.swirlds.wiring.schedulers.TaskScheduler; +import com.swirlds.wiring.schedulers.builders.TaskSchedulerType; +import com.swirlds.wiring.wires.SolderType; +import edu.umd.cs.findbugs.annotations.NonNull; +import edu.umd.cs.findbugs.annotations.Nullable; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; + +/** + * Common functionality for wiring model implementations. Has methods for registering information about the topology of + * wiring that is appropriate for internal use by the framework, but should not be exposed to the end users of the + * wiring framework. + */ +public abstract class TraceableWiringModel implements WiringModel { + + /** + * A map of vertex names to vertices. + */ + private final Map vertices = new HashMap<>(); + + /** + * A set of all edges in the model. + */ + private final Set edges = new HashSet<>(); + + /** + * Input wires that have been created. + */ + private final Set inputWires = new HashSet<>(); + + /** + * Input wires that have been bound to a handler. + */ + private final Set boundInputWires = new HashSet<>(); + + /** + * Input wires with at least one thing soldered to them. + */ + private final Set solderedInputWires = new HashSet<>(); + + /** + * All task schedulers in the model. + */ + protected final List> schedulers = new ArrayList<>(); + + /** + * True if start() has been called. + */ + private boolean started = false; + + /** + * True if backpressure is enabled. + */ + private final boolean backpressureEnabled; + + /** + * Constructor. + * + * @param backpressureEnabled true if backpressure is enabled + */ + TraceableWiringModel(final boolean backpressureEnabled) { + this.backpressureEnabled = backpressureEnabled; + } + + /** + * If true then backpressure is enabled. If false then this model will never apply backpressure internally. + * + * @return true if backpressure is enabled for this model + */ + public boolean isBackpressureEnabled() { + return backpressureEnabled; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean checkForCyclicalBackpressure() { + return CycleFinder.checkForCyclicalBackPressure(vertices.values()); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean checkForIllegalDirectSchedulerUsage() { + return DirectSchedulerChecks.checkForIllegalDirectSchedulerUse(vertices.values()); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean checkForUnboundInputWires() { + return InputWireChecks.checkForUnboundInputWires(inputWires, boundInputWires); + } + + /** + * {@inheritDoc} + */ + @NonNull + @Override + public String generateWiringDiagram( + @NonNull final List groups, + @NonNull final List substitutions, + @NonNull final List manualLinks, + final boolean moreMystery) { + addVertexForUnsolderedInputWires(moreMystery); + final WiringFlowchart flowchart = new WiringFlowchart(vertices, substitutions, groups, manualLinks); + return flowchart.render(); + } + + /** + * Add a special vertex for all unsoldered input wires. + */ + private void addVertexForUnsolderedInputWires(final boolean moreMystery) { + final Set unsolderedInputWires = new HashSet<>(inputWires); + unsolderedInputWires.removeAll(solderedInputWires); + + if (unsolderedInputWires.isEmpty()) { + return; + } + + final ModelVertex unsolderedDataSource = + new StandardVertex("Mystery Input", DIRECT_THREADSAFE, SCHEDULER, null, true); + vertices.put(unsolderedDataSource.getName(), unsolderedDataSource); + + for (final InputWireDescriptor unsolderedInputWire : unsolderedInputWires) { + final ModelVertex destination = getVertex(unsolderedInputWire.taskSchedulerName()); + + final String edgeDescription = moreMystery ? "mystery data" : unsolderedInputWire.name(); + final ModelEdge edge = new ModelEdge(unsolderedDataSource, destination, edgeDescription, true, true); + unsolderedDataSource.getOutgoingEdges().add(edge); + } + } + + /** + * Register a task scheduler with the wiring model. + * + * @param scheduler the task scheduler to register + * @param hyperlink the hyperlink to the documentation for this vertex, or null if there is no documentation + */ + public void registerScheduler(@NonNull final TaskScheduler scheduler, @Nullable final String hyperlink) { + throwIfStarted(); + Objects.requireNonNull(scheduler); + schedulers.add(scheduler); + registerVertex(scheduler.getName(), scheduler.getType(), hyperlink, scheduler.isInsertionBlocking()); + } + + /** + * Register a vertex in the wiring model. These are either task schedulers or wire transformers. + * + * @param vertexName the name of the vertex + * @param type the type of task scheduler that corresponds to this vertex. + * @param hyperlink the hyperlink to the documentation for this vertex, or null if there is no + * documentation + * @param insertionIsBlocking if true then insertion may block until capacity is available + */ + public void registerVertex( + @NonNull final String vertexName, + @NonNull final TaskSchedulerType type, + @Nullable final String hyperlink, + final boolean insertionIsBlocking) { + throwIfStarted(); + Objects.requireNonNull(vertexName); + Objects.requireNonNull(type); + final boolean unique = vertices.put( + vertexName, new StandardVertex(vertexName, type, SCHEDULER, hyperlink, insertionIsBlocking)) + == null; + if (!unique) { + throw new IllegalArgumentException("Duplicate vertex name: " + vertexName); + } + } + + /** + * Register an edge between two vertices. + * + * @param originVertex the origin vertex + * @param destinationVertex the destination vertex + * @param label the label of the edge + * @param solderType the type of solder connection + */ + public void registerEdge( + @NonNull final String originVertex, + @NonNull final String destinationVertex, + @NonNull final String label, + @NonNull final SolderType solderType) { + throwIfStarted(); + + final boolean blockingEdge = solderType == SolderType.PUT; + + final ModelVertex origin = getVertex(originVertex); + final ModelVertex destination = getVertex(destinationVertex); + final boolean blocking = blockingEdge && destination.isInsertionIsBlocking(); + + final ModelEdge edge = new ModelEdge(origin, destination, label, blocking, false); + origin.getOutgoingEdges().add(edge); + + final boolean unique = edges.add(edge); + if (!unique) { + throw new IllegalArgumentException( + "Duplicate edge: " + originVertex + " -> " + destinationVertex + ", label = " + label); + } + + solderedInputWires.add(new InputWireDescriptor(destinationVertex, label)); + } + + /** + * Register an input wire with the wiring model. For every input wire registered via this method, the model expects + * to see exactly one registration via {@link #registerInputWireBinding(String, String)}. + * + * @param taskSchedulerName the name of the task scheduler that the input wire is associated with + * @param inputWireName the name of the input wire + */ + public void registerInputWireCreation( + @NonNull final String taskSchedulerName, @NonNull final String inputWireName) { + throwIfStarted(); + + final boolean unique = inputWires.add(new InputWireDescriptor(taskSchedulerName, inputWireName)); + if (!unique) { + throw new IllegalStateException( + "Duplicate input wire " + inputWireName + " for scheduler " + taskSchedulerName); + } + } + + /** + * Register an input wire binding with the wiring model. For every input wire registered via + * {@link #registerInputWireCreation(String, String)}, the model expects to see exactly one registration via this + * method. + * + * @param taskSchedulerName the name of the task scheduler that the input wire is associated with + * @param inputWireName the name of the input wire + */ + public void registerInputWireBinding(@NonNull final String taskSchedulerName, @NonNull final String inputWireName) { + throwIfStarted(); + + final InputWireDescriptor descriptor = new InputWireDescriptor(taskSchedulerName, inputWireName); + + final boolean registered = inputWires.contains(descriptor); + if (!registered) { + throw new IllegalStateException( + "Input wire " + inputWireName + " for scheduler " + taskSchedulerName + " was not registered"); + } + + final boolean unique = boundInputWires.add(descriptor); + if (!unique) { + throw new IllegalStateException("Input wire " + inputWireName + " for scheduler " + taskSchedulerName + + " should not be bound more than once"); + } + } + + /** + * Throw an exception if start() has already been called. + */ + protected void throwIfStarted() { + if (started) { + throw new IllegalStateException("start() has already been called, operation not permitted."); + } + } + + /** + * Throw an exception if the wiring model has not been started. + */ + protected void throwIfNotStarted() { + if (!started) { + throw new IllegalStateException("start() has not been called, operation not permitted."); + } + } + + /** + * Mark the wiring model as started. + */ + protected void markAsStarted() { + started = true; + } + + /** + * Find an existing vertex + * + * @param vertexName the name of the vertex + * @return the vertex + */ + @NonNull + private ModelVertex getVertex(@NonNull final String vertexName) { + final ModelVertex vertex = vertices.get(vertexName); + if (vertex != null) { + return vertex; + } + + // Create an ad hoc vertex. + final StandardVertex adHocVertex = new StandardVertex(vertexName, DIRECT, SCHEDULER, null, true); + + vertices.put(vertexName, adHocVertex); + return adHocVertex; + } +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/WiringModel.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/WiringModel.java new file mode 100644 index 00000000000..f6448007789 --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/WiringModel.java @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.model; + +import com.swirlds.base.state.Startable; +import com.swirlds.base.state.Stoppable; +import com.swirlds.wiring.model.diagram.ModelEdgeSubstitution; +import com.swirlds.wiring.model.diagram.ModelGroup; +import com.swirlds.wiring.model.diagram.ModelManualLink; +import com.swirlds.wiring.schedulers.builders.TaskSchedulerBuilder; +import com.swirlds.wiring.schedulers.builders.TaskSchedulerType; +import com.swirlds.wiring.wires.output.OutputWire; +import edu.umd.cs.findbugs.annotations.NonNull; +import java.time.Duration; +import java.time.Instant; +import java.util.List; + +/** + * A wiring model is a collection of task schedulers and the wires connecting them. It can be used to analyze the wiring + * of a system and to generate diagrams. + */ +public interface WiringModel extends Startable, Stoppable { + + /** + * Get a new task scheduler builder. + * + * @param name the name of the task scheduler. Used for metrics and debugging. Must be unique. Must only contain + * alphanumeric characters and underscores. + * @param the data type of the scheduler's primary output wire + * @return a new task scheduler builder + */ + @NonNull + TaskSchedulerBuilder schedulerBuilder(@NonNull final String name); + + /** + * Check to see if there is cyclic backpressure in the wiring model. Cyclical back pressure can lead to deadlocks, + * and so it should be avoided at all costs. + * + *

+ * If this method finds cyclical backpressure, it will log a message that will fail standard platform tests. + * + * @return true if there is cyclical backpressure, false otherwise + */ + boolean checkForCyclicalBackpressure(); + + /** + * Task schedulers using the {@link TaskSchedulerType#DIRECT} strategy have very strict rules about how data can be + * added to input wires. This method checks to see if these rules are being followed. + * + *

+ * If this method finds illegal direct scheduler usage, it will log a message that will fail standard platform + * tests. + * + * @return true if there is illegal direct scheduler usage, false otherwise + */ + boolean checkForIllegalDirectSchedulerUsage(); + + /** + * Check to see if there are any input wires that are unbound. + * + *

+ * If this method detects unbound input wires in the model, it will log a message that will fail standard platform + * tests. + * + * @return true if there are unbound input wires, false otherwise + */ + boolean checkForUnboundInputWires(); + + /** + * Generate a mermaid style wiring diagram. + * + * @param groups optional groupings of vertices + * @param substitutions edges to substitute + * @param manualLinks manual links to add to the diagram + * @param moreMystery if enabled then use a generic label for all input from mystery sources. This removes + * information about mystery edges, but allows the diagram to be easier to groc. Turn this off + * when attempting to debug mystery edges. + * @return a mermaid style wiring diagram + */ + @NonNull + String generateWiringDiagram( + @NonNull List groups, + @NonNull List substitutions, + @NonNull List manualLinks, + boolean moreMystery); + + /** + * Build a wire that produces an instant (reflecting current time) at the specified rate. Note that the exact rate + * of heartbeats may vary. This is a best effort algorithm, and actual rates may vary depending on a variety of + * factors. + * + * @param period the period of the heartbeat. For example, setting a period of 100ms will cause the heartbeat to be + * sent at 10 hertz. Note that time is measured at millisecond precision, and so periods less than 1ms + * are not supported. + * @return the output wire + * @throws IllegalStateException if start() has already been called + */ + @NonNull + OutputWire buildHeartbeatWire(@NonNull final Duration period); + + /** + * Get the output of the wiring model's health monitor. The output of this wire is the length of time that any + * particular scheduler has been in an unhealthy state, or {@link Duration#ZERO} if all schedulers are currently + * healthy. + * + * @return the output wire + */ + @NonNull + OutputWire getHealthMonitorWire(); + + /** + * Get the duration that any particular scheduler has been concurrently unhealthy. This getter is intended for use + * by things outside of the wiring framework. For use within the framework, the proper way to access this value is + * via the wire returned by {@link #getHealthMonitorWire()}. + * + * @return the duration that any particular scheduler has been concurrently unhealthy, or {@link Duration#ZERO} if + * no scheduler is currently unhealthy + */ + @NonNull + Duration getUnhealthyDuration(); + + /** + * Build a wire that produces an instant (reflecting current time) at the specified rate. Note that the exact rate + * of heartbeats may vary. This is a best effort algorithm, and actual rates may vary depending on a variety of + * factors. + * + * @param frequency the frequency of the heartbeat in hertz. Note that time is measured at millisecond precision, + * and so frequencies greater than 1000hz are not supported. + * @return the output wire + */ + @NonNull + OutputWire buildHeartbeatWire(final double frequency); + + /** + * Start everything in the model that needs to be started. Performs static analysis of the wiring topology and + * writes errors to the logs if problems are detected. + */ + @Override + void start(); + + /** + * Stops everything in the model that needs to be stopped. + */ + @Override + void stop(); +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/WiringModelBuilder.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/WiringModelBuilder.java new file mode 100644 index 00000000000..2319ca5a40a --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/WiringModelBuilder.java @@ -0,0 +1,278 @@ +/* + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.model; + +import com.swirlds.common.context.PlatformContext; +import edu.umd.cs.findbugs.annotations.NonNull; +import java.time.Duration; +import java.util.Objects; +import java.util.concurrent.ForkJoinPool; + +/** + * Builds a {@link WiringModel}. + */ +public class WiringModelBuilder { + + private final PlatformContext platformContext; + + private boolean deterministicModeEnabled; + private ForkJoinPool defaultPool = ForkJoinPool.commonPool(); + private boolean healthMonitorEnabled = true; + private boolean hardBackpressureEnabled = false; + private boolean jvmAnchorEnabled = false; + private int healthMonitorCapacity = 500; + private Duration healthMonitorPeriod = Duration.ofMillis(100); + private Duration healthLogThreshold = Duration.ofSeconds(5); + private Duration healthLogPeriod = Duration.ofMinutes(10); + + /** + * Create a new builder. + * + * @param platformContext the platform context + * @return the builder + */ + @NonNull + public static WiringModelBuilder create(@NonNull final PlatformContext platformContext) { + return new WiringModelBuilder(platformContext); + } + + /** + * Constructor. + * + * @param platformContext the platform context + */ + private WiringModelBuilder(@NonNull final PlatformContext platformContext) { + this.platformContext = Objects.requireNonNull(platformContext); + } + + /** + * Specify the fork join pool to use for schedulers that don't specify a fork join pool. Schedulers not explicitly + * assigned a pool will use this one. Default is the common pool. + * + * @param defaultPool the default fork join pool + * @return this + */ + @NonNull + public WiringModelBuilder withDefaultPool(@NonNull final ForkJoinPool defaultPool) { + this.defaultPool = Objects.requireNonNull(defaultPool); + return this; + } + + /** + * Set if deterministic mode should be enabled. If enabled, the wiring model will be deterministic (and much + * slower). Suitable for simulations and testing. Default false. + * + * @param deterministicModeEnabled whether to enable deterministic mode + * @return this + */ + @NonNull + public WiringModelBuilder withDeterministicModeEnabled(final boolean deterministicModeEnabled) { + this.deterministicModeEnabled = deterministicModeEnabled; + return this; + } + + /** + * Set if the health monitor should be enabled. Default is true. + * + * @param healthMonitorEnabled whether to enable the health monitor + * @return this + */ + @NonNull + public WiringModelBuilder withHealthMonitorEnabled(final boolean healthMonitorEnabled) { + this.healthMonitorEnabled = healthMonitorEnabled; + return this; + } + + /** + * Set if hard backpressure should be enabled. Default is false. + * + * @param hardBackpressureEnabled whether to enable hard backpressure + * @return this + */ + @NonNull + public WiringModelBuilder withHardBackpressureEnabled(final boolean hardBackpressureEnabled) { + this.hardBackpressureEnabled = hardBackpressureEnabled; + return this; + } + + /** + * Set if the JVM anchor should be enabled. Default is false. If enabled and {@link WiringModel#start()} has been + * called, the JVM will not automatically exit due to lack of non-daemon threads until {@link WiringModel#stop()} is + * called. + * + * @param jvmAnchorEnabled whether to enable the JVM anchor + * @return this + */ + @NonNull + public WiringModelBuilder withJvmAnchorEnabled(final boolean jvmAnchorEnabled) { + this.jvmAnchorEnabled = jvmAnchorEnabled; + return this; + } + + /** + * Set the capacity of the health monitor's task scheduler's unhandled task capacity. Default is 500. + * + * @param healthMonitorCapacity the capacity of the health monitor + * @return this + */ + @NonNull + public WiringModelBuilder withHealthMonitorCapacity(final int healthMonitorCapacity) { + this.healthMonitorCapacity = healthMonitorCapacity; + return this; + } + + /** + * Set the period of the health monitor's task scheduler. Default is 100ms. + * + * @param healthMonitorPeriod the period of the health monitor + * @return this + */ + @NonNull + public WiringModelBuilder withHealthMonitorPeriod(@NonNull final Duration healthMonitorPeriod) { + this.healthMonitorPeriod = Objects.requireNonNull(healthMonitorPeriod); + return this; + } + + /** + * Set the amount of time a scheduler may be unhealthy before the platform is considered to be unhealthy. When a + * scheduler crosses this threshold, the health monitor will log a warning. Default is 5 seconds. + * + * @param healthThreshold the amount of time a scheduler may be unhealthy + * @return this + */ + @NonNull + public WiringModelBuilder withHealthLogThreshold(@NonNull final Duration healthThreshold) { + this.healthLogThreshold = Objects.requireNonNull(healthThreshold); + return this; + } + + /** + * Set the minimum amount of time that must pass between health log messages for the same scheduler. Default is 10 + * minutes. + * + * @param healthLogPeriod the minimum amount of time that must pass between health log messages + * @return this + */ + @NonNull + public WiringModelBuilder withHealthLogPeriod(@NonNull final Duration healthLogPeriod) { + this.healthLogPeriod = Objects.requireNonNull(healthLogPeriod); + return this; + } + + /** + * Build the wiring model. + * + * @param the type of wiring model + * @return the wiring model + */ + @SuppressWarnings("unchecked") + @NonNull + public T build() { + if (deterministicModeEnabled) { + return (T) new DeterministicWiringModel(platformContext); + } else { + return (T) new StandardWiringModel(this); + } + } + + /** + * Get the platform context. + * + * @return the platform context + */ + @NonNull + PlatformContext getPlatformContext() { + return platformContext; + } + + /** + * Get the default fork join pool for schedulers. Schedulers that have not been assigned a fork join pool should use + * this one. + * + * @return the default fork join pool + */ + @NonNull + ForkJoinPool getDefaultPool() { + return defaultPool; + } + + /** + * Check if the health monitor is enabled. + * + * @return true if the health monitor is enabled + */ + boolean isHealthMonitorEnabled() { + return healthMonitorEnabled; + } + + /** + * Check if hard backpressure is enabled. + * + * @return true if hard backpressure is enabled + */ + boolean isHardBackpressureEnabled() { + return hardBackpressureEnabled; + } + + /** + * Check if the JVM anchor is enabled. + * + * @return true if the JVM anchor is enabled + */ + boolean isJvmAnchorEnabled() { + return jvmAnchorEnabled; + } + + /** + * Get the capacity of the health monitor's task scheduler's unhandled task capacity. + * + * @return the capacity of the health monitor + */ + int getHealthMonitorCapacity() { + return healthMonitorCapacity; + } + + /** + * Get the period of the health monitor's task scheduler. + * + * @return the period of the health monitor + */ + @NonNull + Duration getHealthMonitorPeriod() { + return healthMonitorPeriod; + } + + /** + * Get the amount of time a scheduler may be unhealthy before the platform is considered to be unhealthy. + * + * @return the amount of time a scheduler may be unhealthy + */ + @NonNull + Duration getHealthLogThreshold() { + return healthLogThreshold; + } + + /** + * Get the minimum amount of time that must pass between health log messages for the same scheduler. + * + * @return the minimum amount of time that must pass between health log messages + */ + @NonNull + Duration getHealthLogPeriod() { + return healthLogPeriod; + } +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/diagram/HyperlinkBuilder.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/diagram/HyperlinkBuilder.java new file mode 100644 index 00000000000..aad92eebfa7 --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/diagram/HyperlinkBuilder.java @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.model.diagram; + +import edu.umd.cs.findbugs.annotations.NonNull; + +/** + * Given a class, derive a hyperlink to the github for that class's source code (in main). + */ +public final class HyperlinkBuilder { + + public static final String PLATFORM_CORE_ROOT = "https://github.com/hashgraph/hedera-services/blob/main/" + + "platform-sdk/swirlds-platform-core/src/main/java"; + + public static final String PLATFORM_COMMON_ROOT = + "https://github.com/hashgraph/hedera-services/blob/main/platform-sdk/swirlds-common/src/main/java"; + + /** + * Build a hyperlink to the platform core source code for the given class. Only works for things in the core + * platform module. + * + * @param clazz the class + * @return the hyperlink + */ + public static String platformCoreHyperlink(@NonNull final Class clazz) { + return buildHyperlink(PLATFORM_CORE_ROOT, clazz); + } + + /** + * Build a hyperlink to the platform common source code for the given class. Only works for things in the common + * platform module. + * + * @param clazz the class + * @return the hyperlink + */ + public static String platformCommonHyperlink(@NonNull final Class clazz) { + return buildHyperlink(PLATFORM_COMMON_ROOT, clazz); + } + + /** + * Get a github hyperlink to this class (in main). + * + * @param clazz the class + * @return the hyperlink + */ + @NonNull + public static String buildHyperlink(@NonNull final String root, @NonNull final Class clazz) { + + final String className = clazz.getName(); + final String[] parts = className.split("\\."); + + final StringBuilder sb = new StringBuilder(); + sb.append(root); + if (!root.endsWith("/")) { + sb.append("/"); + } + for (int i = 0; i < parts.length; i++) { + sb.append(parts[i]); + if (i < parts.length - 1) { + sb.append("/"); + } + } + sb.append(".java"); + + return sb.toString(); + } +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/diagram/ModelEdgeSubstitution.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/diagram/ModelEdgeSubstitution.java new file mode 100644 index 00000000000..8eb0a04697b --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/diagram/ModelEdgeSubstitution.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.model.diagram; + +import edu.umd.cs.findbugs.annotations.NonNull; + +/** + * Describes an edge substitution. A substituted edge is not drawn on the diagram, and is instead noted using a label. + * Useful for situations where a component is connected with a large number of other components (thus making the diagram + * hard to read). + * + * @param source the name of the scheduler that produces the output wire corresponding to the edge we are + * attempting to substitute (NOT the group name, if grouped) + * @param edge the label on the edge(s) to be substituted + * @param substitution the substitute label + */ +public record ModelEdgeSubstitution(@NonNull String source, @NonNull String edge, @NonNull String substitution) {} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/diagram/ModelGroup.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/diagram/ModelGroup.java new file mode 100644 index 00000000000..89ea7d34354 --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/diagram/ModelGroup.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.model.diagram; + +import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Set; + +/** + * Describes a group of components that should be visualized together in a wiring diagram. Specified via strings since + * this configuration is presumably read from the command line. + * + * @param name the name of the group + * @param elements the set of subcomponents in the group + * @param collapse true if the group should be collapsed into a single box + */ +public record ModelGroup(@NonNull String name, @NonNull Set elements, boolean collapse) + implements Comparable { + + /** + * Sorts groups by name. + */ + @Override + public int compareTo(@NonNull final ModelGroup that) { + return name.compareTo(that.name); + } +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/diagram/ModelManualLink.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/diagram/ModelManualLink.java new file mode 100644 index 00000000000..ad3c6f3b689 --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/diagram/ModelManualLink.java @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.model.diagram; + +import edu.umd.cs.findbugs.annotations.NonNull; + +/** + * Describes a manual link between two components. Useful for adding information to the diagram that is not captured by + * the wiring framework + * + * @param source the source scheduler + * @param label the label on the edge + * @param target the target scheduler + */ +public record ModelManualLink(@NonNull String source, @NonNull String label, @NonNull String target) {} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/CycleFinder.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/CycleFinder.java new file mode 100644 index 00000000000..b0c8b5a1b9d --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/CycleFinder.java @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.model.internal.analysis; + +import static com.swirlds.logging.legacy.LogMarker.EXCEPTION; +import static com.swirlds.logging.legacy.LogMarker.STARTUP; + +import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Deque; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +/** + * A utility for finding cyclical back pressure in a wiring model. + */ +public final class CycleFinder { + + private static final Logger logger = LogManager.getLogger(CycleFinder.class); + + private CycleFinder() {} + + /** + * Check for cyclical back pressure in a wiring model. + * + * @param vertices the vertices in the wiring model + * @return true if there is cyclical backpressure + */ + public static boolean checkForCyclicalBackPressure(@NonNull final Collection vertices) { + for (final ModelVertex vertex : vertices) { + if (checkForCycleStartingFromVertex(vertex)) { + return true; + } + } + logger.info(STARTUP.getMarker(), "No cyclical back pressure detected in wiring model."); + return false; + } + + /** + * Check for a cycle starting from a vertex. + * + * @param start the vertex to start from + * @return true if there is a cycle + */ + private static boolean checkForCycleStartingFromVertex(@NonNull final ModelVertex start) { + + // Perform a depth first traversal of the graph starting from the given vertex. + // Ignore any edge that doesn't apply back pressure. + + final Deque stack = new LinkedList<>(); + stack.addLast(start); + + final Set visited = new HashSet<>(); + + // Track the parent of each vertex. Useful for tracing the cycle after it's detected. + final Map parents = new HashMap<>(); + + while (!stack.isEmpty()) { + + final ModelVertex parent = stack.removeLast(); + + for (final ModelEdge childEdge : parent.getOutgoingEdges()) { + if (!childEdge.isInsertionIsBlocking()) { + // Ignore non-blocking edges. + continue; + } + + final ModelVertex child = childEdge.getDestination(); + + if (child.equals(start)) { + // We've found a cycle! + parents.put(child, parent); + logCycle(start, parents); + return true; + } + + if (visited.add(child)) { + stack.addLast(child); + parents.put(child, parent); + } + } + } + return false; + } + + /** + * Logs a warning message when cyclical back pressure is detected. Is intended to fail standard test validators. + * + * @param start the vertex where the cycle was detected + * @param parents records the parents for the traversal, used to trace the cycle + */ + private static void logCycle( + @NonNull final ModelVertex start, @NonNull final Map parents) { + + final StringBuilder sb = new StringBuilder(); + sb.append("Cyclical back pressure detected in wiring model. Cycle: "); + + // Following parent links will walk the cycle in reverse order. + final List path = new ArrayList<>(); + path.add(start); + ModelVertex target = start; + + while (!target.equals(start) || path.size() == 1) { + target = parents.get(target); + path.add(target); + } + + for (int i = path.size() - 1; i >= 0; i--) { + sb.append(path.get(i).getName()); + if (i > 0) { + sb.append(" -> "); + } + } + + logger.error(EXCEPTION.getMarker(), sb.toString()); + } +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/DirectSchedulerChecks.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/DirectSchedulerChecks.java new file mode 100644 index 00000000000..b42690038d2 --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/DirectSchedulerChecks.java @@ -0,0 +1,177 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.model.internal.analysis; + +import static com.swirlds.logging.legacy.LogMarker.EXCEPTION; +import static com.swirlds.logging.legacy.LogMarker.STARTUP; + +import com.swirlds.wiring.schedulers.builders.TaskSchedulerType; +import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Collection; +import java.util.Deque; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.Map; +import java.util.Set; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +/** + * A utility for checking direct scheduler use. + */ +public final class DirectSchedulerChecks { + + private static final Logger logger = LogManager.getLogger(DirectSchedulerChecks.class); + + private DirectSchedulerChecks() {} + + /** + * Check for illegal direct scheduler use. Rules are as follows: + * + *

    + *
  • + * Calling into a component with type {@link TaskSchedulerType#DIRECT DIRECT} + * from a component with {@link TaskSchedulerType#CONCURRENT CONCURRENT} is not + * allowed. + *
  • + *
  • + * Calling into a component with type {@link TaskSchedulerType#DIRECT DIRECT} + * from more than one component with type + * {@link TaskSchedulerType#SEQUENTIAL SEQUENTIAL} or type + * {@link TaskSchedulerType#SEQUENTIAL_THREAD SEQUENTIAL_THREAD} is not allowed. + *
  • + *
  • + * Calling into a component A with type + * {@link TaskSchedulerType#DIRECT DIRECT} from component B with type + * {@link TaskSchedulerType#DIRECT DIRECT} or type + * {@link TaskSchedulerType#DIRECT_THREADSAFE DIRECT_THREADSAFE} counts as a call + * into B from all components calling into component A. + *
  • + *
+ * + * @param vertices the vertices in the wiring model + * @return true if there is illegal direct scheduler use + */ + public static boolean checkForIllegalDirectSchedulerUse(@NonNull final Collection vertices) { + + boolean illegalAccessDetected = false; + + // Note: this is only logged if we detect a problem. + final StringBuilder sb = new StringBuilder("Illegal direct scheduler use detected:\n"); + + // A map from each direct vertex to a set of non-direct schedulers that call into it. + // If access is legal, then each of these sets should contain at most one element. + final Map> directVertexCallers = new HashMap<>(); + + for (final ModelVertex vertex : vertices) { + final TaskSchedulerType vertexType = vertex.getType(); + + if (vertexType == TaskSchedulerType.DIRECT || vertexType == TaskSchedulerType.DIRECT_THREADSAFE) { + // we can ignore direct schedulers at this phase. We care about calls INTO direct schedulers, + // not calls OUT OF direct schedulers. + continue; + } + + final Set directSchedulersAccessed = collectDirectVerticesAccessedByScheduler(vertex); + + if (vertexType == TaskSchedulerType.CONCURRENT && !directSchedulersAccessed.isEmpty()) { + // It is illegal for a concurrent scheduler to call into a direct scheduler. + illegalAccessDetected = true; + sb.append(" ") + .append(vertex.getName()) + .append(" is a concurrent scheduler that calls into direct scheduler(s):\n"); + for (final ModelVertex directScheduler : directSchedulersAccessed) { + sb.append(" - ").append(directScheduler.getName()).append("\n"); + } + } + + for (final ModelVertex directScheduler : directSchedulersAccessed) { + directVertexCallers + .computeIfAbsent(directScheduler, k -> new HashSet<>()) + .add(vertex); + } + } + + // Now, check to see if any direct schedulers are called into by more than one non-direct scheduler. + for (final Map.Entry> entry : directVertexCallers.entrySet()) { + final ModelVertex directScheduler = entry.getKey(); + final Set callers = entry.getValue(); + + if (callers.size() > 1) { + illegalAccessDetected = true; + sb.append(" ") + .append(directScheduler.getName()) + .append(" is called into by more than one non-direct scheduler:\n"); + for (final ModelVertex caller : callers) { + sb.append(" - ").append(caller.getName()).append("\n"); + } + } + } + + if (illegalAccessDetected) { + logger.error(EXCEPTION.getMarker(), sb.toString()); + } else { + logger.info(STARTUP.getMarker(), "No illegal direct scheduler use detected in the wiring model."); + } + + return illegalAccessDetected; + } + + /** + * Collect all direct vertices that are accessed by a scheduler. + * + * @param scheduler the scheduler to check + * @return the set of direct vertices accessed by the scheduler + */ + @NonNull + private static Set collectDirectVerticesAccessedByScheduler(@NonNull final ModelVertex scheduler) { + final Set directSchedulersAccessed = new HashSet<>(); + + final Deque stack = new LinkedList<>(); + final Set visited = new HashSet<>(); + + stack.addLast(scheduler); + visited.add(scheduler); + + while (!stack.isEmpty()) { + final ModelVertex next = stack.removeLast(); + + for (final ModelEdge edge : next.getOutgoingEdges()) { + final ModelVertex destination = edge.getDestination(); + final TaskSchedulerType destinationType = destination.getType(); + + if (destinationType != TaskSchedulerType.DIRECT + && destinationType != TaskSchedulerType.DIRECT_THREADSAFE) { + // we don't need to traverse edges that lead into non-direct schedulers + continue; + } + + if (destinationType == TaskSchedulerType.DIRECT) { + directSchedulersAccessed.add(destination); + } + + if (visited.add(destination)) { + stack.addLast(destination); + visited.add(destination); + } + } + } + + return directSchedulersAccessed; + } +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/GroupVertex.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/GroupVertex.java new file mode 100644 index 00000000000..73602735e3d --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/GroupVertex.java @@ -0,0 +1,171 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.model.internal.analysis; + +import static com.swirlds.wiring.model.internal.analysis.WiringFlowchart.GROUP_COLOR; +import static com.swirlds.wiring.model.internal.analysis.WiringFlowchart.TEXT_COLOR; + +import com.swirlds.wiring.schedulers.builders.TaskSchedulerType; +import edu.umd.cs.findbugs.annotations.NonNull; +import edu.umd.cs.findbugs.annotations.Nullable; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; +import java.util.Set; + +/** + * A vertex that represents a nexted group of vertices. + */ +public class GroupVertex implements ModelVertex { + + /** + * The name of the vertex. + */ + private final String name; + + /** + * The outgoing edges of this vertex. + */ + private final Set outgoingEdges = new HashSet<>(); + + /** + * Vertices that are contained within this group. + */ + private final List subVertices; + + private int depth; + private final Set substitutedInputs = new HashSet<>(); + + public GroupVertex(@NonNull final String name, @NonNull final List subVertices) { + + this.name = Objects.requireNonNull(name); + this.subVertices = Objects.requireNonNull(subVertices); + + for (final ModelVertex vertex : subVertices) { + vertex.setDepth(1); + } + } + + /** + * {@inheritDoc} + */ + @NonNull + @Override + public String getName() { + return name; + } + + /** + * {@inheritDoc} + */ + @NonNull + @Override + public TaskSchedulerType getType() { + return TaskSchedulerType.DIRECT; + } + + /** + * {@inheritDoc} + */ + @Nullable + @Override + public String getHyperlink() { + return null; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isInsertionIsBlocking() { + return true; + } + + /** + * {@inheritDoc} + */ + @NonNull + @Override + public Set getOutgoingEdges() { + return outgoingEdges; + } + + /** + * {@inheritDoc} + */ + @NonNull + @Override + public Set getSubstitutedInputs() { + return substitutedInputs; + } + + /** + * Get the vertices that are contained within this group. + * + * @return the vertices that are contained within this group + */ + public List getSubVertices() { + return subVertices; + } + + /** + * {@inheritDoc} + */ + @Override + public void setDepth(final int depth) { + this.depth = depth; + for (final ModelVertex vertex : subVertices) { + vertex.setDepth(depth + 1); + } + } + + /** + * Generate the style for this vertex. + * + * @return the style for this vertex + */ + @NonNull + private String generateStyle() { + final int baseRedValue = Integer.parseInt(String.valueOf(GROUP_COLOR.charAt(0)), 16); + final int baseGreenValue = Integer.parseInt(String.valueOf(GROUP_COLOR.charAt(1)), 16); + final int baseBlueValue = Integer.parseInt(String.valueOf(GROUP_COLOR.charAt(2)), 16); + + final int redValue = Math.min(0xF, baseRedValue + depth * 2); + final int greenValue = Math.min(0xF, baseGreenValue + depth * 2); + final int blueValue = Math.min(0xF, baseBlueValue + depth * 2); + + final String color = String.format("%X%X%X", redValue, greenValue, blueValue); + + return "fill:#" + color + ",stroke:#" + TEXT_COLOR + ",stroke-width:2px"; + } + + /** + * {@inheritDoc} + */ + @Override + public void render( + @NonNull final StringBuilder sb, + @NonNull final MermaidNameShortener nameProvider, + @NonNull final MermaidStyleManager styleManager) { + final String shortName = nameProvider.getShortVertexName(name); + styleManager.registerStyle(shortName, generateStyle()); + + sb.append("subgraph ").append(shortName).append("[\"").append(name).append("\"]\n"); + subVertices.stream().sorted().forEachOrdered(vertex -> vertex.render(sb, nameProvider, styleManager)); + sb.append("end\n"); + } +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/InputWireChecks.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/InputWireChecks.java new file mode 100644 index 00000000000..4984bf804fa --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/InputWireChecks.java @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.model.internal.analysis; + +import static com.swirlds.logging.legacy.LogMarker.EXCEPTION; +import static com.swirlds.logging.legacy.LogMarker.STARTUP; + +import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Set; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +/** + * Utilities for sanity checking input wires. + */ +public final class InputWireChecks { + + private static final Logger logger = LogManager.getLogger(InputWireChecks.class); + + private InputWireChecks() {} + + /** + * Make sure every input wire was properly bound. + * + * @param inputWires the input wires that were created + * @param boundInputWires the input wires that were bound + * @return true if there were unbound input wires, false otherwise + */ + public static boolean checkForUnboundInputWires( + @NonNull final Set inputWires, + @NonNull final Set boundInputWires) { + if (inputWires.size() == boundInputWires.size()) { + logger.info(STARTUP.getMarker(), "All input wires have been bound."); + return false; + } + + final StringBuilder sb = new StringBuilder(); + sb.append("The following input wire(s) were created but not bound:\n"); + for (final InputWireDescriptor inputWire : inputWires) { + if (!boundInputWires.contains(inputWire)) { + sb.append(" - ") + .append("Input wire '") + .append(inputWire.name()) + .append("' in scheduler '") + .append(inputWire.taskSchedulerName()) + .append("'\n"); + } + } + + logger.error(EXCEPTION.getMarker(), sb.toString()); + + return true; + } +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/InputWireDescriptor.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/InputWireDescriptor.java new file mode 100644 index 00000000000..0654c4cf7d9 --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/InputWireDescriptor.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.model.internal.analysis; + +import edu.umd.cs.findbugs.annotations.NonNull; + +/** + * Uniquely describes an input wire within a wiring model. + * + *

+ * This object exists so that standard input wires don't have to implement equals and hash code. + * + * @param taskSchedulerName the name of the task scheduler the input wire is bound to + * @param name the name of the input wire + */ +public record InputWireDescriptor(@NonNull String taskSchedulerName, @NonNull String name) {} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/MermaidNameShortener.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/MermaidNameShortener.java new file mode 100644 index 00000000000..ba81266fa67 --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/MermaidNameShortener.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.model.internal.analysis; + +import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.HashMap; +import java.util.Map; + +/** + * Generates shortened names in a mermaid wiring flowchart. Reduces the resulting flowchart size. + */ +public class MermaidNameShortener { + + private final Map vertexNameMap = new HashMap<>(); + + /** + * Get the name that should be used for a vertex with the given base name. + * + * @param baseName the base name of the vertex + * @return the name that should be used for a vertex with the given base name + */ + @NonNull + public String getShortVertexName(@NonNull final String baseName) { + return vertexNameMap.computeIfAbsent(baseName, this::generateShortVertexName); + } + + /** + * Generate a name for a vertex with the given base name. + * + * @param baseName the base name of the vertex + * @return the name that should be used for a vertex with the given base name + */ + @NonNull + private String generateShortVertexName(@NonNull final String baseName) { + return "v" + vertexNameMap.size(); + } +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/MermaidStyleManager.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/MermaidStyleManager.java new file mode 100644 index 00000000000..1743faf1751 --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/MermaidStyleManager.java @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.model.internal.analysis; + +import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Manages the styles in a mermaid flowchart. + */ +public class MermaidStyleManager { + + private final Map styleToStyleName = new HashMap<>(); + private final Map styleNameToStyle = new HashMap<>(); + private final Map /* classes with style */> styleNameToClasses = + new HashMap<>(); + + /** + * Register a style string. Will be attached to a vertex with the given base name at a later time. + * + * @param name the name of the vertex with the style + * @param style the style string + */ + public void registerStyle(@NonNull final String name, @NonNull final String style) { + final String styleName = styleToStyleName.computeIfAbsent(style, this::generateShortStyleName); + styleNameToStyle.put(styleName, style); + styleNameToClasses.computeIfAbsent(styleName, x -> new ArrayList<>()).add(name); + } + + /** + * Generate a name for a style. + * + * @param style the style string + * @return the name that should be used for a style + */ + @NonNull + private String generateShortStyleName(@NonNull final String style) { + return "s" + styleToStyleName.size(); + } + + /** + * Render the styles to the given string builder. + * + * @param sb the string builder + */ + public void render(@NonNull final StringBuilder sb) { + styleNameToStyle.keySet().stream().sorted().forEachOrdered(styleName -> { + sb.append("classDef ") + .append(styleName) + .append(" ") + .append(styleNameToStyle.get(styleName)) + .append("\n"); + sb.append("class "); + final List classNames = styleNameToClasses.get(styleName); + Collections.sort(classNames); + for (int i = 0; i < classNames.size(); i++) { + sb.append(classNames.get(i)); + if (i < classNames.size() - 1) { + sb.append(","); + } + } + sb.append(" ").append(styleName).append("\n"); + }); + } +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/ModelEdge.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/ModelEdge.java new file mode 100644 index 00000000000..a9d95e7e48c --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/ModelEdge.java @@ -0,0 +1,196 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.model.internal.analysis; + +import static com.swirlds.common.utility.NonCryptographicHashing.hash32; + +import edu.umd.cs.findbugs.annotations.NonNull; +import edu.umd.cs.findbugs.annotations.Nullable; +import java.util.Objects; + +/** + * A directed edge between to vertices. + */ +public class ModelEdge implements Comparable { + + private ModelVertex source; + private ModelVertex destination; + private final String label; + private final boolean insertionIsBlocking; + private final boolean manual; + + /** + * Constructor. + * + * @param source the source vertex + * @param destination the destination vertex + * @param label the label of the edge, if a label is not needed for an edge then holds the value "" + * @param insertionIsBlocking true if the insertion of this edge may block until capacity is available + * @param manual true if this edge has been manually added to the diagram, false if this edge + * represents something tracked by the wiring framework + */ + public ModelEdge( + @NonNull final ModelVertex source, + @NonNull final ModelVertex destination, + @NonNull final String label, + final boolean insertionIsBlocking, + final boolean manual) { + + this.source = Objects.requireNonNull(source); + this.destination = Objects.requireNonNull(destination); + this.label = Objects.requireNonNull(label); + this.insertionIsBlocking = insertionIsBlocking; + this.manual = manual; + } + + /** + * Get the source vertex. + * + * @return the source vertex + */ + @NonNull + public ModelVertex getSource() { + return source; + } + + /** + * Set the source vertex. + * + * @param source the source vertex + */ + public void setSource(@NonNull final StandardVertex source) { + this.source = Objects.requireNonNull(source); + } + + /** + * Get the destination vertex. + * + * @return the destination vertex + */ + @NonNull + public ModelVertex getDestination() { + return destination; + } + + /** + * Set the destination vertex. + * + * @param destination the destination vertex + */ + public void setDestination(@NonNull final StandardVertex destination) { + this.destination = Objects.requireNonNull(destination); + } + + /** + * Get the label of the edge. + * + * @return the label of the edge + */ + @NonNull + public String getLabel() { + return label; + } + + /** + * Get whether or not the insertion of this edge may block until capacity is available. + * + * @return true if the insertion of this edge may block until capacity is available + */ + public boolean isInsertionIsBlocking() { + return insertionIsBlocking; + } + + @Override + public boolean equals(@Nullable final Object obj) { + if (obj instanceof final ModelEdge that) { + return this.source.equals(that.source) + && this.destination.equals(that.destination) + && this.label.equals(that.label); + } + return false; + } + + @Override + public int hashCode() { + return hash32(source.hashCode(), destination.hashCode(), label.hashCode()); + } + + /** + * Useful for looking at a model in a debugger. + */ + @Override + public String toString() { + return source + " --" + label + "-->" + (insertionIsBlocking ? "" : ">") + " " + destination; + } + + /** + * Sorts first by source, then by destination, then by label. + */ + @Override + public int compareTo(@NonNull final ModelEdge that) { + if (!this.source.equals(that.source)) { + return this.source.compareTo(that.source); + } + if (!this.destination.equals(that.destination)) { + return this.destination.compareTo(that.destination); + } + return this.label.compareTo(that.label); + } + + /** + * Get the character for the outgoing end of this edge. + */ + @NonNull + private String getArrowCharacter() { + if (manual) { + return "o"; + } else { + return ">"; + } + } + + /** + * Render this edge to a string builder. + * + * @param sb the string builder to render to + * @param nameProvider provides short names for vertices + */ + public void render(@NonNull final StringBuilder sb, @NonNull final MermaidNameShortener nameProvider) { + + final String sourceName = nameProvider.getShortVertexName(source.getName()); + sb.append(sourceName).append(" "); + + if (insertionIsBlocking) { + if (label.isEmpty()) { + sb.append("--"); + } else { + sb.append("-- \"").append(label).append("\" --"); + } + } else { + if (label.isEmpty()) { + sb.append("-.-"); + } else { + sb.append("-. \"").append(label).append("\" .-"); + } + } + + sb.append(getArrowCharacter()).append(" "); + + final String destinationName = nameProvider.getShortVertexName(destination.getName()); + sb.append(destinationName).append("\n"); + } +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/ModelVertex.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/ModelVertex.java new file mode 100644 index 00000000000..6c1d7d52640 --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/ModelVertex.java @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.model.internal.analysis; + +import com.swirlds.wiring.schedulers.builders.TaskSchedulerType; +import edu.umd.cs.findbugs.annotations.NonNull; +import edu.umd.cs.findbugs.annotations.Nullable; +import java.util.Set; + +/** + * A vertex in a wiring model. + */ +public interface ModelVertex extends Comparable { + + /** + * Get the name of the vertex. + * + * @return the name + */ + @NonNull + String getName(); + + /** + * Get the type of task scheduler that corresponds to this vertex, or null if this vertex does not correspond to a + * task scheduler. + * + * @return the type of task scheduler that corresponds to this vertex, or null if this vertex does not correspond to + * a task scheduler + */ + @NonNull + TaskSchedulerType getType(); + + /** + * Get the hyperlink to the documentation for this vertex, or null if there is no documentation. + * + * @return the hyperlink to the documentation for this vertex, or null if there is no documentation + */ + @Nullable + String getHyperlink(); + + /** + * Get whether the insertion of this vertex may block until capacity is available. + * + * @return true if the insertion of this vertex may block until capacity is available + */ + boolean isInsertionIsBlocking(); + + /** + * Get the outgoing edges of this vertex. + * + * @return the outgoing edges of this vertex + */ + @NonNull + Set getOutgoingEdges(); + + /** + * Get substituted inputs for this vertex. + */ + @NonNull + Set getSubstitutedInputs(); + + /** + * Render this vertex in mermaid format. Used when generating a wiring diagram. + * + * @param sb the string builder to render to + * @param nameProvider provides short names for vertices + * @param styleManager manages the styles of vertices + */ + void render( + @NonNull final StringBuilder sb, + @NonNull final MermaidNameShortener nameProvider, + @NonNull final MermaidStyleManager styleManager); + + /** + * Sorts by name. + */ + default int compareTo(@NonNull final ModelVertex that) { + return this.getName().compareTo(that.getName()); + } + + /** + * Set the depth of this vertex in the wiring diagram. Depth increases by 1 for every group that this vertex is + * nested within. + * + * @param depth the depth of this vertex in the wiring diagram + */ + void setDepth(int depth); +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/ModelVertexMetaType.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/ModelVertexMetaType.java new file mode 100644 index 00000000000..74ec1c76014 --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/ModelVertexMetaType.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.model.internal.analysis; + +/** + * The type of a vertex in a wiring flowchart. Although the original graph will be constructed of SCHEDULER vertices + * alone, when generating the flowchart, verticies will be added, removed and combined. New verticies that do not + * directly correspond to a scheduler will be of type SUBSTITUTION or GROUP. + */ +public enum ModelVertexMetaType { + /** + * A vertex that corresponds to a scheduler. + */ + SCHEDULER, + /** + * A vertex that is used as a stand-in for a substituted edge. + */ + SUBSTITUTION, + /** + * A vertex that is used as a stand-in for a group of vertices. + */ + GROUP +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/StandardVertex.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/StandardVertex.java new file mode 100644 index 00000000000..52daa55b1de --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/StandardVertex.java @@ -0,0 +1,267 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.model.internal.analysis; + +import static com.swirlds.wiring.model.internal.analysis.WiringFlowchart.DIRECT_SCHEDULER_COLOR; +import static com.swirlds.wiring.model.internal.analysis.WiringFlowchart.GROUP_COLOR; +import static com.swirlds.wiring.model.internal.analysis.WiringFlowchart.SCHEDULER_COLOR; +import static com.swirlds.wiring.model.internal.analysis.WiringFlowchart.SUBSTITUTION_COLOR; +import static com.swirlds.wiring.model.internal.analysis.WiringFlowchart.TEXT_COLOR; + +import com.swirlds.wiring.schedulers.builders.TaskSchedulerType; +import edu.umd.cs.findbugs.annotations.NonNull; +import edu.umd.cs.findbugs.annotations.Nullable; +import java.util.HashSet; +import java.util.Objects; +import java.util.Set; + +/** + * A standard vertex in a wiring model. Does not contain sub-vertices. + */ +public class StandardVertex implements ModelVertex { + + /** + * The name of the vertex. + */ + private final String name; + + /** + * When tasks are inserted into this vertex, is this component capable of applying back pressure? + */ + private final boolean insertionIsBlocking; + + /** + * The task scheduler type that corresponds to this vertex. + */ + private final TaskSchedulerType type; + + /** + * The meta-type of this vertex. Used by the wiring diagram, ignored by other use cases. + */ + private final ModelVertexMetaType metaType; + + /** + * The outgoing edges of this vertex. + */ + private final Set outgoingEdges = new HashSet<>(); + + /** + * Used to track inputs that have been substituted during diagram generation. + */ + private final Set substitutedInputs = new HashSet<>(); + + /** + * The link to the documentation for this vertex. If null, no hyperlink will be generated. + */ + private final String hyperlink; + + /** + * Constructor. + * + * @param name the name of the vertex + * @param type the type of task scheduler that corresponds to this vertex + * @param metaType the meta-type of this vertex, used to generate a wiring diagram + * @param hyperlink the link to the documentation for this vertex, ignored if null + * @param insertionIsBlocking true if the insertion of this vertex may block until capacity is available + */ + public StandardVertex( + @NonNull final String name, + @NonNull final TaskSchedulerType type, + @NonNull final ModelVertexMetaType metaType, + @Nullable final String hyperlink, + final boolean insertionIsBlocking) { + this.name = Objects.requireNonNull(name); + this.type = Objects.requireNonNull(type); + this.metaType = Objects.requireNonNull(metaType); + this.hyperlink = hyperlink; + this.insertionIsBlocking = insertionIsBlocking; + } + + /** + * {@inheritDoc} + */ + @NonNull + @Override + public String getName() { + return name; + } + + /** + * {@inheritDoc} + */ + @NonNull + @Override + public TaskSchedulerType getType() { + return type; + } + + /** + * {@inheritDoc} + */ + @Nullable + @Override + public String getHyperlink() { + return hyperlink; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isInsertionIsBlocking() { + return insertionIsBlocking; + } + + /** + * {@inheritDoc} + */ + @NonNull + @Override + public Set getOutgoingEdges() { + return outgoingEdges; + } + + /** + * {@inheritDoc} + */ + @NonNull + @Override + public Set getSubstitutedInputs() { + return substitutedInputs; + } + + /** + * {@inheritDoc} + */ + @Override + public int hashCode() { + return name.hashCode(); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean equals(@Nullable final Object obj) { + if (obj instanceof final StandardVertex that) { + return name.equals(that.name); + } + return false; + } + + /** + * Makes the vertex nicer to look at in a debugger. + */ + @Override + public String toString() { + if (insertionIsBlocking) { + return "[" + name + "]"; + } else { + return "(" + name + ")"; + } + } + + /** + * Generate the style for this vertex. + * + * @return the style for this vertex + */ + @NonNull + private String generateStyle() { + final String color = + switch (metaType) { + case SUBSTITUTION -> SUBSTITUTION_COLOR; + case GROUP -> GROUP_COLOR; + case SCHEDULER -> switch (type) { + case DIRECT -> DIRECT_SCHEDULER_COLOR; + case DIRECT_THREADSAFE -> DIRECT_SCHEDULER_COLOR; + default -> SCHEDULER_COLOR; + }; + }; + + final StringBuilder sb = new StringBuilder(); + sb.append("fill:#").append(color).append(",stroke:#").append(TEXT_COLOR).append(",stroke-width:2px"); + + return sb.toString(); + } + + /** + * {@inheritDoc} + */ + @Override + public void render( + @NonNull final StringBuilder sb, + @NonNull final MermaidNameShortener nameProvider, + @NonNull final MermaidStyleManager styleManager) { + final String shortenedName = nameProvider.getShortVertexName(name); + sb.append(shortenedName); + + switch (metaType) { + case SUBSTITUTION -> sb.append("(("); + case GROUP -> sb.append("["); + case SCHEDULER -> { + switch (type) { + case CONCURRENT -> sb.append("[["); + case DIRECT -> sb.append("[/"); + case DIRECT_THREADSAFE -> sb.append("{{"); + default -> sb.append("["); + } + } + } + + sb.append("\""); + if (hyperlink != null) { + sb.append(""); + } + sb.append(name); + if (hyperlink != null) { + sb.append(""); + } + + if (!substitutedInputs.isEmpty()) { + sb.append("
"); + substitutedInputs.stream().sorted().forEachOrdered(sb::append); + } + + sb.append("\""); + + switch (metaType) { + case SUBSTITUTION -> sb.append("))"); + case GROUP -> sb.append("]"); + case SCHEDULER -> { + switch (type) { + case CONCURRENT -> sb.append("]]"); + case DIRECT -> sb.append("/]"); + case DIRECT_THREADSAFE -> sb.append("}}"); + default -> sb.append("]"); + } + } + } + + sb.append("\n"); + + styleManager.registerStyle(shortenedName, generateStyle()); + } + + /** + * {@inheritDoc} + */ + @Override + public void setDepth(final int depth) { + // ignored + } +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/WiringFlowchart.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/WiringFlowchart.java new file mode 100644 index 00000000000..788dba7c9c7 --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/WiringFlowchart.java @@ -0,0 +1,425 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.model.internal.analysis; + +import static com.swirlds.wiring.model.internal.analysis.ModelVertexMetaType.SCHEDULER; +import static com.swirlds.wiring.model.internal.analysis.ModelVertexMetaType.SUBSTITUTION; +import static com.swirlds.wiring.schedulers.builders.TaskSchedulerType.CONCURRENT; +import static com.swirlds.wiring.schedulers.builders.TaskSchedulerType.DIRECT; +import static com.swirlds.wiring.schedulers.builders.TaskSchedulerType.DIRECT_THREADSAFE; +import static com.swirlds.wiring.schedulers.builders.TaskSchedulerType.SEQUENTIAL; +import static com.swirlds.wiring.schedulers.builders.TaskSchedulerType.SEQUENTIAL_THREAD; + +import com.swirlds.wiring.model.diagram.ModelEdgeSubstitution; +import com.swirlds.wiring.model.diagram.ModelGroup; +import com.swirlds.wiring.model.diagram.ModelManualLink; +import com.swirlds.wiring.schedulers.builders.TaskSchedulerType; +import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; + +/** + * A readable wiring flowchart. + */ +public class WiringFlowchart { + + public static final String SCHEDULER_COLOR = "135f12"; + public static final String DIRECT_SCHEDULER_COLOR = "12305f"; + public static final String TEXT_COLOR = "000"; + public static final String GROUP_COLOR = "9cf"; + public static final String SUBSTITUTION_COLOR = "5f1212"; + + private final MermaidNameShortener nameProvider = new MermaidNameShortener(); + private final MermaidStyleManager styleManager = new MermaidStyleManager(); + + /** + * A map from vertex name to vertex. + */ + private final Map vertexMap; + + /** + * Draws a mermaid flowchart from the given wiring model. + * + * @param modelVertexMap a map from vertex name to vertex + * @param substitutions a list of edge substitutions to perform + * @param groups a list of groups to create + * @param manualLinks a list of manual links to draw + */ + public WiringFlowchart( + @NonNull final Map modelVertexMap, + @NonNull final List substitutions, + @NonNull final List groups, + @NonNull final List manualLinks) { + + Objects.requireNonNull(modelVertexMap); + + vertexMap = copyVertexMap(modelVertexMap); + addManualLinks(manualLinks); + substituteEdges(substitutions); + handleGroups(groups); + } + + /** + * Do a deep copy of the vertex map. Allows the local copy to be modified without affecting the original. + * + * @return a deep copy of the vertex map + */ + @NonNull + private Map copyVertexMap(@NonNull final Map original) { + final Map copy = new HashMap<>(); + + // First, copy the vertices without copying the edges. + // We should only encounter StandardVertex instances here. + for (final ModelVertex vertex : original.values()) { + if (!(vertex instanceof StandardVertex)) { + throw new IllegalStateException("Encountered a vertex that is not a StandardVertex"); + } + final StandardVertex vertexCopy = new StandardVertex( + vertex.getName(), + vertex.getType(), + SCHEDULER, + vertex.getHyperlink(), + vertex.isInsertionIsBlocking()); + + copy.put(vertex.getName(), vertexCopy); + } + + // Next, copy the edges. + for (final ModelVertex vertex : original.values()) { + for (final ModelEdge edge : vertex.getOutgoingEdges()) { + + final ModelVertex source = copy.get(edge.getSource().getName()); + final ModelVertex destination = copy.get(edge.getDestination().getName()); + + final ModelEdge edgeCopy = + new ModelEdge(source, destination, edge.getLabel(), edge.isInsertionIsBlocking(), false); + + source.getOutgoingEdges().add(edgeCopy); + } + } + + return copy; + } + + /** + * Add manual links to the flowchart. + * + * @param manualLinks the manual links to add + */ + private void addManualLinks(@NonNull final List manualLinks) { + for (final ModelManualLink link : manualLinks) { + final ModelVertex source = vertexMap.get(link.source()); + final ModelVertex destination = vertexMap.get(link.target()); + + if (source == null) { + throw new IllegalStateException("Source vertex " + link.source() + " does not exist."); + } + + if (destination == null) { + throw new IllegalStateException("Destination vertex " + link.target() + " does not exist."); + } + + final ModelEdge edge = new ModelEdge(source, destination, link.label(), false, true); + source.getOutgoingEdges().add(edge); + } + } + + /** + * Find all edges that need to be substituted and perform the substitution. + */ + private void substituteEdges(@NonNull final List substitutions) { + for (final ModelEdgeSubstitution substitution : substitutions) { + substituteEdge(substitution); + } + } + + /** + * Perform a single edge substitution. + */ + private void substituteEdge(@NonNull final ModelEdgeSubstitution substitution) { + // First, create a new vertex that will represent the destination of the substitution. + final StandardVertex substitutedVertex = + new StandardVertex(substitution.substitution(), DIRECT, SUBSTITUTION, null, true); + vertexMap.put(substitution.substitution(), substitutedVertex); + + // Next, cause all substituted edges to point to this new vertex. + for (final ModelVertex vertex : vertexMap.values()) { + if (!substitution.source().equals(vertex.getName())) { + // Only replace edges with the given source. + continue; + } + + final HashSet uniqueEdges = new HashSet<>(); + + for (final ModelEdge edge : vertex.getOutgoingEdges()) { + if (!substitution.edge().equals(edge.getLabel())) { + // Only replace destinations for edges with the given label. + uniqueEdges.add(edge); + continue; + } + + edge.getDestination().getSubstitutedInputs().add(substitution.substitution()); + edge.setDestination(substitutedVertex); + uniqueEdges.add(edge); + } + + vertex.getOutgoingEdges().clear(); + vertex.getOutgoingEdges().addAll(uniqueEdges); + } + } + + /** + * Handle groups in the order provided. + */ + private void handleGroups(@NonNull final List groups) { + for (final ModelGroup group : groups) { + final GroupVertex groupVertex = createGroup(group); + if (group.collapse()) { + collapseGroup(groupVertex); + } + } + } + + /** + * Collect all vertices that are contained within the given group and create a new vertex that represents the + * group. + * + * @param group the group to create a vertex for + * @return the new vertex + */ + private GroupVertex createGroup(@NonNull final ModelGroup group) { + // Collect all vertices that are contained within the group. + final List subVertices = new ArrayList<>(); + + for (final String vertexName : group.elements()) { + final ModelVertex subVertex = vertexMap.get(vertexName); + if (subVertex == null) { + throw new IllegalStateException("Vertex " + vertexName + + " is not in the vertex map. Can not insert into group " + group.name() + "."); + } + + subVertices.add(subVertex); + } + + // Remove those vertices from the vertex map. + for (final ModelVertex subVertex : subVertices) { + vertexMap.remove(subVertex.getName()); + } + + // Create a new vertex that represents the group. + final GroupVertex groupVertex = new GroupVertex(group.name(), subVertices); + vertexMap.put(group.name(), groupVertex); + + return groupVertex; + } + + /** + * Collapse a group of vertices into a single vertex. + * + * @param group the group to collapse + */ + private void collapseGroup(@NonNull final GroupVertex group) { + final List edges = collectEdges(); + final List groupVertices = collectGroupVertices(group); + + final Set hyperlinks = new HashSet<>(); + for (final ModelVertex vertex : groupVertices) { + if (vertex.getHyperlink() != null) { + hyperlinks.add(vertex.getHyperlink()); + } + } + final String hyperlink = hyperlinks.size() == 1 ? hyperlinks.iterator().next() : null; + + final TaskSchedulerType schedulerType = getSchedulerTypeOfCollapsedGroup(groupVertices); + + final StandardVertex newVertex = new StandardVertex(group.getName(), schedulerType, SCHEDULER, hyperlink, true); + + // Assign all vertices with a source that is collapsed to the new vertex. + // Redirect all vertices with a destination that is collapsed to the new vertex. + for (final ModelEdge edge : edges) { + final boolean collapsedSource = groupVertices.contains(edge.getSource()); + final boolean collapsedDestination = groupVertices.contains(edge.getDestination()); + + if (collapsedSource && collapsedDestination) { + // If the source and or destination are collapsed, then the edge is removed. + continue; + } + + if (collapsedSource) { + edge.setSource(newVertex); + newVertex.getOutgoingEdges().add(edge); + } + + if (collapsedDestination) { + // Add and remove from set to avoid possible duplicates. + edge.getSource().getOutgoingEdges().remove(edge); + edge.setDestination(newVertex); + edge.getSource().getOutgoingEdges().add(edge); + } + } + + // Extract substitutions from collapsed vertices. + for (final ModelVertex vertex : groupVertices) { + for (final String input : vertex.getSubstitutedInputs()) { + newVertex.getSubstitutedInputs().add(input); + } + } + + // Remove old vertices from the vertex map. + for (final ModelVertex vertex : groupVertices) { + vertexMap.remove(vertex.getName()); + } + + // Finally, add the new vertex to the vertex map. + vertexMap.put(newVertex.getName(), newVertex); + } + + /** + * When collapsing a group, determine the type of task scheduler type that should be displayed. + */ + @NonNull + private TaskSchedulerType getSchedulerTypeOfCollapsedGroup(@NonNull final List groupVertices) { + + boolean hasSequential = false; + boolean hasState = false; + + for (final ModelVertex vertex : groupVertices) { + if (vertex.getType() == CONCURRENT) { + return CONCURRENT; + } + + if (vertex.getType() == SEQUENTIAL || vertex.getType() == SEQUENTIAL_THREAD) { + if (hasSequential) { + // We've detected more than one sequential scheduler type, so there is more than one logical + // thread of execution within this group. + return CONCURRENT; + } + hasSequential = true; + } + + if (vertex.getType() == DIRECT) { + hasState = true; + } + } + + if (hasSequential) { + return SEQUENTIAL; + } else { + if (hasState) { + return DIRECT; + } + return DIRECT_THREADSAFE; + } + } + + /** + * Get all edges in the flowchart. + * + * @return all edges in the flowchart, sorted + */ + private List collectGroupVertices(@NonNull final GroupVertex group) { + final List vertices = new ArrayList<>(); + final LinkedList stack = new LinkedList<>(); + stack.addLast(group); + + while (!stack.isEmpty()) { + final ModelVertex vertex = stack.removeLast(); + vertices.add(vertex); + if (vertex instanceof final GroupVertex groupVertex) { + for (final ModelVertex subVertex : groupVertex.getSubVertices()) { + stack.addLast(subVertex); + } + } + } + + Collections.sort(vertices); + return vertices; + } + + /** + * Get all edges in the flowchart. + * + * @return all edges in the flowchart, sorted + */ + private List collectEdges() { + final List edges = new ArrayList<>(); + final LinkedList stack = new LinkedList<>(); + + for (final ModelVertex vertex : vertexMap.values()) { + stack.addLast(vertex); + } + + while (!stack.isEmpty()) { + final ModelVertex vertex = stack.removeLast(); + edges.addAll(vertex.getOutgoingEdges()); + if (vertex instanceof final GroupVertex groupVertex) { + for (final ModelVertex subVertex : groupVertex.getSubVertices()) { + stack.addLast(subVertex); + } + } + } + + Collections.sort(edges); + return edges; + } + + /** + * Render the flowchart to a string. + * + * @return the rendered flowchart + */ + @NonNull + public String render() { + final StringBuilder sb = new StringBuilder(); + sb.append( + """ + %%{ + init: { + 'flowchart': {'defaultRenderer': 'elk'}, + 'theme': 'base', + 'themeVariables': { + 'primaryColor': '#454545', + 'primaryTextColor': '#EEEEEE', + 'lineColor': '#C0C0C0' + } + } + }%% + flowchart TD + """); + + final List sortedVertices = + vertexMap.values().stream().sorted().toList(); + for (final ModelVertex vertex : sortedVertices) { + vertex.render(sb, nameProvider, styleManager); + } + + for (final ModelEdge edge : collectEdges()) { + edge.render(sb, nameProvider); + } + + styleManager.render(sb); + + return sb.toString(); + } +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/deterministic/DeterministicHeartbeatScheduler.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/deterministic/DeterministicHeartbeatScheduler.java new file mode 100644 index 00000000000..3ee3efdb3e8 --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/deterministic/DeterministicHeartbeatScheduler.java @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.model.internal.deterministic; + +import static com.swirlds.common.utility.CompareTo.isGreaterThanOrEqualTo; + +import com.swirlds.base.time.Time; +import com.swirlds.wiring.model.TraceableWiringModel; +import com.swirlds.wiring.model.internal.standard.AbstractHeartbeatScheduler; +import com.swirlds.wiring.model.internal.standard.HeartbeatTask; +import edu.umd.cs.findbugs.annotations.NonNull; +import java.time.Duration; +import java.time.Instant; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +/** + * A deterministic implementation of a heartbeat scheduler. + */ +public class DeterministicHeartbeatScheduler extends AbstractHeartbeatScheduler { + + /** + * This maps from the period of the heartbeat to the list of heartbeats that want to be notified with that period. + */ + private final Map> heartbeatsByPeriod = new HashMap<>(); + + /** + * The timestamps of the previous heartbeats sent for each group of heartbeats that subscribe to the same period. + */ + private final Map previousHeartbeats = new HashMap<>(); + + /** + * Constructor. + * + * @param model the wiring model containing this heartbeat scheduler + * @param time provides wall clock time + * @param name the name of the heartbeat scheduler + */ + public DeterministicHeartbeatScheduler( + @NonNull final TraceableWiringModel model, @NonNull final Time time, @NonNull final String name) { + super(model, time, name); + } + + /** + * Send out heartbeats based on the amount of time that has passed. + */ + public void tick() { + if (!started) { + throw new IllegalStateException("Cannot tick the heartbeat before it has started"); + } + + final Instant currentTime = time.now(); + + for (final Entry> entry : heartbeatsByPeriod.entrySet()) { + final Duration period = entry.getKey(); + final List tasksForPeriod = entry.getValue(); + final Instant previousHeartbeat = previousHeartbeats.get(period); + final Duration timeSinceLastHeartbeat = Duration.between(previousHeartbeat, currentTime); + if (isGreaterThanOrEqualTo(timeSinceLastHeartbeat, period)) { + for (final HeartbeatTask task : tasksForPeriod) { + task.run(); + } + previousHeartbeats.put(period, currentTime); + } + } + } + + /** + * {@inheritDoc} + */ + @Override + public void start() { + if (started) { + throw new IllegalStateException("Cannot start the heartbeat more than once"); + } + + final Instant currentTime = time.now(); + for (final HeartbeatTask task : tasks) { + final List tasksForPeriod = + heartbeatsByPeriod.computeIfAbsent(task.getPeriod(), k -> new ArrayList<>()); + tasksForPeriod.add(task); + previousHeartbeats.put(task.getPeriod(), currentTime); + } + + started = true; + } + + @Override + public void stop() { + if (!started) { + throw new IllegalStateException("Cannot stop the heartbeat before it has started"); + } + } +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/deterministic/DeterministicTaskScheduler.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/deterministic/DeterministicTaskScheduler.java new file mode 100644 index 00000000000..0589705d5c0 --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/deterministic/DeterministicTaskScheduler.java @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.model.internal.deterministic; + +import com.swirlds.wiring.counters.ObjectCounter; +import com.swirlds.wiring.model.TraceableWiringModel; +import com.swirlds.wiring.schedulers.TaskScheduler; +import com.swirlds.wiring.schedulers.builders.TaskSchedulerType; +import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Objects; +import java.util.function.Consumer; + +/** + * A deterministic implementation of a task scheduler. + * + * @param the output type of the scheduler (use {@link Void} for a task scheduler with no output type) + */ +public class DeterministicTaskScheduler extends TaskScheduler { + + private final Consumer submitWork; + + private final ObjectCounter onRamp; + private final ObjectCounter offRamp; + private final long capacity; + + /** + * Constructor. + * + * @param model the wiring model containing this task scheduler + * @param name the name of the task scheduler + * @param type the type of task scheduler + * @param onRamp counts when things are added to this scheduler to be eventually handled + * @param offRamp counts when things are handled by this scheduler + * @param capacity the maximum desired capacity for this task scheduler + * @param flushEnabled if true, then {@link #flush()} will be enabled, otherwise it will throw. + * @param squelchingEnabled if true, then squelching will be enabled, otherwise trying to squelch will throw. + * @param insertionIsBlocking when data is inserted into this task scheduler, will it block until capacity is + * available? + * @param submitWork a method where all work should be submitted + */ + protected DeterministicTaskScheduler( + @NonNull final TraceableWiringModel model, + @NonNull final String name, + @NonNull final TaskSchedulerType type, + @NonNull final ObjectCounter onRamp, + @NonNull final ObjectCounter offRamp, + final long capacity, + final boolean flushEnabled, + final boolean squelchingEnabled, + final boolean insertionIsBlocking, + @NonNull final Consumer submitWork) { + super(model, name, type, flushEnabled, squelchingEnabled, insertionIsBlocking); + + this.onRamp = Objects.requireNonNull(onRamp); + this.offRamp = Objects.requireNonNull(offRamp); + this.submitWork = Objects.requireNonNull(submitWork); + this.capacity = capacity; + } + + /** + * {@inheritDoc} + */ + @Override + public long getUnprocessedTaskCount() { + return onRamp.getCount(); + } + + /** + * {@inheritDoc} + */ + @Override + public long getCapacity() { + return capacity; + } + + /** + * {@inheritDoc} + */ + @Override + public void flush() { + // Future work: flushing is incompatible with deterministic task schedulers. + // This is because flushing currently requires us to block thread A while + // thread B does work, but with turtle there is only a single thread. + } + + /** + * {@inheritDoc} + */ + @Override + protected void put(@NonNull final Consumer handler, @NonNull final Object data) { + onRamp.onRamp(); + submitWork.accept(() -> { + handler.accept(data); + offRamp.offRamp(); + }); + } + + /** + * {@inheritDoc} + */ + @Override + protected boolean offer(@NonNull final Consumer handler, @NonNull final Object data) { + if (onRamp.attemptOnRamp()) { + submitWork.accept(() -> { + handler.accept(data); + offRamp.offRamp(); + }); + return true; + } + return false; + } + + /** + * {@inheritDoc} + */ + @Override + protected void inject(@NonNull final Consumer handler, @NonNull final Object data) { + onRamp.forceOnRamp(); + submitWork.accept(() -> { + handler.accept(data); + offRamp.offRamp(); + }); + } +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/deterministic/DeterministicTaskSchedulerBuilder.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/deterministic/DeterministicTaskSchedulerBuilder.java new file mode 100644 index 00000000000..c51b8ed5591 --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/deterministic/DeterministicTaskSchedulerBuilder.java @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.model.internal.deterministic; + +import static com.swirlds.wiring.schedulers.builders.TaskSchedulerType.DIRECT_THREADSAFE; +import static com.swirlds.wiring.schedulers.builders.TaskSchedulerType.NO_OP; + +import com.swirlds.common.context.PlatformContext; +import com.swirlds.common.metrics.extensions.FractionalTimer; +import com.swirlds.common.metrics.extensions.NoOpFractionalTimer; +import com.swirlds.wiring.model.DeterministicWiringModel; +import com.swirlds.wiring.model.TraceableWiringModel; +import com.swirlds.wiring.schedulers.TaskScheduler; +import com.swirlds.wiring.schedulers.builders.internal.AbstractTaskSchedulerBuilder; +import com.swirlds.wiring.schedulers.internal.DirectTaskScheduler; +import com.swirlds.wiring.schedulers.internal.NoOpTaskScheduler; +import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Objects; +import java.util.concurrent.ForkJoinPool; +import java.util.function.Consumer; + +/** + * Builds schedulers for a {@link DeterministicWiringModel}. + * + * @param + */ +public class DeterministicTaskSchedulerBuilder extends AbstractTaskSchedulerBuilder { + + private final Consumer submitWork; + + /** + * Constructor. + * + * @param platformContext the platform context + * @param model the wiring model + * @param name the name of the task scheduler. Used for metrics and debugging. Must be unique. Must only + * contain alphanumeric characters and underscores. + * @param submitWork a method where all work should be submitted + */ + public DeterministicTaskSchedulerBuilder( + @NonNull final PlatformContext platformContext, + @NonNull final TraceableWiringModel model, + @NonNull final String name, + @NonNull final Consumer submitWork) { + super(platformContext, model, name, ForkJoinPool.commonPool()); + this.submitWork = Objects.requireNonNull(submitWork); + } + + /** + * {@inheritDoc} + */ + @NonNull + @Override + public TaskScheduler build() { + + final boolean insertionIsBlocking = unhandledTaskCapacity != UNLIMITED_CAPACITY || externalBackPressure; + + final Counters counters = buildCounters(); + final FractionalTimer busyFractionTimer = NoOpFractionalTimer.getInstance(); + + final TaskScheduler scheduler = + switch (type) { + case CONCURRENT, SEQUENTIAL, SEQUENTIAL_THREAD -> new DeterministicTaskScheduler<>( + model, + name, + type, + counters.onRamp(), + counters.offRamp(), + unhandledTaskCapacity, + flushingEnabled, + squelchingEnabled, + insertionIsBlocking, + submitWork); + case DIRECT, DIRECT_THREADSAFE -> new DirectTaskScheduler<>( + model, + name, + buildUncaughtExceptionHandler(), + counters.onRamp(), + counters.offRamp(), + squelchingEnabled, + busyFractionTimer, + type == DIRECT_THREADSAFE); + case NO_OP -> new NoOpTaskScheduler<>(model, name, type, flushingEnabled, squelchingEnabled); + }; + + if (type != NO_OP) { + model.registerScheduler(scheduler, hyperlink); + } + + return scheduler; + } +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/monitor/HealthMonitor.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/monitor/HealthMonitor.java new file mode 100644 index 00000000000..0f63ef7615b --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/monitor/HealthMonitor.java @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.model.internal.monitor; + +import static com.swirlds.common.utility.CompareTo.isGreaterThan; + +import com.swirlds.common.context.PlatformContext; +import com.swirlds.wiring.schedulers.TaskScheduler; +import com.swirlds.wiring.schedulers.builders.TaskSchedulerBuilder; +import edu.umd.cs.findbugs.annotations.NonNull; +import edu.umd.cs.findbugs.annotations.Nullable; +import java.time.Duration; +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.atomic.AtomicReference; + +/** + * Monitors the health of a wiring model. A healthy wiring model is a model without too much work backed up in queues. + * An unhealthy wiring model is a model with at least one queue that is backed up with too much work. + */ +public class HealthMonitor { + + /** + * A list of task schedulers without unlimited capacities. + */ + private final List> schedulers; + + /** + * Corresponds to the schedulers list. The instant at the index of a scheduler indicates the last timestamp at which + * that scheduler was observed to be in a healthy state. + */ + private final List lastHealthyTimes = new ArrayList<>(); + + /** + * The previous value returned by {@link #checkSystemHealth(Instant)}. Used to avoid sending repeat output. + */ + private Duration previouslyReportedDuration = Duration.ZERO; + + /** + * Metrics for the health monitor. + */ + private final HealthMonitorMetrics metrics; + + /** + * Logs health issues. + */ + private final HealthMonitorLogger logger; + + /** + * The longest duration that any single scheduler has been concurrently unhealthy. + */ + private final AtomicReference longestUnhealthyDuration = new AtomicReference<>(Duration.ZERO); + + /** + * Constructor. + * + * @param platformContext the platform context + * @param schedulers the task schedulers to monitor + * @param healthLogThreshold the amount of time that must pass before we start logging health information + * @param healthLogPeriod the period at which we log health information + */ + public HealthMonitor( + @NonNull final PlatformContext platformContext, + @NonNull final List> schedulers, + @NonNull final Duration healthLogThreshold, + @NonNull final Duration healthLogPeriod) { + + metrics = new HealthMonitorMetrics(platformContext, healthLogThreshold); + + this.schedulers = new ArrayList<>(); + for (final TaskScheduler scheduler : schedulers) { + if (scheduler.getCapacity() != TaskSchedulerBuilder.UNLIMITED_CAPACITY) { + this.schedulers.add(Objects.requireNonNull(scheduler)); + lastHealthyTimes.add(null); + } + } + + logger = new HealthMonitorLogger(platformContext, this.schedulers, healthLogThreshold, healthLogPeriod); + } + + /** + * Called periodically. Scans the task schedulers for health issues. + * + * @param now the current time + * @return the amount of time any single scheduler has been concurrently unhealthy. Returns {@link Duration#ZERO} if + * all schedulers are healthy, returns null if there is no change in health status. + */ + @Nullable + public Duration checkSystemHealth(@NonNull final Instant now) { + Duration longestUnhealthyDuration = Duration.ZERO; + + for (int i = 0; i < lastHealthyTimes.size(); i++) { + final TaskScheduler scheduler = schedulers.get(i); + final boolean healthy = scheduler.getUnprocessedTaskCount() <= scheduler.getCapacity(); + if (healthy) { + lastHealthyTimes.set(i, null); + } else { + if (lastHealthyTimes.get(i) == null) { + lastHealthyTimes.set(i, now); + } + + final Duration unhealthyDuration = Duration.between(lastHealthyTimes.get(i), now); + logger.reportUnhealthyScheduler(scheduler, unhealthyDuration); + if (isGreaterThan(unhealthyDuration, longestUnhealthyDuration)) { + longestUnhealthyDuration = unhealthyDuration; + } + } + } + + try { + if (longestUnhealthyDuration.equals(previouslyReportedDuration)) { + // Only report when there is a change in health status + return null; + } else { + this.longestUnhealthyDuration.set(longestUnhealthyDuration); + metrics.reportUnhealthyDuration(longestUnhealthyDuration); + return longestUnhealthyDuration; + } + } finally { + previouslyReportedDuration = longestUnhealthyDuration; + } + } + + /** + * Get the duration that any particular scheduler has been concurrently unhealthy. + * + * @return the duration that any particular scheduler has been concurrently unhealthy, or {@link Duration#ZERO} if + * no scheduler is currently unhealthy + */ + @NonNull + public Duration getUnhealthyDuration() { + return longestUnhealthyDuration.get(); + } +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/monitor/HealthMonitorLogger.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/monitor/HealthMonitorLogger.java new file mode 100644 index 00000000000..eb5db196c3d --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/monitor/HealthMonitorLogger.java @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.model.internal.monitor; + +import static com.swirlds.common.units.TimeUnit.UNIT_NANOSECONDS; +import static com.swirlds.logging.legacy.LogMarker.STARTUP; + +import com.swirlds.common.context.PlatformContext; +import com.swirlds.common.utility.CompareTo; +import com.swirlds.common.utility.throttle.RateLimitedLogger; +import com.swirlds.wiring.schedulers.TaskScheduler; +import edu.umd.cs.findbugs.annotations.NonNull; +import java.time.Duration; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +/** + * Encapsulates logging for the wiring health monitor. + */ +public class HealthMonitorLogger { + + private static final Logger logger = LogManager.getLogger(HealthMonitorLogger.class); + + /** + * The amount of time that must pass before we start logging health information. + */ + private final Duration healthLogThreshold; + + /** + * A rate limited logger for each scheduler. + */ + private final Map schedulerLoggers = new HashMap<>(); + + /** + * Constructor. + * + * @param platformContext the platform context + * @param schedulers the task schedulers being monitored + * @param healthLogThreshold the amount of time that must pass before we start logging health information + * @param healthLogPeriod the period at which we log health information + */ + public HealthMonitorLogger( + @NonNull final PlatformContext platformContext, + @NonNull final List> schedulers, + @NonNull final Duration healthLogThreshold, + @NonNull final Duration healthLogPeriod) { + + this.healthLogThreshold = healthLogThreshold; + for (final TaskScheduler scheduler : schedulers) { + final String schedulerName = scheduler.getName(); + final RateLimitedLogger rateLimitedLogger = + new RateLimitedLogger(logger, platformContext.getTime(), healthLogPeriod); + schedulerLoggers.put(schedulerName, rateLimitedLogger); + } + } + + /** + * Report an unhealthy scheduler. + * + * @param scheduler the unhealthy scheduler + * @param unhealthyDuration the duration for which the scheduler has been unhealthy + */ + public void reportUnhealthyScheduler( + @NonNull final TaskScheduler scheduler, @NonNull final Duration unhealthyDuration) { + if (CompareTo.isLessThan(unhealthyDuration, healthLogThreshold)) { + // Don't log about small unhealthy durations + return; + } + + final RateLimitedLogger rateLimitedLogger = schedulerLoggers.get(scheduler.getName()); + final String formattedDuration = + UNIT_NANOSECONDS.buildFormatter(unhealthyDuration.toNanos()).render(); + rateLimitedLogger.warn( + STARTUP.getMarker(), + "Task scheduler {} has been unhealthy for {}. It currently has {}/{} unhandled tasks.", + scheduler.getName(), + formattedDuration, + scheduler.getUnprocessedTaskCount(), + scheduler.getCapacity()); + } +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/monitor/HealthMonitorMetrics.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/monitor/HealthMonitorMetrics.java new file mode 100644 index 00000000000..3e69d441b5e --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/monitor/HealthMonitorMetrics.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.model.internal.monitor; + +import static com.swirlds.common.utility.CompareTo.isLessThan; + +import com.swirlds.common.context.PlatformContext; +import com.swirlds.common.metrics.DurationGauge; +import com.swirlds.metrics.api.IntegerGauge; +import edu.umd.cs.findbugs.annotations.NonNull; +import java.time.Duration; +import java.time.temporal.ChronoUnit; + +/** + * Encapsulates metrics for the wiring health monitor. + */ +public class HealthMonitorMetrics { + + private static final DurationGauge.Config DURATION_GAUGE_CONFIG = new DurationGauge.Config( + "platform", "unhealthyDuration", ChronoUnit.SECONDS) + .withDescription("The duration that the most unhealthy scheduler has been in an unhealthy state."); + private final DurationGauge unhealthyDuration; + + private static final IntegerGauge.Config HEALTHY_CONFIG = new IntegerGauge.Config("platform", "healthy") + .withDescription("1 if the platform is healthy, 0 otherwise. " + + "Triggers once unhealthyDuration metric crosses configured threshold."); + private final IntegerGauge healthy; + + private final Duration healthThreshold; + + /** + * Constructor. + * + * @param platformContext the platform context + * @param healthLogThreshold the duration after which the system is considered unhealthy + */ + public HealthMonitorMetrics( + @NonNull final PlatformContext platformContext, @NonNull final Duration healthLogThreshold) { + unhealthyDuration = platformContext.getMetrics().getOrCreate(DURATION_GAUGE_CONFIG); + healthy = platformContext.getMetrics().getOrCreate(HEALTHY_CONFIG); + + // Always initialize the system as healthy + healthy.set(1); + + healthThreshold = healthLogThreshold; + } + + /** + * Set the unhealthy duration. + * + * @param duration the unhealthy duration + */ + public void reportUnhealthyDuration(@NonNull final Duration duration) { + unhealthyDuration.set(duration); + healthy.set(isLessThan(duration, healthThreshold) ? 1 : 0); + } +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/standard/AbstractHeartbeatScheduler.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/standard/AbstractHeartbeatScheduler.java new file mode 100644 index 00000000000..8d622581c15 --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/standard/AbstractHeartbeatScheduler.java @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.model.internal.standard; + +import static com.swirlds.wiring.model.diagram.HyperlinkBuilder.platformCommonHyperlink; + +import com.swirlds.base.time.Time; +import com.swirlds.wiring.model.TraceableWiringModel; +import com.swirlds.wiring.schedulers.builders.TaskSchedulerType; +import com.swirlds.wiring.wires.output.OutputWire; +import edu.umd.cs.findbugs.annotations.NonNull; +import java.time.Duration; +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * A scheduler that produces heartbeats at a specified rate. + */ +public abstract class AbstractHeartbeatScheduler { + + private final TraceableWiringModel model; + protected final Time time; + protected final String name; + protected final List tasks = new ArrayList<>(); + protected boolean started; + + /** + * Constructor. + * + * @param model the wiring model containing this heartbeat scheduler + * @param time provides wall clock time + * @param name the name of the heartbeat scheduler + */ + public AbstractHeartbeatScheduler( + @NonNull final TraceableWiringModel model, @NonNull final Time time, @NonNull final String name) { + this.model = Objects.requireNonNull(model); + this.time = Objects.requireNonNull(time); + this.name = Objects.requireNonNull(name); + model.registerVertex( + name, TaskSchedulerType.SEQUENTIAL, platformCommonHyperlink(AbstractHeartbeatScheduler.class), false); + } + + /** + * Build a wire that produces an instant (reflecting current time) at the specified rate. Note that the exact rate + * of heartbeats may vary. This is a best effort algorithm, and actual rates may vary depending on a variety of + * factors. + * + * @param period the period of the heartbeat. For example, setting a period of 100ms will cause the heartbeat to be + * sent at 10 hertz. Note that time is measured at millisecond precision, and so periods less than 1ms + * are not supported. + * @return the output wire + * @throws IllegalStateException if start has already been called + */ + @NonNull + public OutputWire buildHeartbeatWire(@NonNull final Duration period) { + if (started) { + throw new IllegalStateException("Cannot create heartbeat wires after the heartbeat has started"); + } + + if (period.isNegative() || period.isZero()) { + throw new IllegalArgumentException("Period must be positive"); + } + + if (period.toMillis() == 0) { + throw new IllegalArgumentException( + "Time is measured at millisecond precision, and so periods less than 1ms are not supported. " + + "Requested period: " + period); + } + + final HeartbeatTask task = new HeartbeatTask(model, name, time, period); + tasks.add(task); + + return task.getOutputWire(); + } + + /** + * Build a wire that produces an instant (reflecting current time) at the specified rate. Note that the exact rate + * of heartbeats may vary. This is a best effort algorithm, and actual rates may vary depending on a variety of + * factors. + * + * @param frequency the frequency of the heartbeat in hertz. Note that time is measured at millisecond precision, + * and so frequencies greater than 1000hz are not supported. + * @return the output wire + */ + public OutputWire buildHeartbeatWire(final double frequency) { + if (frequency <= 0) { + throw new IllegalArgumentException("Frequency must be positive"); + } + final Duration period = Duration.ofMillis((long) (1000.0 / frequency)); + return buildHeartbeatWire(period); + } + + /** + * Start the heartbeats. + */ + public abstract void start(); + + /** + * Stop the heartbeats. + */ + public abstract void stop(); +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/standard/HeartbeatScheduler.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/standard/HeartbeatScheduler.java new file mode 100644 index 00000000000..112ea7fe2a8 --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/standard/HeartbeatScheduler.java @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.model.internal.standard; + +import com.swirlds.base.time.Time; +import com.swirlds.wiring.model.StandardWiringModel; +import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Timer; + +/** + * A scheduler that produces heartbeats at a specified rate. + */ +public class HeartbeatScheduler extends AbstractHeartbeatScheduler { + + private final Timer timer = new Timer(); + + /** + * Constructor. + * + * @param model the wiring model containing this heartbeat scheduler + * @param time provides wall clock time + * @param name the name of the heartbeat scheduler + */ + public HeartbeatScheduler( + @NonNull final StandardWiringModel model, @NonNull final Time time, @NonNull final String name) { + super(model, time, name); + } + + /** + * Start the heartbeats. + */ + @Override + public void start() { + if (started) { + throw new IllegalStateException("Cannot start the heartbeat more than once"); + } + started = true; + + for (final HeartbeatTask task : tasks) { + timer.scheduleAtFixedRate(task, 0, task.getPeriod().toMillis()); + } + } + + /** + * Stop the heartbeats. + */ + @Override + public void stop() { + if (!started) { + throw new IllegalStateException("Cannot stop the heartbeat before it has started"); + } + timer.cancel(); + } +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/standard/HeartbeatTask.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/standard/HeartbeatTask.java new file mode 100644 index 00000000000..2e4f8dc7ac2 --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/standard/HeartbeatTask.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.model.internal.standard; + +import com.swirlds.base.time.Time; +import com.swirlds.wiring.model.TraceableWiringModel; +import com.swirlds.wiring.wires.output.OutputWire; +import com.swirlds.wiring.wires.output.StandardOutputWire; +import edu.umd.cs.findbugs.annotations.NonNull; +import java.time.Duration; +import java.time.Instant; +import java.util.Objects; +import java.util.TimerTask; + +/** + * A task that produces a heartbeat at a specified rate. + */ +public class HeartbeatTask extends TimerTask { + + private final Time time; + private final Duration period; + private final StandardOutputWire outputWire; + + /** + * Constructor. + * + * @param model the wiring model that this heartbeat is for + * @param name the name of the output wire + * @param time provides wall clock time + * @param period the period of the heartbeat + */ + public HeartbeatTask( + @NonNull final TraceableWiringModel model, + @NonNull final String name, + @NonNull final Time time, + @NonNull final Duration period) { + this.time = Objects.requireNonNull(time); + this.period = Objects.requireNonNull(period); + Objects.requireNonNull(name); + + this.outputWire = new StandardOutputWire<>(model, name); + } + + /** + * Get the period of the heartbeat. + * + * @return the period of the heartbeat + */ + @NonNull + public Duration getPeriod() { + return period; + } + + /** + * Get the output wire. Produces an Instant with the current time at the specified rate. + * + * @return the output wire + */ + @NonNull + public OutputWire getOutputWire() { + return outputWire; + } + + /** + * Produce a single heartbeat. + */ + @Override + public void run() { + outputWire.forward(time.now()); + } +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/standard/JvmAnchor.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/standard/JvmAnchor.java new file mode 100644 index 00000000000..4085bc52601 --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/standard/JvmAnchor.java @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.model.internal.standard; + +import static java.util.concurrent.TimeUnit.SECONDS; + +import com.swirlds.base.state.Startable; +import com.swirlds.base.state.Stoppable; + +/** + * Creates a non-daemon JVM thread that does nothing. Keeps the JVM alive if all other threads are daemon threads. + */ +public class JvmAnchor implements Startable, Stoppable { + + private final Thread thread; + + /** + * Constructor. + */ + public JvmAnchor() { + thread = new Thread(this::run, ""); + thread.setDaemon(false); // important + } + + /** + * {@inheritDoc} + */ + @Override + public void start() { + thread.start(); + } + + /** + * {@inheritDoc} + */ + @Override + public void stop() { + thread.interrupt(); + } + + /** + * Runs and does nothing until interrupted. + */ + private void run() { + while (!Thread.currentThread().isInterrupted()) { + try { + SECONDS.sleep(Integer.MAX_VALUE); + } catch (final InterruptedException e) { + Thread.currentThread().interrupt(); + return; + } + } + } +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/TaskScheduler.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/TaskScheduler.java new file mode 100644 index 00000000000..f0029a43721 --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/TaskScheduler.java @@ -0,0 +1,289 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.schedulers; + +import com.swirlds.wiring.counters.ObjectCounter; +import com.swirlds.wiring.model.TraceableWiringModel; +import com.swirlds.wiring.schedulers.builders.TaskSchedulerBuilder; +import com.swirlds.wiring.schedulers.builders.TaskSchedulerType; +import com.swirlds.wiring.schedulers.internal.DefaultSquelcher; +import com.swirlds.wiring.schedulers.internal.Squelcher; +import com.swirlds.wiring.schedulers.internal.ThrowingSquelcher; +import com.swirlds.wiring.wires.input.BindableInputWire; +import com.swirlds.wiring.wires.input.InputWire; +import com.swirlds.wiring.wires.input.TaskSchedulerInput; +import com.swirlds.wiring.wires.output.OutputWire; +import com.swirlds.wiring.wires.output.StandardOutputWire; +import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Objects; +import java.util.function.Consumer; +import java.util.function.Function; + +/** + * Schedules tasks for a component. + *

+ * The lifecycle of a task is as follows: + *

    + *
  1. Unscheduled: the task has not been passed to the scheduler yet (e.g. via {@link InputWire#put(Object)})
  2. + *
  3. Scheduled but not processed: the task has been passed to the scheduler but the corresponding handler has not + * yet returned (either because the handler has not yet been called or because the handler has been called but hasn't + * finished yet)
  4. + *
  5. Processed: the corresponding handle method for the task has been called and has returned.
  6. + *
+ * + * @param the output type of the primary output wire (use {@link Void} if no output is needed) + */ +public abstract class TaskScheduler extends TaskSchedulerInput { + + private final boolean flushEnabled; + private final TraceableWiringModel model; + private final String name; + private final TaskSchedulerType type; + private final StandardOutputWire primaryOutputWire; + private final boolean insertionIsBlocking; + + /** + * Handles squelching for this task scheduler. Will be a valid object whether or not squelching is enabled for this + * task scheduler. + */ + private final Squelcher squelcher; + + /** + * Constructor. + * + * @param model the wiring model containing this task scheduler + * @param name the name of the task scheduler + * @param type the type of task scheduler + * @param flushEnabled if true, then {@link #flush()} will be enabled, otherwise it will throw. + * @param squelchingEnabled if true, then squelching will be enabled, otherwise trying to squelch will throw. + * @param insertionIsBlocking when data is inserted into this task scheduler, will it block until capacity is + * available? + */ + protected TaskScheduler( + @NonNull final TraceableWiringModel model, + @NonNull final String name, + @NonNull final TaskSchedulerType type, + final boolean flushEnabled, + final boolean squelchingEnabled, + final boolean insertionIsBlocking) { + + this.model = Objects.requireNonNull(model); + this.name = Objects.requireNonNull(name); + this.type = Objects.requireNonNull(type); + this.flushEnabled = flushEnabled; + + if (squelchingEnabled) { + this.squelcher = new DefaultSquelcher(); + } else { + this.squelcher = new ThrowingSquelcher(); + } + + primaryOutputWire = buildPrimaryOutputWire(model, name); + this.insertionIsBlocking = insertionIsBlocking; + } + + /** + * Build an input wire for passing data to this task scheduler. In order to use this wire, a handler must be bound + * via {@link BindableInputWire#bind(Function)} {@link BindableInputWire#bindConsumer(Consumer)}. + * + * @param name the name of the input wire + * @param the type of data that is inserted via this input wire + * @return the input wire + */ + @NonNull + public BindableInputWire buildInputWire(@NonNull final String name) { + return new BindableInputWire<>(model, this, name); + } + + /** + * Build the primary output wire for this scheduler. + * + * @param model the wiring model that contains this scheduler + * @param name the name of this scheduler + * @return the primary output wire + */ + @NonNull + protected StandardOutputWire buildPrimaryOutputWire( + @NonNull final TraceableWiringModel model, @NonNull final String name) { + return new StandardOutputWire<>(model, name); + } + + /** + * Get the default output wire for this task scheduler. Sometimes referred to as the "primary" output wire. All data + * returned by handlers is passed ot this output wire. Calling this method more than once will always return the + * same object. + * + * @return the primary output wire + */ + @NonNull + public OutputWire getOutputWire() { + return primaryOutputWire; + } + + /** + * By default a component has a single output wire (i.e. the primary output wire). This method allows additional + * output wires to be created. + * + *

+ * Unlike primary wires, secondary output wires need to be passed to a component's constructor. It is considered a + * violation of convention to push data into a secondary output wire from any code that is not executing within this + * task scheduler. + * + * @param the type of data that is transmitted over this output wire + * @return the secondary output wire + */ + @NonNull + public StandardOutputWire buildSecondaryOutputWire() { + // Intentionally do not register this with the model. Connections using this output wire will be represented + // in the model in the same way as connections to the primary output wire. + return new StandardOutputWire<>(model, name); + } + + /** + * Get the name of this task scheduler. + * + * @return the name of this task scheduler + */ + @NonNull + public String getName() { + return name; + } + + /** + * Get the type of this task scheduler. + * + * @return the type of this task scheduler + */ + @NonNull + public TaskSchedulerType getType() { + return type; + } + + /** + * Get whether or not this task scheduler can block when data is inserted into it. + * + * @return true if this task scheduler can block when data is inserted into it, false otherwise + */ + public boolean isInsertionBlocking() { + return insertionIsBlocking; + } + + /** + * Cast this scheduler into whatever a variable is expecting. Sometimes the compiler gets confused with generics, + * and path of least resistance is to just cast to the proper data type. + * + *

+ * Warning: this will appease the compiler, but it is possible to cast a scheduler into a data type that will cause + * runtime exceptions. Use with appropriate caution. + * + * @param the type to cast to + * @return this, cast into whatever type is requested + */ + @NonNull + @SuppressWarnings("unchecked") + public final TaskScheduler cast() { + return (TaskScheduler) this; + } + + /** + * Get the number of unprocessed tasks. A task is considered to be unprocessed until the data has been passed to the + * handler method (i.e. the one given to {@link BindableInputWire#bind(Function)} or + * {@link BindableInputWire#bindConsumer(Consumer)}) and that handler method has returned. + *

+ * Returns {@link ObjectCounter#COUNT_UNDEFINED} if this task scheduler is not monitoring the number of unprocessed + * tasks. Schedulers do not track the number of unprocessed tasks by default. This method will always return + * {@link ObjectCounter#COUNT_UNDEFINED} unless one of the following is true: + *

    + *
  • {@link TaskSchedulerBuilder#withUnhandledTaskMetricEnabled(boolean)} is called with the value + * true
  • + *
  • {@link TaskSchedulerBuilder#withUnhandledTaskCapacity(long)} is passed a positive value
  • + *
  • {@link TaskSchedulerBuilder#withOnRamp(ObjectCounter)} is passed a counter that is not a no op counter
  • + *
+ */ + public abstract long getUnprocessedTaskCount(); + + /** + * Get this task scheduler's desired maximum desired capacity. If {@link TaskSchedulerBuilder#UNLIMITED_CAPACITY} is + * returned, then this task scheduler does not have a maximum capacity. + * + * @return the maximum desired capacity of this task scheduler + */ + public abstract long getCapacity(); + + /** + * Flush all data in the task scheduler. Blocks until all data currently in flight has been processed. + * + *

+ * Note: must be enabled by passing true to {@link TaskSchedulerBuilder#withFlushingEnabled(boolean)}. + * + *

+ * Warning: some implementations of flush may block indefinitely if new work is continuously added to the scheduler + * while flushing. Such implementations are guaranteed to finish flushing once new work is no longer being added. + * Some implementations do not have this restriction, and will return as soon as all of the in flight work has been + * processed, regardless of whether or not new work is being added. + * + * @throws UnsupportedOperationException if {@link TaskSchedulerBuilder#withFlushingEnabled(boolean)} was set to + * false (or was unset, default is false) + */ + public abstract void flush(); + + /** + * Throw an {@link UnsupportedOperationException} if flushing is not enabled. + */ + protected final void throwIfFlushDisabled() { + if (!flushEnabled) { + throw new UnsupportedOperationException("Flushing is not enabled for the task scheduler " + name); + } + } + + /** + * Start squelching, and continue doing so until {@link #stopSquelching()} is called. + * + * @throws UnsupportedOperationException if squelching is not supported by this scheduler + * @throws IllegalStateException if scheduler is already squelching + */ + public void startSquelching() { + squelcher.startSquelching(); + } + + /** + * Stop squelching. + * + * @throws UnsupportedOperationException if squelching is not supported by this scheduler + * @throws IllegalStateException if scheduler is not currently squelching + */ + public void stopSquelching() { + squelcher.stopSquelching(); + } + + /** + * Get whether or not this task scheduler is currently squelching. + * + * @return true if this task scheduler is currently squelching, false otherwise + */ + public final boolean currentlySquelching() { + return squelcher.shouldSquelch(); + } + + /** + * {@inheritDoc} + */ + @Override + protected void forward(@NonNull final OUT data) { + primaryOutputWire.forward(data); + } +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/builders/TaskSchedulerBuilder.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/builders/TaskSchedulerBuilder.java new file mode 100644 index 00000000000..498032acada --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/builders/TaskSchedulerBuilder.java @@ -0,0 +1,196 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.schedulers.builders; + +import com.swirlds.wiring.counters.ObjectCounter; +import com.swirlds.wiring.schedulers.TaskScheduler; +import edu.umd.cs.findbugs.annotations.NonNull; +import edu.umd.cs.findbugs.annotations.Nullable; +import java.lang.Thread.UncaughtExceptionHandler; +import java.time.Duration; +import java.util.concurrent.ForkJoinPool; +import java.util.function.ToLongFunction; + +/** + * A builder for {@link TaskScheduler}s. + * + * @param the output type of the primary output wire for this task scheduler (use {@link Void} for a scheduler + * with no output) + */ +public interface TaskSchedulerBuilder { + + long UNLIMITED_CAPACITY = -1; + + /** + * Configure this task scheduler with values from settings. + * + * @param configuration the configuration + * @return this + */ + @NonNull + TaskSchedulerBuilder configure(@NonNull TaskSchedulerConfiguration configuration); + + /** + * Set the type of task scheduler to build. Alters the semantics of the scheduler (i.e. this is not just an internal + * implementation detail). + * + * @param type the type of task scheduler to build + * @return this + */ + @NonNull + TaskSchedulerBuilder withType(@NonNull TaskSchedulerType type); + + /** + * Set the maximum number of permitted scheduled tasks. Default is 1. + * + * @param unhandledTaskCapacity the maximum number of permitted unhandled tasks + * @return this + */ + @NonNull + TaskSchedulerBuilder withUnhandledTaskCapacity(long unhandledTaskCapacity); + + /** + * Set whether the task scheduler should enable flushing. Default false. Flushing a scheduler with this disabled + * will cause the scheduler to throw an exception. Enabling flushing may add overhead. + * + * @param requireFlushCapability true if the wire should require flush capability, false otherwise + * @return this + */ + @NonNull + TaskSchedulerBuilder withFlushingEnabled(boolean requireFlushCapability); + + /** + * Set whether the task scheduler should enable squelching. Default false. Enabling squelching may add overhead. + *

+ * IMPORTANT: you must not enable squelching if the scheduler handles tasks that require special cleanup. If + * squelching is enabled and activated, all existing and incoming tasks will be unceremoniously dumped into the + * void! + * + * @param squelchingEnabled true if the scheduler should enable squelching, false otherwise. + * @return this + */ + @NonNull + TaskSchedulerBuilder withSquelchingEnabled(boolean squelchingEnabled); + + /** + * Specify an object counter that should be notified when data is added to the task scheduler. This is useful for + * implementing backpressure that spans multiple schedulers. + * + * @param onRamp the object counter that should be notified when data is added to the task scheduler + * @return this + */ + @NonNull + TaskSchedulerBuilder withOnRamp(@NonNull ObjectCounter onRamp); + + /** + * Specify an object counter that should be notified when data is removed from the task scheduler. This is useful + * for implementing backpressure that spans multiple schedulers. + * + * @param offRamp the object counter that should be notified when data is removed from the wire + * @return this + */ + @NonNull + TaskSchedulerBuilder withOffRamp(@NonNull ObjectCounter offRamp); + + /** + * If true then the framework will assume that back pressure is being applied via external mechanisms. + *

+ * This method does not change the runtime behavior of the wiring framework. But it does affect cyclical back + * pressure detection and automatically generated wiring diagrams. + * + * @param externalBackPressure true if back pressure is being applied externally, false otherwise + * @return this + */ + @NonNull + TaskSchedulerBuilder withExternalBackPressure(boolean externalBackPressure); + + /** + * If a method needs to block, this is the amount of time that is slept while waiting for the needed condition. + * + * @param backpressureSleepDuration the length of time to sleep when backpressure needs to be applied + * @return this + */ + @NonNull + TaskSchedulerBuilder withSleepDuration(@NonNull Duration backpressureSleepDuration); + + /** + * Set whether the unhandled task count metric should be enabled. Default false. + * + * @param enabled true if the unhandled task count metric should be enabled, false otherwise + * @return this + */ + @NonNull + TaskSchedulerBuilder withUnhandledTaskMetricEnabled(boolean enabled); + + /** + * Set whether the busy fraction metric should be enabled. Default false. + *

+ * Note: this metric is currently only compatible with non-concurrent task scheduler implementations. At a future + * time this metric may be updated to work with concurrent scheduler implementations. + * + * @param enabled true if the busy fraction metric should be enabled, false otherwise + * @return this + */ + @NonNull + TaskSchedulerBuilder withBusyFractionMetricsEnabled(boolean enabled); + + /** + * Provide a custom thread pool for this task scheduler. If none is provided then the common fork join pool will be + * used. + * + * @param pool the thread pool + * @return this + */ + @NonNull + TaskSchedulerBuilder withPool(@NonNull ForkJoinPool pool); + + /** + * Provide a custom uncaught exception handler for this task scheduler. If none is provided then the default + * uncaught exception handler will be used. The default handler will write a message to the log. + * + * @param uncaughtExceptionHandler the uncaught exception handler + * @return this + */ + @NonNull + TaskSchedulerBuilder withUncaughtExceptionHandler(@NonNull UncaughtExceptionHandler uncaughtExceptionHandler); + + /** + * Provide a hyperlink to documentation for this task scheduler. If none is provided then no hyperlink will be + * generated. Used only for the automatically generated wiring diagram. + * + * @param hyperlink the hyperlink to the documentation for this task scheduler + * @return this + */ + @NonNull + TaskSchedulerBuilder withHyperlink(@Nullable String hyperlink); + + /** + * Provide a function to count weight of a data object for component health monitoring. + * @param dataCounter the + * @return this + */ + @NonNull + TaskSchedulerBuilder withDataCounter(@NonNull ToLongFunction dataCounter); + + /** + * Build the task scheduler. + * + * @return the task scheduler + */ + @NonNull + TaskScheduler build(); +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/builders/TaskSchedulerConfigOption.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/builders/TaskSchedulerConfigOption.java new file mode 100644 index 00000000000..6c8af48fa12 --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/builders/TaskSchedulerConfigOption.java @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.schedulers.builders; + +/** + * Various configuration options for a task scheduler. Note that the task scheduler type uses values from + * {@link TaskSchedulerType}, and that the unhandled task capacity is represented as an integer value. + */ +public enum TaskSchedulerConfigOption { + /** + * If present, a metric will be created to show the number of unhandled tasks. + */ + UNHANDLED_TASK_METRIC, + /** + * If present, a metric will be created to show the fraction of time the scheduler is busy. + */ + BUSY_FRACTION_METRIC, + /** + * If present, the scheduler will be capable of being flushed. + */ + FLUSHABLE, + /** + * If present, the scheduler will be capable of squelching. + */ + SQUELCHABLE; + + /** + * This is not defined as an enum constant because it is used in a special way. To specify the capacity, + * use a string in the form "CAPACITY(1234)" where 1234 is the desired capacity. + */ + public static final String CAPACITY = "CAPACITY"; +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/builders/TaskSchedulerConfiguration.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/builders/TaskSchedulerConfiguration.java new file mode 100644 index 00000000000..f0116271655 --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/builders/TaskSchedulerConfiguration.java @@ -0,0 +1,237 @@ +/* + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.schedulers.builders; + +import static com.swirlds.wiring.schedulers.builders.TaskSchedulerConfigOption.BUSY_FRACTION_METRIC; +import static com.swirlds.wiring.schedulers.builders.TaskSchedulerConfigOption.FLUSHABLE; +import static com.swirlds.wiring.schedulers.builders.TaskSchedulerConfigOption.SQUELCHABLE; +import static com.swirlds.wiring.schedulers.builders.TaskSchedulerConfigOption.UNHANDLED_TASK_METRIC; + +import edu.umd.cs.findbugs.annotations.NonNull; +import edu.umd.cs.findbugs.annotations.Nullable; + +/** + * Configures a task scheduler. + * + * @param type the type of task scheduler, if null then {@link TaskSchedulerType#SEQUENTIAL} is + * used + * @param unhandledTaskCapacity the maximum number of unhandled tasks, or 0 if unbounded, if null then 0 is used + * @param unhandledTaskMetricEnabled whether the unhandled task count metric should be enabled, if null than false is + * used + * @param busyFractionMetricEnabled whether the busy fraction metric should be enabled, if null then false is used + * @param flushingEnabled whether flushing is enabled, if null then false is used + * @param squelchingEnabled whether squelching is enabled, if null then false is used + */ +public record TaskSchedulerConfiguration( + @Nullable TaskSchedulerType type, + @Nullable Long unhandledTaskCapacity, + @Nullable Boolean unhandledTaskMetricEnabled, + @Nullable Boolean busyFractionMetricEnabled, + @Nullable Boolean flushingEnabled, + @Nullable Boolean squelchingEnabled) { + + /** + * This configuration is for a no-op task scheduler. It is not necessary to use this constant for a no-op task + * scheduler, but it is provided for convenience. + */ + public static final TaskSchedulerConfiguration NO_OP_CONFIGURATION = + new TaskSchedulerConfiguration(TaskSchedulerType.NO_OP, 0L, false, false, false, false); + + /** + * This configuration is for a simple direct task scheduler. It is not necessary to use this constant for a direct + * task scheduler, but it is provided for convenience. + */ + public static final TaskSchedulerConfiguration DIRECT_CONFIGURATION = + new TaskSchedulerConfiguration(TaskSchedulerType.DIRECT, 0L, false, false, false, false); + + /** + * This configuration is for a thread-safe direct task scheduler. It is not necessary to use this constant for a + * thread-safe direct task scheduler, but it is provided for convenience. + */ + public static final TaskSchedulerConfiguration DIRECT_THREADSAFE_CONFIGURATION = + new TaskSchedulerConfiguration(TaskSchedulerType.DIRECT_THREADSAFE, 0L, false, false, false, false); + + /** + * Parse a string representation of a task scheduler configuration. + *

+ * Syntax is as follows: + *

    + *
  • + * Zero or one values from the {@link TaskSchedulerType} enum, specifies the type of the task scheduler. + * If not present then the default is used. + *
  • + *
  • + * Zero or one string of the form "CAPACITY(1234)", specifies the maximum number of unhandled tasks. + *
  • + *
  • + * Zero or more values from the {@link TaskSchedulerConfigOption} enum, specifies the configuration options. + * Sets a boolean configuration option to true if the value is present, and false if the value is prefixed + * with a "!". If not present then the default is used. + *
  • + *
+ * Example: "SEQUENTIAL CAPACITY(500) !FLUSHABLE UNHANDLED_TASK_METRIC" + *

+ * Note that default values are not specified within this class. Default values are the responsibility of the + * {@link TaskSchedulerBuilder} class. + * + * @param string the string to parse + * @return the parsed configuration + */ + @NonNull + public static TaskSchedulerConfiguration parse(@NonNull final String string) { + TaskSchedulerType type = null; + Long unhandledTaskCapacity = null; + Boolean unhandledTaskMetricEnabled = null; + Boolean busyFractionMetricEnabled = null; + Boolean flushingEnabled = null; + Boolean squelchingEnabled = null; + + final String[] parts = string.split(" "); + for (final String part : parts) { + final String strippedPart = part.strip(); + if (strippedPart.isEmpty()) { + continue; + } + + final TaskSchedulerType parsedType = tryToParseTaskSchedulerType(strippedPart); + if (parsedType != null) { + if (type != null) { + throw new IllegalArgumentException("Multiple task scheduler types specified: " + string); + } + type = parsedType; + continue; + } + + final Long parsedCapacity = tryToParseCapacity(strippedPart); + if (parsedCapacity != null) { + if (unhandledTaskCapacity != null) { + throw new IllegalArgumentException("Multiple capacities specified: " + string); + } + unhandledTaskCapacity = parsedCapacity; + continue; + } + + final Boolean parsedUnhandledTaskMetric = tryToParseOption(UNHANDLED_TASK_METRIC, strippedPart); + if (parsedUnhandledTaskMetric != null) { + if (unhandledTaskMetricEnabled != null) { + throw new IllegalArgumentException( + "Multiple unhandled task metric configurations specified: " + string); + } + unhandledTaskMetricEnabled = parsedUnhandledTaskMetric; + continue; + } + + final Boolean parsedBusyFractionMetric = tryToParseOption(BUSY_FRACTION_METRIC, strippedPart); + if (parsedBusyFractionMetric != null) { + if (busyFractionMetricEnabled != null) { + throw new IllegalArgumentException( + "Multiple busy fraction metric configurations specified: " + string); + } + busyFractionMetricEnabled = parsedBusyFractionMetric; + continue; + } + + final Boolean parsedFlushing = tryToParseOption(FLUSHABLE, strippedPart); + if (parsedFlushing != null) { + if (flushingEnabled != null) { + throw new IllegalArgumentException("Multiple flushing configurations specified: " + string); + } + flushingEnabled = parsedFlushing; + continue; + } + + final Boolean parsedSquelching = tryToParseOption(SQUELCHABLE, strippedPart); + if (parsedSquelching != null) { + if (squelchingEnabled != null) { + throw new IllegalArgumentException("Multiple squelching configurations specified: " + string); + } + squelchingEnabled = parsedSquelching; + continue; + } + + throw new IllegalArgumentException("Invalid task scheduler configuration: " + part); + } + + return new TaskSchedulerConfiguration( + type, + unhandledTaskCapacity, + unhandledTaskMetricEnabled, + busyFractionMetricEnabled, + flushingEnabled, + squelchingEnabled); + } + + /** + * Try to parse a string as a {@link TaskSchedulerType}. + * + * @param string the string to parse + * @return the parsed type, or null if the string is not a valid type + */ + @Nullable + private static TaskSchedulerType tryToParseTaskSchedulerType(@NonNull final String string) { + try { + return TaskSchedulerType.valueOf(string); + } catch (final IllegalArgumentException e) { + return null; + } + } + + /** + * Try to parse a string as a capacity. + * + * @param string the string to parse + * @return the parsed capacity, or null if the string is not a valid capacity + */ + @Nullable + private static Long tryToParseCapacity(@NonNull final String string) { + if (string.startsWith(TaskSchedulerConfigOption.CAPACITY)) { + + try { + // parse a string in the form "CAPACITY(1234)" + final int openParenIndex = string.indexOf('('); + final int closeParenIndex = string.indexOf(')'); + if (openParenIndex == -1 || closeParenIndex == -1) { + throw new IllegalArgumentException("Invalid capacity \"" + string + "\""); + } + final String capacityString = string.substring(openParenIndex + 1, closeParenIndex); + return Long.parseLong(capacityString); + } catch (final NumberFormatException e) { + throw new IllegalArgumentException("Invalid capacity \"" + string + "\"", e); + } + } + return null; + } + + /** + * Try to parse a string as a configuration option that is represented by an enum string and an optional "!". + * + * @param option the option to look for + * @param string the string to parse + * @return the parsed option, or null if the string is not a valid option + */ + @Nullable + private static Boolean tryToParseOption( + @NonNull final TaskSchedulerConfigOption option, @NonNull final String string) { + + if (string.equals(option.toString())) { + return true; + } else if (string.equals("!" + option)) { + return false; + } + return null; + } +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/builders/TaskSchedulerType.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/builders/TaskSchedulerType.java new file mode 100644 index 00000000000..a536df9a178 --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/builders/TaskSchedulerType.java @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.schedulers.builders; + +/** + * Various types of task schedulers. Pass one of these types to {@link TaskSchedulerBuilder#withType(TaskSchedulerType)} + * to create a task scheduler of the desired type. If unspecified, the default scheduler type is {@link #SEQUENTIAL}. + */ +public enum TaskSchedulerType { + /** + * Tasks are executed in a fork join pool one at a time in the order they were enqueued. There is a happens before + * relationship between each task. + */ + SEQUENTIAL, + /** + * Tasks are executed on a dedicated thread one at a time in the order they were enqueued. There is a happens before + * relationship between each task. This scheduler type has very similar semantics as {@link #SEQUENTIAL}, although + * the implementation and performance characteristics are not identical. + */ + SEQUENTIAL_THREAD, + /** + * Tasks are executed on a fork join pool. Tasks may be executed in parallel with each other. Ordering is not + * guaranteed. + */ + CONCURRENT, + /** + * Tasks are executed immediately on the caller's thread. There is no queue for tasks waiting to be handled (logical + * or otherwise). Useful for scenarios where tasks are extremely small and not worth the scheduling overhead. + *

+ * Only a single logical thread of execution is permitted to send data to a direct task scheduler. + * {@link #SEQUENTIAL} and {@link #SEQUENTIAL_THREAD} schedulers are permitted to send data to a direct task + * scheduler, but it is illegal for more than one of these schedulers to send data to the same direct task + * scheduler. {@link #CONCURRENT} task schedulers are forbidden from sending data to a direct task scheduler. It is + * legal for operations that are executed on the calling thread (e.g. filters, transformers, stateless/stateful + * direct schedulers) to call into a direct scheduler as long as the calling thread is not in a concurrent scheduler + * or originating from more than one sequential scheduler. + *

+ * To decide if a direct scheduler is wired in a legal way, the following algorithm is used: + *

    + *
  • Create a directed graph where vertices are schedulers and edges are wires between schedulers
  • + *
  • Starting from each vertex, walk over the graph in depth first order. Follow edges that lead to + * DIRECT or DIRECT_THREADSAFE vertices, but do not follow edges that lead into SEQUENTIAL, SEQUENTIAL_THREAD, + * or CONCURRENT vertices.
  • + *
  • If a DIRECT vertex is reachable starting from a CONCURRENT vertex, the wiring is illegal.
  • + *
  • For each vertex with type DIRECT, count the number of unique SEQUENTIAL or SEQUENTIAL_THREAD vertexes that + * it can be reached by. If that number exceeds 1, then the wiring is illegal.
  • + *
+ * + *

+ * These constraints are enforced by the framework. + */ + DIRECT, + /** + * Similar to {@link #DIRECT} except that work performed by this scheduler is required to be threadsafe. This means + * that it is safe to concurrently execute multiple instances of the same task, freeing it from the restrictions of + * {@link #DIRECT}. + * + *

+ * There is no enforcement mechanism in the framework to ensure that the task is actually threadsafe. It is advised + * that this scheduler type be used with caution, as improper use can lead to can lead to nasty race conditions. + */ + DIRECT_THREADSAFE, + /** + * A scheduler that does nothing. All wires into and out of this scheduler are effectively non-existent at runtime. + * Useful for testing and debugging, or for when the ability to toggle a scheduler on/off via configuration is + * desired. For a deeper dive into why this is a useful concept, see + * this explanation. + */ + NO_OP +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/builders/internal/AbstractTaskSchedulerBuilder.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/builders/internal/AbstractTaskSchedulerBuilder.java new file mode 100644 index 00000000000..d646955f473 --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/builders/internal/AbstractTaskSchedulerBuilder.java @@ -0,0 +1,355 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.schedulers.builders.internal; + +import static com.swirlds.logging.legacy.LogMarker.EXCEPTION; +import static com.swirlds.wiring.schedulers.builders.TaskSchedulerType.DIRECT; +import static com.swirlds.wiring.schedulers.builders.TaskSchedulerType.DIRECT_THREADSAFE; +import static com.swirlds.wiring.schedulers.builders.TaskSchedulerType.NO_OP; + +import com.swirlds.common.context.PlatformContext; +import com.swirlds.wiring.counters.BackpressureObjectCounter; +import com.swirlds.wiring.counters.MultiObjectCounter; +import com.swirlds.wiring.counters.NoOpObjectCounter; +import com.swirlds.wiring.counters.ObjectCounter; +import com.swirlds.wiring.counters.StandardObjectCounter; +import com.swirlds.wiring.model.TraceableWiringModel; +import com.swirlds.wiring.schedulers.TaskScheduler; +import com.swirlds.wiring.schedulers.builders.TaskSchedulerBuilder; +import com.swirlds.wiring.schedulers.builders.TaskSchedulerConfiguration; +import com.swirlds.wiring.schedulers.builders.TaskSchedulerType; +import edu.umd.cs.findbugs.annotations.NonNull; +import edu.umd.cs.findbugs.annotations.Nullable; +import java.lang.Thread.UncaughtExceptionHandler; +import java.time.Duration; +import java.util.Objects; +import java.util.concurrent.ForkJoinPool; +import java.util.function.ToLongFunction; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +/** + * A builder for {@link TaskScheduler}s. + * + * @param the output type of the primary output wire for this task scheduler (use {@link Void} for a scheduler with + * no output) + */ +public abstract class AbstractTaskSchedulerBuilder implements TaskSchedulerBuilder { + + private static final Logger logger = LogManager.getLogger(AbstractTaskSchedulerBuilder.class); + + protected final TraceableWiringModel model; + + protected TaskSchedulerType type = TaskSchedulerType.SEQUENTIAL; + protected final String name; + protected long unhandledTaskCapacity = 1; + protected boolean flushingEnabled = false; + protected boolean squelchingEnabled = false; + protected boolean externalBackPressure = false; + protected ObjectCounter onRamp; + protected ObjectCounter offRamp; + protected ForkJoinPool pool; + protected UncaughtExceptionHandler uncaughtExceptionHandler; + protected String hyperlink; + protected ToLongFunction dataCounter = data -> 1L; + + protected boolean unhandledTaskMetricEnabled = false; + protected boolean busyFractionMetricEnabled = false; + + protected Duration sleepDuration = Duration.ofNanos(100); + + protected final PlatformContext platformContext; + + /** + * Constructor. + * + * @param platformContext the platform context + * @param model the wiring model + * @param name the name of the task scheduler. Used for metrics and debugging. Must be unique. Must only + * contain alphanumeric characters and underscores. + * @param defaultPool the default fork join pool, if none is provided then this pool will be used + */ + public AbstractTaskSchedulerBuilder( + @NonNull final PlatformContext platformContext, + @NonNull final TraceableWiringModel model, + @NonNull final String name, + @NonNull final ForkJoinPool defaultPool) { + + this.platformContext = Objects.requireNonNull(platformContext); + this.model = Objects.requireNonNull(model); + + // The reason why wire names have a restricted character set is because downstream consumers of metrics + // are very fussy about what characters are allowed in metric names. + if (!name.matches("^[a-zA-Z0-9_]*$")) { + throw new IllegalArgumentException("Illegal name: \"" + name + + "\". Task Schedulers name must only contain alphanumeric characters and underscores"); + } + if (name.isEmpty()) { + throw new IllegalArgumentException("TaskScheduler name must not be empty"); + } + this.name = name; + this.pool = Objects.requireNonNull(defaultPool); + } + + /** + * {@inheritDoc} + */ + @Override + @NonNull + public AbstractTaskSchedulerBuilder configure(@NonNull final TaskSchedulerConfiguration configuration) { + if (configuration.type() != null) { + withType(configuration.type()); + } + if (configuration.unhandledTaskCapacity() != null) { + withUnhandledTaskCapacity(configuration.unhandledTaskCapacity()); + } + if (configuration.unhandledTaskMetricEnabled() != null) { + withUnhandledTaskMetricEnabled(configuration.unhandledTaskMetricEnabled()); + } + if (configuration.busyFractionMetricEnabled() != null) { + withBusyFractionMetricsEnabled(configuration.busyFractionMetricEnabled()); + } + if (configuration.flushingEnabled() != null) { + withFlushingEnabled(configuration.flushingEnabled()); + } + if (configuration.squelchingEnabled() != null) { + withSquelchingEnabled(configuration.squelchingEnabled()); + } + return this; + } + + /** + * {@inheritDoc} + */ + @Override + @NonNull + public AbstractTaskSchedulerBuilder withType(@NonNull final TaskSchedulerType type) { + this.type = Objects.requireNonNull(type); + return this; + } + + /** + * {@inheritDoc} + */ + @Override + @NonNull + public AbstractTaskSchedulerBuilder withUnhandledTaskCapacity(final long unhandledTaskCapacity) { + this.unhandledTaskCapacity = unhandledTaskCapacity; + return this; + } + + /** + * {@inheritDoc} + */ + @Override + @NonNull + public AbstractTaskSchedulerBuilder withFlushingEnabled(final boolean requireFlushCapability) { + this.flushingEnabled = requireFlushCapability; + return this; + } + + /** + * {@inheritDoc} + */ + @Override + @NonNull + public AbstractTaskSchedulerBuilder withSquelchingEnabled(final boolean squelchingEnabled) { + this.squelchingEnabled = squelchingEnabled; + return this; + } + + /** + * {@inheritDoc} + */ + @Override + @NonNull + public AbstractTaskSchedulerBuilder withOnRamp(@NonNull final ObjectCounter onRamp) { + this.onRamp = Objects.requireNonNull(onRamp); + return this; + } + + /** + * {@inheritDoc} + */ + @Override + @NonNull + public AbstractTaskSchedulerBuilder withOffRamp(@NonNull final ObjectCounter offRamp) { + this.offRamp = Objects.requireNonNull(offRamp); + return this; + } + + /** + * {@inheritDoc} + */ + @Override + @NonNull + public AbstractTaskSchedulerBuilder withExternalBackPressure(final boolean externalBackPressure) { + this.externalBackPressure = externalBackPressure; + return this; + } + + /** + * {@inheritDoc} + */ + @Override + @NonNull + public AbstractTaskSchedulerBuilder withSleepDuration(@NonNull final Duration backpressureSleepDuration) { + if (backpressureSleepDuration.isNegative()) { + throw new IllegalArgumentException("Backpressure sleep duration must not be negative"); + } + this.sleepDuration = backpressureSleepDuration; + return this; + } + + /** + * {@inheritDoc} + */ + @Override + @NonNull + public AbstractTaskSchedulerBuilder withUnhandledTaskMetricEnabled(final boolean enabled) { + this.unhandledTaskMetricEnabled = enabled; + return this; + } + + /** + * {@inheritDoc} + */ + @Override + @NonNull + public AbstractTaskSchedulerBuilder withBusyFractionMetricsEnabled(final boolean enabled) { + this.busyFractionMetricEnabled = enabled; + return this; + } + + /** + * {@inheritDoc} + */ + @Override + @NonNull + public AbstractTaskSchedulerBuilder withPool(@NonNull final ForkJoinPool pool) { + this.pool = Objects.requireNonNull(pool); + return this; + } + + /** + * {@inheritDoc} + */ + @Override + @NonNull + public AbstractTaskSchedulerBuilder withUncaughtExceptionHandler( + @NonNull final UncaughtExceptionHandler uncaughtExceptionHandler) { + this.uncaughtExceptionHandler = Objects.requireNonNull(uncaughtExceptionHandler); + return this; + } + + /** + * {@inheritDoc} + */ + @Override + @NonNull + public AbstractTaskSchedulerBuilder withHyperlink(@Nullable final String hyperlink) { + this.hyperlink = hyperlink; + return this; + } + + @Override + @NonNull + public AbstractTaskSchedulerBuilder withDataCounter(@NonNull ToLongFunction counter) { + this.dataCounter = counter; + return this; + } + + /** + * Build an uncaught exception handler if one was not provided. + * + * @return the uncaught exception handler + */ + @NonNull + protected UncaughtExceptionHandler buildUncaughtExceptionHandler() { + if (uncaughtExceptionHandler != null) { + return uncaughtExceptionHandler; + } else { + return (thread, throwable) -> + logger.error(EXCEPTION.getMarker(), "Uncaught exception in scheduler {}", name, throwable); + } + } + + protected record Counters(@NonNull ObjectCounter onRamp, @NonNull ObjectCounter offRamp) {} + + /** + * Combine two counters into one. + * + * @param innerCounter the counter needed for internal implementation details, or null if not needed + * @param outerCounter the counter provided by the outer scope, or null if not provided + * @return the combined counter, or a no op counter if both are null + */ + @NonNull + protected static ObjectCounter combineCounters( + @Nullable final ObjectCounter innerCounter, @Nullable final ObjectCounter outerCounter) { + if (innerCounter == null) { + if (outerCounter == null) { + return NoOpObjectCounter.getInstance(); + } else { + return outerCounter; + } + } else { + if (outerCounter == null) { + return innerCounter; + } else { + return new MultiObjectCounter(innerCounter, outerCounter); + } + } + } + + /** + * Figure out which counters to use for this task scheduler (if any), constructing them if they need to be + * constructed. + */ + @NonNull + protected Counters buildCounters() { + if (type == NO_OP) { + return new Counters(NoOpObjectCounter.getInstance(), NoOpObjectCounter.getInstance()); + } + + final ObjectCounter innerCounter; + + // If we need to enforce a maximum capacity, we have no choice but to use a backpressure object counter. + // + // If we don't need to enforce a maximum capacity, we need to use a standard object counter if any + // of the following conditions are true: + // - we have unhandled task metrics enabled + // - flushing is enabled. This is because our flush implementation is not + // compatible with a no-op counter. + // + // In all other cases, better to use a no-op counter. Counters have overhead, and if we don't need one + // then we shouldn't use one. + + if (model.isBackpressureEnabled() + && unhandledTaskCapacity != UNLIMITED_CAPACITY + && type != DIRECT + && type != DIRECT_THREADSAFE) { + + innerCounter = new BackpressureObjectCounter(name, unhandledTaskCapacity, sleepDuration); + } else if (unhandledTaskMetricEnabled || flushingEnabled) { + innerCounter = new StandardObjectCounter(sleepDuration); + } else { + innerCounter = null; + } + + return new Counters(combineCounters(innerCounter, onRamp), combineCounters(innerCounter, offRamp)); + } +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/builders/internal/StandardTaskSchedulerBuilder.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/builders/internal/StandardTaskSchedulerBuilder.java new file mode 100644 index 00000000000..edd89d11f0f --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/builders/internal/StandardTaskSchedulerBuilder.java @@ -0,0 +1,184 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.schedulers.builders.internal; + +import static com.swirlds.wiring.schedulers.builders.TaskSchedulerType.DIRECT_THREADSAFE; +import static com.swirlds.wiring.schedulers.builders.TaskSchedulerType.NO_OP; + +import com.swirlds.common.context.PlatformContext; +import com.swirlds.common.metrics.FunctionGauge; +import com.swirlds.common.metrics.extensions.FractionalTimer; +import com.swirlds.common.metrics.extensions.NoOpFractionalTimer; +import com.swirlds.common.metrics.extensions.StandardFractionalTimer; +import com.swirlds.wiring.model.StandardWiringModel; +import com.swirlds.wiring.schedulers.TaskScheduler; +import com.swirlds.wiring.schedulers.builders.TaskSchedulerType; +import com.swirlds.wiring.schedulers.internal.ConcurrentTaskScheduler; +import com.swirlds.wiring.schedulers.internal.DirectTaskScheduler; +import com.swirlds.wiring.schedulers.internal.NoOpTaskScheduler; +import com.swirlds.wiring.schedulers.internal.SequentialTaskScheduler; +import com.swirlds.wiring.schedulers.internal.SequentialThreadTaskScheduler; +import edu.umd.cs.findbugs.annotations.NonNull; +import edu.umd.cs.findbugs.annotations.Nullable; +import java.util.Objects; +import java.util.concurrent.ForkJoinPool; +import java.util.function.Supplier; + +/** + * A builder for {@link TaskScheduler}s. + * + * @param the output type of the primary output wire for this task scheduler (use {@link Void} for a scheduler + * with no output) + */ +public class StandardTaskSchedulerBuilder extends AbstractTaskSchedulerBuilder { + + /** + * Constructor. + * + * @param platformContext the platform context + * @param model the wiring model + * @param name the name of the task scheduler. Used for metrics and debugging. Must be unique. Must only + * contain alphanumeric characters and underscores. + * @param defaultPool the default fork join pool, if none is provided then this pool will be used + */ + public StandardTaskSchedulerBuilder( + @NonNull final PlatformContext platformContext, + @NonNull final StandardWiringModel model, + @NonNull final String name, + @NonNull final ForkJoinPool defaultPool) { + + super(platformContext, model, name, defaultPool); + } + + /** + * Build a busy timer if enabled. + * + * @return the busy timer, or null if not enabled + */ + @NonNull + private FractionalTimer buildBusyTimer() { + if (!busyFractionMetricEnabled || type == NO_OP) { + return NoOpFractionalTimer.getInstance(); + } + if (type == TaskSchedulerType.CONCURRENT) { + throw new IllegalStateException("Busy fraction metric is not compatible with concurrent schedulers"); + } + return new StandardFractionalTimer(platformContext.getTime()); + } + + /** + * Register all configured metrics. + * + * @param longSupplier the counter that is used to track the number of unhandled tasks + * @param busyFractionTimer the timer that is used to track the fraction of the time that the underlying thread + * is busy + */ + private void registerMetrics( + @Nullable final Supplier longSupplier, @NonNull final FractionalTimer busyFractionTimer) { + + if (type == NO_OP) { + return; + } + + if (unhandledTaskMetricEnabled) { + Objects.requireNonNull(longSupplier); + + final FunctionGauge.Config config = new FunctionGauge.Config<>( + "platform", name + "_unhandled_task_count", Long.class, longSupplier) + .withDescription( + "The number of scheduled tasks that have not been fully handled for the scheduler " + name); + platformContext.getMetrics().getOrCreate(config); + } + + if (busyFractionMetricEnabled) { + busyFractionTimer.registerMetric( + platformContext.getMetrics(), + "platform", + name + "_busy_fraction", + "Fraction (out of 1.0) of time spent processing tasks for the task scheduler " + name); + } + } + + /** + * {@inheritDoc} + */ + @Override + @NonNull + public TaskScheduler build() { + final Counters counters = buildCounters(); + final FractionalTimer busyFractionTimer = buildBusyTimer(); + final boolean insertionIsBlocking = + ((unhandledTaskCapacity != UNLIMITED_CAPACITY) || externalBackPressure) && (type != NO_OP); + + final TaskScheduler scheduler = + switch (type) { + case CONCURRENT -> new ConcurrentTaskScheduler<>( + model, + name, + pool, + buildUncaughtExceptionHandler(), + counters.onRamp(), + counters.offRamp(), + unhandledTaskCapacity, + flushingEnabled, + squelchingEnabled, + insertionIsBlocking); + case SEQUENTIAL -> new SequentialTaskScheduler<>( + model, + name, + pool, + buildUncaughtExceptionHandler(), + counters.onRamp(), + counters.offRamp(), + busyFractionTimer, + unhandledTaskCapacity, + flushingEnabled, + squelchingEnabled, + insertionIsBlocking); + case SEQUENTIAL_THREAD -> new SequentialThreadTaskScheduler<>( + model, + name, + buildUncaughtExceptionHandler(), + counters.onRamp(), + counters.offRamp(), + dataCounter, + busyFractionTimer, + unhandledTaskCapacity, + flushingEnabled, + squelchingEnabled, + insertionIsBlocking); + case DIRECT, DIRECT_THREADSAFE -> new DirectTaskScheduler<>( + model, + name, + buildUncaughtExceptionHandler(), + counters.onRamp(), + counters.offRamp(), + squelchingEnabled, + busyFractionTimer, + type == DIRECT_THREADSAFE); + case NO_OP -> new NoOpTaskScheduler<>(model, name, type, flushingEnabled, squelchingEnabled); + }; + + if (type != NO_OP) { + model.registerScheduler(scheduler, hyperlink); + } + + registerMetrics(scheduler::getUnprocessedTaskCount, busyFractionTimer); + + return scheduler; + } +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/ConcurrentTask.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/ConcurrentTask.java new file mode 100644 index 00000000000..0f058cad6ee --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/ConcurrentTask.java @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.schedulers.internal; + +import com.swirlds.wiring.counters.ObjectCounter; +import com.swirlds.wiring.tasks.AbstractTask; +import edu.umd.cs.findbugs.annotations.NonNull; +import edu.umd.cs.findbugs.annotations.Nullable; +import java.lang.Thread.UncaughtExceptionHandler; +import java.util.concurrent.ForkJoinPool; +import java.util.function.Consumer; + +/** + * A task in a {@link ConcurrentTaskScheduler}. + */ +class ConcurrentTask extends AbstractTask { + + private final Consumer handler; + private final Object data; + private final ObjectCounter offRamp; + private final UncaughtExceptionHandler uncaughtExceptionHandler; + + /** + * Constructor. The task is created with zero dependencies, but not started automatically. It's + * the caller responsibility to start the task using {@link #send()} method. + * + * @param pool the fork join pool that will execute this task + * @param offRamp an object counter that is decremented when this task is executed + * @param uncaughtExceptionHandler the handler for uncaught exceptions + * @param handler the method that will be called when this task is executed + * @param data the data to be passed to the consumer for this task + */ + ConcurrentTask( + @NonNull final ForkJoinPool pool, + @NonNull final ObjectCounter offRamp, + @NonNull final UncaughtExceptionHandler uncaughtExceptionHandler, + @NonNull final Consumer handler, + @Nullable final Object data) { + super(pool, 0); + this.handler = handler; + this.data = data; + this.offRamp = offRamp; + this.uncaughtExceptionHandler = uncaughtExceptionHandler; + } + + /** + * {@inheritDoc} + */ + @Override + protected boolean exec() { + try { + handler.accept(data); + } catch (final Throwable t) { + uncaughtExceptionHandler.uncaughtException(Thread.currentThread(), t); + } finally { + offRamp.offRamp(); + } + return true; + } +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/ConcurrentTaskScheduler.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/ConcurrentTaskScheduler.java new file mode 100644 index 00000000000..ab350857ae0 --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/ConcurrentTaskScheduler.java @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.schedulers.internal; + +import com.swirlds.wiring.counters.ObjectCounter; +import com.swirlds.wiring.model.TraceableWiringModel; +import com.swirlds.wiring.schedulers.TaskScheduler; +import com.swirlds.wiring.schedulers.builders.TaskSchedulerType; +import edu.umd.cs.findbugs.annotations.NonNull; +import java.lang.Thread.UncaughtExceptionHandler; +import java.util.Objects; +import java.util.concurrent.ForkJoinPool; +import java.util.function.Consumer; + +/** + * A {@link TaskScheduler} that permits parallel execution of tasks. + * + * @param the output type of the scheduler (use {@link Void} for a task scheduler with no output type) + */ +public class ConcurrentTaskScheduler extends TaskScheduler { + + private final ObjectCounter onRamp; + private final ObjectCounter offRamp; + private final UncaughtExceptionHandler uncaughtExceptionHandler; + private final ForkJoinPool pool; + private final long capacity; + + /** + * Constructor. + * + * @param model the wiring model containing this scheduler + * @param name the name of the scheduler + * @param pool the fork join pool that will execute tasks on this scheduler + * @param uncaughtExceptionHandler the handler for uncaught exceptions + * @param onRamp an object counter that is incremented when data is added to the scheduler + * @param offRamp an object counter that is decremented when data is removed from the scheduler + * @param capacity the maximum desired capacity for this scheduler + * @param flushEnabled if true, then {@link #flush()} will be enabled, otherwise it will throw. + * @param squelchingEnabled if true, then squelching will be enabled, otherwise trying to squelch will throw + * @param insertionIsBlocking when data is inserted into this scheduler, will it block until capacity is + * available? + */ + public ConcurrentTaskScheduler( + @NonNull final TraceableWiringModel model, + @NonNull final String name, + @NonNull final ForkJoinPool pool, + @NonNull final UncaughtExceptionHandler uncaughtExceptionHandler, + @NonNull final ObjectCounter onRamp, + @NonNull final ObjectCounter offRamp, + final long capacity, + final boolean flushEnabled, + final boolean squelchingEnabled, + final boolean insertionIsBlocking) { + + super(model, name, TaskSchedulerType.CONCURRENT, flushEnabled, squelchingEnabled, insertionIsBlocking); + + this.pool = Objects.requireNonNull(pool); + this.uncaughtExceptionHandler = Objects.requireNonNull(uncaughtExceptionHandler); + this.onRamp = Objects.requireNonNull(onRamp); + this.offRamp = Objects.requireNonNull(offRamp); + this.capacity = capacity; + } + + /** + * {@inheritDoc} + */ + @Override + protected void put(@NonNull final Consumer handler, @NonNull final Object data) { + onRamp.onRamp(); + new ConcurrentTask(pool, offRamp, uncaughtExceptionHandler, handler, data).send(); + } + + /** + * {@inheritDoc} + */ + @Override + protected boolean offer(@NonNull final Consumer handler, @NonNull final Object data) { + final boolean accepted = onRamp.attemptOnRamp(); + if (accepted) { + new ConcurrentTask(pool, offRamp, uncaughtExceptionHandler, handler, data).send(); + } + return accepted; + } + + /** + * {@inheritDoc} + */ + @Override + protected void inject(@NonNull final Consumer handler, @NonNull final Object data) { + onRamp.forceOnRamp(); + new ConcurrentTask(pool, offRamp, uncaughtExceptionHandler, handler, data).send(); + } + + /** + * {@inheritDoc} + */ + @Override + public long getUnprocessedTaskCount() { + return onRamp.getCount(); + } + + /** + * {@inheritDoc} + */ + @Override + public long getCapacity() { + return capacity; + } + + /** + * {@inheritDoc} + */ + @Override + public void flush() { + throwIfFlushDisabled(); + onRamp.waitUntilEmpty(); + } +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/DefaultSquelcher.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/DefaultSquelcher.java new file mode 100644 index 00000000000..a430e40e2ba --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/DefaultSquelcher.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.schedulers.internal; + +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * A squelcher that actually supports squelching. + */ +public class DefaultSquelcher implements Squelcher { + /** + * Whether or not tasks should actively be squelched. + */ + private final AtomicBoolean squelchFlag = new AtomicBoolean(false); + + /** + * {@inheritDoc} + */ + @Override + public void startSquelching() { + if (!squelchFlag.compareAndSet(false, true)) { + throw new IllegalStateException("Scheduler is already squelching"); + } + } + + /** + * {@inheritDoc} + */ + @Override + public void stopSquelching() { + if (!squelchFlag.compareAndSet(true, false)) { + throw new IllegalStateException("Scheduler is not currently squelching"); + } + } + + /** + * {@inheritDoc} + */ + @Override + public boolean shouldSquelch() { + return squelchFlag.get(); + } +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/DirectTaskScheduler.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/DirectTaskScheduler.java new file mode 100644 index 00000000000..8c1d1e812d9 --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/DirectTaskScheduler.java @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.schedulers.internal; + +import static com.swirlds.wiring.schedulers.builders.TaskSchedulerBuilder.UNLIMITED_CAPACITY; + +import com.swirlds.common.metrics.extensions.FractionalTimer; +import com.swirlds.wiring.counters.ObjectCounter; +import com.swirlds.wiring.model.TraceableWiringModel; +import com.swirlds.wiring.schedulers.TaskScheduler; +import com.swirlds.wiring.schedulers.builders.TaskSchedulerType; +import edu.umd.cs.findbugs.annotations.NonNull; +import java.lang.Thread.UncaughtExceptionHandler; +import java.util.Objects; +import java.util.function.Consumer; + +/** + * A scheduler that performs work immediately on the caller's thread. + * + * @param the output type of the scheduler (use {@link Void} for a task scheduler with no output type) + */ +public class DirectTaskScheduler extends TaskScheduler { + + private final UncaughtExceptionHandler uncaughtExceptionHandler; + private final ObjectCounter onRamp; + private final ObjectCounter offRamp; + private final FractionalTimer busyTimer; + + /** + * Constructor. + * + * @param model the wiring model containing this task scheduler + * @param name the name of the task scheduler + * @param uncaughtExceptionHandler the uncaught exception handler + * @param onRamp an object counter that is incremented when data is added to the task scheduler + * @param offRamp an object counter that is decremented when data is removed from the task + * @param squelchingEnabled if true, then squelching will be enabled, otherwise trying to squelch will throw + * @param busyTimer a timer that tracks the amount of time the task scheduler is busy + * @param threadsafe true if the work scheduled by this object is threadsafe + */ + public DirectTaskScheduler( + @NonNull final TraceableWiringModel model, + @NonNull final String name, + @NonNull final UncaughtExceptionHandler uncaughtExceptionHandler, + @NonNull final ObjectCounter onRamp, + @NonNull final ObjectCounter offRamp, + final boolean squelchingEnabled, + @NonNull final FractionalTimer busyTimer, + final boolean threadsafe) { + super( + model, + name, + threadsafe ? TaskSchedulerType.DIRECT_THREADSAFE : TaskSchedulerType.DIRECT, + false, + squelchingEnabled, + true); + + this.uncaughtExceptionHandler = Objects.requireNonNull(uncaughtExceptionHandler); + this.onRamp = Objects.requireNonNull(onRamp); + this.offRamp = Objects.requireNonNull(offRamp); + this.busyTimer = Objects.requireNonNull(busyTimer); + } + + /** + * {@inheritDoc} + */ + @Override + public long getUnprocessedTaskCount() { + return onRamp.getCount(); + } + + /** + * {@inheritDoc} + */ + @Override + public long getCapacity() { + // Direct schedulers have no concept of capacity. + return UNLIMITED_CAPACITY; + } + + /** + * {@inheritDoc} + */ + @Override + public void flush() { + throw new UnsupportedOperationException("Direct task schedulers do not support flushing"); + } + + /** + * {@inheritDoc} + */ + @Override + protected void put(@NonNull final Consumer handler, @NonNull final Object data) { + onRamp.onRamp(); + handleAndOffRamp(handler, data); + } + + /** + * {@inheritDoc} + */ + @Override + protected boolean offer(@NonNull final Consumer handler, @NonNull final Object data) { + final boolean accepted = onRamp.attemptOnRamp(); + if (!accepted) { + return false; + } + handleAndOffRamp(handler, data); + return true; + } + + /** + * {@inheritDoc} + */ + @Override + protected void inject(@NonNull final Consumer handler, @NonNull final Object data) { + onRamp.forceOnRamp(); + handleAndOffRamp(handler, data); + } + + /** + * Helper method. Handles the data and then off ramps. + * + * @param handler the handler + * @param data the data + */ + private void handleAndOffRamp(@NonNull final Consumer handler, @NonNull final Object data) { + busyTimer.activate(); + try { + handler.accept(data); + } catch (final Throwable t) { + uncaughtExceptionHandler.uncaughtException(Thread.currentThread(), t); + } + busyTimer.deactivate(); + offRamp.offRamp(); + } +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/NoOpTaskScheduler.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/NoOpTaskScheduler.java new file mode 100644 index 00000000000..c41bc4e3c98 --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/NoOpTaskScheduler.java @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.schedulers.internal; + +import static com.swirlds.wiring.schedulers.builders.TaskSchedulerBuilder.UNLIMITED_CAPACITY; + +import com.swirlds.wiring.model.TraceableWiringModel; +import com.swirlds.wiring.schedulers.TaskScheduler; +import com.swirlds.wiring.schedulers.builders.TaskSchedulerType; +import com.swirlds.wiring.wires.input.BindableInputWire; +import com.swirlds.wiring.wires.input.NoOpInputWire; +import com.swirlds.wiring.wires.output.NoOpOutputWire; +import com.swirlds.wiring.wires.output.StandardOutputWire; +import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Objects; +import java.util.function.Consumer; + +/** + * A no-op task scheduler that does nothing. + * + * @param the output type of the scheduler (use {@link Void} for a task scheduler with no output type). This is + * just to appease the compiler, as this scheduler never produces output. + */ +public class NoOpTaskScheduler extends TaskScheduler { + + private final TraceableWiringModel model; + + /** + * Constructor. + * + * @param model the wiring model containing this task scheduler + * @param name the name of the task scheduler + * @param type the type of task scheduler + * @param flushEnabled if true, then {@link #flush()} will be enabled, otherwise it will throw. + * @param squelchingEnabled if true, then squelching will be enabled, otherwise trying to squelch will throw. + */ + public NoOpTaskScheduler( + @NonNull final TraceableWiringModel model, + @NonNull final String name, + @NonNull final TaskSchedulerType type, + final boolean flushEnabled, + final boolean squelchingEnabled) { + super(model, name, type, flushEnabled, squelchingEnabled, false); + + this.model = Objects.requireNonNull(model); + } + + /** + * {@inheritDoc} + */ + @Override + public long getUnprocessedTaskCount() { + return 0; + } + + @Override + public long getCapacity() { + // No op schedulers have no concept of capacity + return UNLIMITED_CAPACITY; + } + + /** + * {@inheritDoc} + */ + @Override + public void flush() { + throwIfFlushDisabled(); + } + + /** + * {@inheritDoc} + */ + @Override + protected void put(@NonNull final Consumer handler, @NonNull final Object data) { + throw new UnsupportedOperationException( + "Data should have been discarded before being sent to this no-op scheduler"); + } + + /** + * {@inheritDoc} + */ + @Override + protected boolean offer(@NonNull final Consumer handler, @NonNull final Object data) { + throw new UnsupportedOperationException( + "Data should have been discarded before being sent to this no-op scheduler"); + } + + /** + * {@inheritDoc} + */ + @Override + protected void inject(@NonNull final Consumer handler, @NonNull final Object data) { + throw new UnsupportedOperationException( + "Data should have been discarded before being sent to this no-op scheduler"); + } + + /** + * {@inheritDoc} + */ + @NonNull + @Override + protected StandardOutputWire buildPrimaryOutputWire( + @NonNull final TraceableWiringModel model, @NonNull final String name) { + return new NoOpOutputWire<>(model, getName()); + } + + /** + * {@inheritDoc} + */ + @NonNull + @Override + public StandardOutputWire buildSecondaryOutputWire() { + return new NoOpOutputWire<>(model, getName()); + } + + /** + * {@inheritDoc} + */ + @NonNull + @Override + public BindableInputWire buildInputWire(@NonNull final String name) { + return new NoOpInputWire<>(model, this, name); + } +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/SequentialTask.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/SequentialTask.java new file mode 100644 index 00000000000..dcc1402d587 --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/SequentialTask.java @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.schedulers.internal; + +import com.swirlds.common.metrics.extensions.FractionalTimer; +import com.swirlds.wiring.counters.ObjectCounter; +import com.swirlds.wiring.tasks.AbstractTask; +import edu.umd.cs.findbugs.annotations.NonNull; +import edu.umd.cs.findbugs.annotations.Nullable; +import java.lang.Thread.UncaughtExceptionHandler; +import java.util.concurrent.ForkJoinPool; +import java.util.function.Consumer; + +/** + * A task in a {@link SequentialTaskScheduler}. + */ +class SequentialTask extends AbstractTask { + private Consumer handler; + private Object data; + private SequentialTask nextTask; + private final ObjectCounter offRamp; + private final FractionalTimer busyTimer; + private final UncaughtExceptionHandler uncaughtExceptionHandler; + + /** + * Constructor. + * + * @param pool the fork join pool that will execute tasks on this task scheduler + * @param offRamp an object counter that is decremented when data is removed from the task + * scheduler + * @param busyTimer a timer that tracks the amount of time the task scheduler is busy + * @param uncaughtExceptionHandler the uncaught exception handler + * @param firstTask true if this is the first task in the scheduler, false otherwise + */ + SequentialTask( + @NonNull final ForkJoinPool pool, + @NonNull final ObjectCounter offRamp, + @NonNull final FractionalTimer busyTimer, + @NonNull final UncaughtExceptionHandler uncaughtExceptionHandler, + final boolean firstTask) { + super(pool, firstTask ? 1 : 2); + this.offRamp = offRamp; + this.busyTimer = busyTimer; + this.uncaughtExceptionHandler = uncaughtExceptionHandler; + } + + /** + * Provide a reference to the next task and the data that will be processed during the handling of this task. + * + * @param nextTask the task that will execute after this task + * @param handler the method that will be called when this task is executed + * @param data the data to be passed to the consumer for this task + */ + void send( + @NonNull final SequentialTask nextTask, + @NonNull final Consumer handler, + @Nullable final Object data) { + this.nextTask = nextTask; + this.handler = handler; + this.data = data; + + // This method provides us with the data we intend to send to the consumer + // when this task is executed, thus resolving one of the two dependencies + // required for the task to be executed. This call will decrement the + // dependency count. If this causes the dependency count to reach 0 + // (i.e. if the previous task has already been executed), then this call + // will cause this task to be immediately eligible for execution. + send(); + } + + /** + * Execute this task. + */ + @Override + public boolean exec() { + busyTimer.activate(); + try { + handler.accept(data); + } catch (final Throwable t) { + uncaughtExceptionHandler.uncaughtException(Thread.currentThread(), t); + } finally { + offRamp.offRamp(); + busyTimer.deactivate(); + + // Reduce the dependency count of the next task. If the next task already has its data, then this + // method will cause the next task to be immediately eligible for execution. + nextTask.send(); + } + return true; + } +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/SequentialTaskScheduler.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/SequentialTaskScheduler.java new file mode 100644 index 00000000000..d5b0f3be84f --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/SequentialTaskScheduler.java @@ -0,0 +1,166 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.schedulers.internal; + +import com.swirlds.common.metrics.extensions.FractionalTimer; +import com.swirlds.wiring.counters.ObjectCounter; +import com.swirlds.wiring.model.TraceableWiringModel; +import com.swirlds.wiring.schedulers.TaskScheduler; +import com.swirlds.wiring.schedulers.builders.TaskSchedulerType; +import edu.umd.cs.findbugs.annotations.NonNull; +import java.lang.Thread.UncaughtExceptionHandler; +import java.util.Objects; +import java.util.concurrent.ForkJoinPool; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Consumer; + +/** + * A {@link TaskScheduler} that guarantees that tasks are executed sequentially in the order they are received. + * + * @param the output type of the scheduler (use {@link Void} for a task scheduler with no output type) + */ +public class SequentialTaskScheduler extends TaskScheduler { + /** + * The next task to be scheduled will be inserted into this placeholder task. When that happens, a new task will be + * created and inserted into this placeholder. + */ + private final AtomicReference nextTaskPlaceholder; + + private final ObjectCounter onRamp; + private final ObjectCounter offRamp; + private final FractionalTimer busyTimer; + private final UncaughtExceptionHandler uncaughtExceptionHandler; + private final ForkJoinPool pool; + private final long capacity; + + /** + * Constructor. + * + * @param model the wiring model containing this scheduler + * @param name the name of the task scheduler + * @param pool the fork join pool that will execute tasks on this scheduler + * @param uncaughtExceptionHandler the uncaught exception handler + * @param onRamp an object counter that is incremented when data is added to the task scheduler + * @param offRamp an object counter that is decremented when data is removed from the task + * scheduler + * @param busyTimer a timer that tracks the amount of time the scheduler is busy + * @param capacity the maximum desired capacity for this task scheduler + * @param flushEnabled if true, then {@link #flush()} will be enabled, otherwise it will throw. + * @param squelchingEnabled if true, then squelching will be enabled, otherwise trying to squelch will throw + * @param insertionIsBlocking when data is inserted into this task scheduler, will it block until capacity is + * available? + */ + public SequentialTaskScheduler( + @NonNull final TraceableWiringModel model, + @NonNull final String name, + @NonNull ForkJoinPool pool, + @NonNull final UncaughtExceptionHandler uncaughtExceptionHandler, + @NonNull final ObjectCounter onRamp, + @NonNull final ObjectCounter offRamp, + @NonNull final FractionalTimer busyTimer, + final long capacity, + final boolean flushEnabled, + final boolean squelchingEnabled, + final boolean insertionIsBlocking) { + + super(model, name, TaskSchedulerType.SEQUENTIAL, flushEnabled, squelchingEnabled, insertionIsBlocking); + + this.pool = Objects.requireNonNull(pool); + this.uncaughtExceptionHandler = Objects.requireNonNull(uncaughtExceptionHandler); + this.onRamp = Objects.requireNonNull(onRamp); + this.offRamp = Objects.requireNonNull(offRamp); + this.busyTimer = Objects.requireNonNull(busyTimer); + this.capacity = capacity; + + this.nextTaskPlaceholder = + new AtomicReference<>(new SequentialTask(pool, offRamp, busyTimer, uncaughtExceptionHandler, true)); + } + + /** + * {@inheritDoc} + */ + @Override + protected void put(@NonNull final Consumer handler, @NonNull final Object data) { + onRamp.onRamp(); + scheduleTask(handler, data); + } + + /** + * {@inheritDoc} + */ + @Override + protected boolean offer(@NonNull final Consumer handler, @NonNull final Object data) { + final boolean accepted = onRamp.attemptOnRamp(); + if (accepted) { + scheduleTask(handler, data); + } + return accepted; + } + + /** + * {@inheritDoc} + */ + @Override + protected void inject(@NonNull final Consumer handler, @NonNull final Object data) { + onRamp.forceOnRamp(); + scheduleTask(handler, data); + } + + /** + * Schedule a task to be handled. This should only be called after successfully on-ramping (one way or another). + * + * @param handler the method that will be called when this task is executed + * @param data the data to be passed to the consumer for this task + */ + private void scheduleTask(@NonNull final Consumer handler, @NonNull final Object data) { + // This method may be called by many threads, but actual execution is required to happen serially. This method + // organizes tasks into a linked list. Tasks in this linked list are executed one at a time in order. + // When execution of one task is completed, execution of the next task is scheduled on the pool. + + final SequentialTask nextTask = new SequentialTask(pool, offRamp, busyTimer, uncaughtExceptionHandler, false); + SequentialTask currentTask; + do { + currentTask = nextTaskPlaceholder.get(); + } while (!nextTaskPlaceholder.compareAndSet(currentTask, nextTask)); + currentTask.send(nextTask, handler, data); + } + + /** + * {@inheritDoc} + */ + @Override + public long getUnprocessedTaskCount() { + return onRamp.getCount(); + } + + /** + * {@inheritDoc} + */ + @Override + public long getCapacity() { + return capacity; + } + + /** + * {@inheritDoc} + */ + @Override + public void flush() { + throwIfFlushDisabled(); + onRamp.waitUntilEmpty(); + } +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/SequentialThreadTask.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/SequentialThreadTask.java new file mode 100644 index 00000000000..d5adf7ddbb6 --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/SequentialThreadTask.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.schedulers.internal; + +import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.function.Consumer; + +/** + * A task that is performed by a {@link SequentialThreadTaskScheduler}. + * + * @param handler the handler to call + * @param data the data to pass to the handler + */ +record SequentialThreadTask(@NonNull Consumer handler, @NonNull Object data) { + + /** + * Handle the task. + */ + public void handle() { + handler.accept(data); + } +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/SequentialThreadTaskScheduler.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/SequentialThreadTaskScheduler.java new file mode 100644 index 00000000000..289e909a6bf --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/SequentialThreadTaskScheduler.java @@ -0,0 +1,204 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.schedulers.internal; + +import com.swirlds.base.state.Startable; +import com.swirlds.base.state.Stoppable; +import com.swirlds.common.metrics.extensions.FractionalTimer; +import com.swirlds.wiring.counters.ObjectCounter; +import com.swirlds.wiring.model.TraceableWiringModel; +import com.swirlds.wiring.schedulers.TaskScheduler; +import com.swirlds.wiring.schedulers.builders.TaskSchedulerType; +import edu.umd.cs.findbugs.annotations.NonNull; +import java.lang.Thread.UncaughtExceptionHandler; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Consumer; +import java.util.function.ToLongFunction; + +/** + * A scheduler that performs work sequentially on a dedicated thread. This class has very similar semantics to + * {@link DirectTaskScheduler}, except that work is done on a thread instead of on a fork join pool. + * + * @param the type of the primary output wire + */ +public class SequentialThreadTaskScheduler extends TaskScheduler implements Startable, Stoppable { + + private final UncaughtExceptionHandler uncaughtExceptionHandler; + private final ObjectCounter onRamp; + private final ObjectCounter offRamp; + private final ToLongFunction dataCounter; + private final FractionalTimer busyTimer; + private final long capacity; + + private final BlockingQueue tasks = new LinkedBlockingQueue<>(); + + private static final int BUFFER_SIZE = 1024; + + private final AtomicBoolean alive = new AtomicBoolean(true); + + private final Thread thread; + + /** + * Constructor. + * + * @param model the wiring model containing this task scheduler + * @param name the name of the task scheduler + * @param uncaughtExceptionHandler the handler to call when an exception is thrown by a task + * @param onRamp the counter to increment when a task is added to the queue + * @param offRamp the counter to decrement when a task is removed from the queue + * @param dataCounter the function to weight input data objects for health monitoring + * @param busyTimer the timer to activate when a task is being handled + * @param capacity the maximum desired capacity for this task scheduler + * @param flushEnabled if true, then {@link #flush()} will be enabled, otherwise it will throw. + * @param squelchingEnabled if true, then squelching will be enabled, otherwise trying to squelch will throw + * @param insertionIsBlocking when data is inserted into this task scheduler, will it block until capacity is + * available? + */ + public SequentialThreadTaskScheduler( + @NonNull final TraceableWiringModel model, + @NonNull final String name, + @NonNull final UncaughtExceptionHandler uncaughtExceptionHandler, + @NonNull final ObjectCounter onRamp, + @NonNull final ObjectCounter offRamp, + @NonNull final ToLongFunction dataCounter, + @NonNull final FractionalTimer busyTimer, + final long capacity, + final boolean flushEnabled, + final boolean squelchingEnabled, + final boolean insertionIsBlocking) { + super(model, name, TaskSchedulerType.SEQUENTIAL_THREAD, flushEnabled, squelchingEnabled, insertionIsBlocking); + + this.uncaughtExceptionHandler = Objects.requireNonNull(uncaughtExceptionHandler); + this.onRamp = Objects.requireNonNull(onRamp); + this.offRamp = Objects.requireNonNull(offRamp); + this.dataCounter = dataCounter; + this.busyTimer = Objects.requireNonNull(busyTimer); + this.capacity = capacity; + + thread = new Thread(this::run, ""); + } + + /** + * {@inheritDoc} + */ + @Override + public long getUnprocessedTaskCount() { + return onRamp.getCount(); + } + + /** + * {@inheritDoc} + */ + @Override + public long getCapacity() { + return capacity; + } + + /** + * {@inheritDoc} + */ + @Override + public void flush() { + throwIfFlushDisabled(); + onRamp.waitUntilEmpty(); + } + + /** + * {@inheritDoc} + */ + @Override + protected void put(@NonNull final Consumer handler, @NonNull final Object data) { + onRamp.onRamp(dataCounter.applyAsLong(data)); + tasks.add(new SequentialThreadTask(handler, data)); + } + + /** + * {@inheritDoc} + */ + @Override + protected boolean offer(@NonNull final Consumer handler, @NonNull final Object data) { + final boolean accepted = onRamp.attemptOnRamp(dataCounter.applyAsLong(data)); + if (!accepted) { + return false; + } + tasks.add(new SequentialThreadTask(handler, data)); + return true; + } + + /** + * {@inheritDoc} + */ + @Override + protected void inject(@NonNull final Consumer handler, @NonNull final Object data) { + onRamp.forceOnRamp(dataCounter.applyAsLong(data)); + tasks.add(new SequentialThreadTask(handler, data)); + } + + /** + * {@inheritDoc} + */ + @Override + public void start() { + thread.start(); + } + + /** + * {@inheritDoc} + */ + @Override + public void stop() { + alive.set(false); + } + + /** + * Take work off of the queue and handle it. + */ + private void run() { + final List buffer = new ArrayList<>(BUFFER_SIZE); + + while (alive.get()) { + if (tasks.drainTo(buffer, BUFFER_SIZE) == 0) { + try { + final SequentialThreadTask task = tasks.take(); + buffer.add(task); + } catch (final InterruptedException e) { + Thread.currentThread().interrupt(); + return; + } + } + + busyTimer.activate(); + for (final SequentialThreadTask task : buffer) { + try { + task.handle(); + } catch (final Throwable t) { + uncaughtExceptionHandler.uncaughtException(thread, t); + } finally { + offRamp.offRamp(dataCounter.applyAsLong(task.data())); + } + } + busyTimer.deactivate(); + + buffer.clear(); + } + } +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/Squelcher.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/Squelcher.java new file mode 100644 index 00000000000..5b7639a29be --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/Squelcher.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.schedulers.internal; + +/** + * Manages whether or not tasks scheduled by a given task scheduler should be squelched. + *

+ * Squelching is a mechanism that allows a task scheduler to temporarily suppress the execution of tasks. When a + * scheduler is being squelched, any new tasks that are received are simply discarded. Any previously scheduled tasks + * are either cleared, or executed as a no-op. + */ +public interface Squelcher { + /** + * Start squelching, and continue doing so until {@link #stopSquelching()} is called. + * + * @throws UnsupportedOperationException if squelching is not supported by this scheduler + * @throws IllegalStateException if scheduler is already squelching + */ + void startSquelching(); + + /** + * Stop squelching. + * + * @throws UnsupportedOperationException if squelching is not supported by this scheduler + * @throws IllegalStateException if scheduler is not currently squelching + */ + void stopSquelching(); + + /** + * Get whether or not tasks created by the relevant scheduler should be squelched. + *

+ * If squelching isn't enabled, then this method will always return false. + * + * @return true if tasks should be squelched, false otherwise + */ + boolean shouldSquelch(); +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/ThrowingSquelcher.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/ThrowingSquelcher.java new file mode 100644 index 00000000000..9abaae540fa --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/ThrowingSquelcher.java @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.schedulers.internal; + +/** + * A squelcher object that does not support squelching. + */ +public class ThrowingSquelcher implements Squelcher { + /** + * {@inheritDoc} + * + * @throws UnsupportedOperationException always + */ + @Override + public void startSquelching() { + throw new UnsupportedOperationException("Squelching is not supported by this task scheduler"); + } + + /** + * {@inheritDoc} + * + * @throws UnsupportedOperationException always + */ + @Override + public void stopSquelching() { + throw new UnsupportedOperationException("Squelching is not supported by this task scheduler"); + } + + /** + * {@inheritDoc} + * + * @return false + */ + @Override + public boolean shouldSquelch() { + return false; + } +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/tasks/AbstractTask.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/tasks/AbstractTask.java new file mode 100644 index 00000000000..64a9cdb0e23 --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/tasks/AbstractTask.java @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.tasks; + +import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.concurrent.ForkJoinPool; +import java.util.concurrent.ForkJoinTask; +import java.util.concurrent.ForkJoinWorkerThread; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * A unit of work that is processed by a task scheduler. + */ +public abstract class AbstractTask extends ForkJoinTask { + + /** + * Counts outstanding dependencies. When it reaches 0, the task is ready to run. + */ + private final AtomicInteger dependencyCount; + + /** + * The fork join pool that will execute this task. + */ + private final ForkJoinPool pool; + + /** + * Constructor. + * + * @param pool the fork join pool that will execute this task + * @param dependencyCount the number of dependencies that must be satisfied before this task is eligible for + * execution + */ + protected AbstractTask(@NonNull final ForkJoinPool pool, final int dependencyCount) { + this.pool = pool; + this.dependencyCount = dependencyCount > 0 ? new AtomicInteger(dependencyCount) : null; + } + + /** + * Unused. + */ + @Override + public final Void getRawResult() { + return null; + } + + /** + * Unused. + */ + @Override + protected final void setRawResult(Void value) {} + + /** + * If the task has no dependencies then execute it. If the task has dependencies, decrement the dependency count and + * execute it if the resulting number of dependencies is zero. + */ + public void send() { + if (dependencyCount == null || dependencyCount.decrementAndGet() == 0) { + if ((Thread.currentThread() instanceof ForkJoinWorkerThread t) && (t.getPool() == pool)) { + fork(); + } else { + pool.execute(this); + } + } + } + + /** + * Execute the work represented by this task. + * + * @return true if this task is known to have been completed normally + */ + @Override + protected abstract boolean exec(); +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/transformers/AdvancedTransformation.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/transformers/AdvancedTransformation.java new file mode 100644 index 00000000000..2c00ddb954f --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/transformers/AdvancedTransformation.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.transformers; + +import com.swirlds.wiring.wires.output.OutputWire; +import edu.umd.cs.findbugs.annotations.NonNull; +import edu.umd.cs.findbugs.annotations.Nullable; + +/** + * Executes a transformation for an advanced transformer as created by + * {@link OutputWire#buildAdvancedTransformer(AdvancedTransformation)}. + * + * @param the original wire output type + * @param the output type of the transformer + */ +public interface AdvancedTransformation { + + /** + * Given data that comes off of the original output wire, this method transforms it before it is passed to each + * input wire that is connected to this transformer. Called once per data element per listener. + * + * @param a a data element from the original output wire + * @return the transformed data element, or null if the data should not be forwarded + */ + @Nullable + B transform(@NonNull A a); + + /** + * Called on the original data element after it has been forwarded to all listeners. This method can do cleanup if + * necessary. Doing nothing is perfectly ok if the use case does not require cleanup. + * + * @param a the original data element + */ + void inputCleanup(@NonNull A a); + + /** + * Called on the transformed data element if it is rejected by a listener. This is possible if offer soldering is + * used and the destination declines to take the data. + * + * @param b the transformed data element + */ + void outputCleanup(@NonNull B b); + + /** + * @return the name of this transformer + */ + @NonNull + String getTransformerName(); + + /** + * Return the name of the input wire that feeds data into this transformer. + * + * @return the name of the input wire + */ + @NonNull + String getTransformerInputName(); +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/transformers/RoutableData.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/transformers/RoutableData.java new file mode 100644 index 00000000000..206db31ac7e --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/transformers/RoutableData.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.transformers; + +import edu.umd.cs.findbugs.annotations.NonNull; + +/** + * Data that can be routed to a specific address. + * + * @param address the address to route to (will be an enum value from ROUTER_TYPE) + * @param data the data + * @param the type of the enum that defines the addresses + */ +public record RoutableData>(@NonNull ROUTER_TYPE address, @NonNull Object data) {} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/transformers/WireFilter.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/transformers/WireFilter.java new file mode 100644 index 00000000000..ecf4cd70f03 --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/transformers/WireFilter.java @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.transformers; + +import com.swirlds.wiring.model.WiringModel; +import com.swirlds.wiring.schedulers.TaskScheduler; +import com.swirlds.wiring.schedulers.builders.TaskSchedulerType; +import com.swirlds.wiring.wires.input.BindableInputWire; +import com.swirlds.wiring.wires.input.InputWire; +import com.swirlds.wiring.wires.output.OutputWire; +import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Objects; +import java.util.function.Predicate; + +/** + * Filters out data, allowing some objects to pass and blocking others. + * + * @param the type of data being filtered + */ +public class WireFilter { + + private final BindableInputWire inputWire; + private final OutputWire outputWire; + + /** + * Constructor. Immediately binds the transformation function to the input wire. + * + * @param model the wiring model containing this output channel + * @param filterName the name of the filter + * @param filterInputName the label for the input wire going into the filter + * @param predicate only data that causes this method to return true is forwarded. This method must be very + * fast. Putting large amounts of work into this transformer violates the intended usage + * pattern of the wiring framework and may result in very poor system performance. + */ + public WireFilter( + @NonNull final WiringModel model, + @NonNull final String filterName, + @NonNull final String filterInputName, + @NonNull final Predicate predicate) { + + Objects.requireNonNull(predicate); + + final TaskScheduler taskScheduler = model.schedulerBuilder(filterName) + .withType(TaskSchedulerType.DIRECT_THREADSAFE) + .build() + .cast(); + + inputWire = taskScheduler.buildInputWire(filterInputName); + inputWire.bind(t -> { + if (predicate.test(t)) { + return t; + } + return null; + }); + outputWire = taskScheduler.getOutputWire(); + } + + /** + * Constructor. + * + * @param model the wiring model containing this output channel + * @param filterName the name of the filter + * @param filterInputName the label for the input wire going into the filter + */ + public WireFilter( + @NonNull final WiringModel model, @NonNull final String filterName, @NonNull final String filterInputName) { + + final TaskScheduler taskScheduler = model.schedulerBuilder(filterName) + .withType(TaskSchedulerType.DIRECT_THREADSAFE) + .build() + .cast(); + + inputWire = taskScheduler.buildInputWire(filterInputName); + outputWire = taskScheduler.getOutputWire(); + } + + /** + * Get the input wire for this filter. + * + * @return the input wire + */ + @NonNull + public InputWire getInputWire() { + return inputWire; + } + + /** + * Get the output wire for this filter. + * + * @return the output wire + */ + @NonNull + public OutputWire getOutputWire() { + return outputWire; + } + + /** + * Bind a predicate to this filter. Should not be called if this object was constructed using + * {@link #WireFilter(WiringModel, String, String, Predicate)}. Must be called prior to use if this object was + * constructed using {@link #WireFilter(WiringModel, String, String)}. + * + * @param predicate the predicate to bind + */ + public void bind(@NonNull final Predicate predicate) { + inputWire.bind(t -> { + if (predicate.test(t)) { + return t; + } + return null; + }); + } +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/transformers/WireListSplitter.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/transformers/WireListSplitter.java new file mode 100644 index 00000000000..48536e512b1 --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/transformers/WireListSplitter.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.transformers; + +import com.swirlds.wiring.model.WiringModel; +import com.swirlds.wiring.schedulers.TaskScheduler; +import com.swirlds.wiring.schedulers.builders.TaskSchedulerType; +import com.swirlds.wiring.wires.input.BindableInputWire; +import com.swirlds.wiring.wires.input.InputWire; +import com.swirlds.wiring.wires.output.OutputWire; +import com.swirlds.wiring.wires.output.StandardOutputWire; +import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.List; + +/** + * Transforms a list of items to a sequence of individual items. Expects that there will not be any null values in the + * collection. + * + * @param the type of data in the list that is being split + */ +public class WireListSplitter { + + private final BindableInputWire, T> inputWire; + private final StandardOutputWire outputWire; + + /** + * Constructor. + * + * @param model the wiring model containing this output wire + * @param splitterName the name of the output channel + * @param splitterInputName the label for the input wire going into the splitter + */ + public WireListSplitter( + @NonNull final WiringModel model, + @NonNull final String splitterName, + @NonNull final String splitterInputName) { + final TaskScheduler taskScheduler = model.schedulerBuilder(splitterName) + .withType(TaskSchedulerType.DIRECT_THREADSAFE) + .build() + .cast(); + + inputWire = taskScheduler.buildInputWire(splitterInputName); + outputWire = (StandardOutputWire) taskScheduler.getOutputWire(); + + inputWire.bindConsumer(list -> { + for (final T t : list) { + outputWire.forward(t); + } + }); + } + + /** + * Get the input wire for this splitter. + * + * @return the input wire + */ + @NonNull + public InputWire> getInputWire() { + return inputWire; + } + + /** + * Get the output wire for this splitter. + * + * @return the output wire + */ + @NonNull + public OutputWire getOutputWire() { + return outputWire; + } +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/transformers/WireRouter.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/transformers/WireRouter.java new file mode 100644 index 00000000000..9f2c2103c36 --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/transformers/WireRouter.java @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.transformers; + +import static com.swirlds.wiring.schedulers.builders.TaskSchedulerType.DIRECT_THREADSAFE; + +import com.swirlds.wiring.model.WiringModel; +import com.swirlds.wiring.schedulers.TaskScheduler; +import com.swirlds.wiring.wires.input.BindableInputWire; +import com.swirlds.wiring.wires.input.InputWire; +import com.swirlds.wiring.wires.output.OutputWire; +import com.swirlds.wiring.wires.output.StandardOutputWire; +import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.ArrayList; +import java.util.List; + +/** + * Create a wire router. A wire router takes a single input and splits data into multiple outputs with different + * addresses. When data is sent to a router, the address is also sent. The router then sends the data to the output wire + * at the specified address. + * + * @param an enum that describes the addresses where data can be routed. Each enum value corresponds to a + * different address where data can be routed. + */ +public class WireRouter> { + + private final BindableInputWire, Void> inputWire; + private final List> outputWires; + private final Class clazz; + + /** + * Constructor. + * + * @param model the wiring model containing this router + * @param routerName the name of the router + * @param routerInputName the label for the input wire going into the router + * @param clazz the class of the enum that describes the different addresses that data can be routed to. + */ + public WireRouter( + @NonNull final WiringModel model, + @NonNull final String routerName, + @NonNull final String routerInputName, + @NonNull final Class clazz) { + final TaskScheduler scheduler = model.schedulerBuilder(routerName) + .withType(DIRECT_THREADSAFE) + .build() + .cast(); + + outputWires = new ArrayList<>(clazz.getEnumConstants().length); + for (int index = 0; index < clazz.getEnumConstants().length; index++) { + final ROUTER_TYPE dataType = clazz.getEnumConstants()[index]; + if (dataType.ordinal() != index) { + throw new IllegalArgumentException("Enum values must be in order"); + } + + final StandardOutputWire outputWire = scheduler.buildSecondaryOutputWire(); + outputWires.add(outputWire); + } + + inputWire = scheduler.buildInputWire(routerInputName); + inputWire.bindConsumer(this::routeData); + this.clazz = clazz; + } + + /** + * Get the input wire. + * + * @return the input wire + */ + @NonNull + public InputWire> getInput() { + return inputWire; + } + + /** + * Get the output wire for a specific address. + * + * @param address the data type + * @param the type of data that the output wire carries + * @return the output wire + */ + @NonNull + @SuppressWarnings("unchecked") + public OutputWire getOutput(@NonNull final ROUTER_TYPE address) { + return (OutputWire) outputWires.get(address.ordinal()); + } + + /** + * Get the type of the enum that defines this router. + * + * @return the class of the enum + */ + @NonNull + public Class getRouterType() { + return clazz; + } + + /** + * Route data to the appropriate output wire. + * + * @param routableData the data to route + */ + private void routeData(@NonNull final RoutableData routableData) { + final ROUTER_TYPE dataType = routableData.address(); + final StandardOutputWire outputWire = outputWires.get(dataType.ordinal()); + outputWire.forward(routableData.data()); + } +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/transformers/WireTransformer.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/transformers/WireTransformer.java new file mode 100644 index 00000000000..99dcffc2152 --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/transformers/WireTransformer.java @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.transformers; + +import com.swirlds.wiring.model.WiringModel; +import com.swirlds.wiring.schedulers.TaskScheduler; +import com.swirlds.wiring.schedulers.builders.TaskSchedulerType; +import com.swirlds.wiring.wires.input.BindableInputWire; +import com.swirlds.wiring.wires.input.InputWire; +import com.swirlds.wiring.wires.output.OutputWire; +import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Objects; +import java.util.function.Function; + +/** + * Transforms data on a wire from one type to another. + * + * @param the input type + * @param the output type + */ +public class WireTransformer { + + private final BindableInputWire inputWire; + private final OutputWire outputWire; + + /** + * Constructor. Immediately binds the transformation function to the input wire. + * + * @param model the wiring model containing this output channel + * @param transformerName the name of the transformer + * @param transformerInputName the label for the input wire going into the transformer + * @param transformer an object that transforms from type A to type B. If this method returns null then no + * data is forwarded. This method must be very fast. Putting large amounts of work into + * this transformer violates the intended usage pattern of the wiring framework and may + * result in very poor system performance. + */ + public WireTransformer( + @NonNull final WiringModel model, + @NonNull final String transformerName, + @NonNull final String transformerInputName, + @NonNull final Function transformer) { + Objects.requireNonNull(transformer); + + final TaskScheduler taskScheduler = model.schedulerBuilder(transformerName) + .withType(TaskSchedulerType.DIRECT_THREADSAFE) + .build() + .cast(); + + inputWire = taskScheduler.buildInputWire(transformerInputName); + inputWire.bind(transformer); + outputWire = taskScheduler.getOutputWire(); + } + + /** + * Constructor. Requires the input wire to be bound later. + * + * @param model the wiring model containing this output channel + * @param transformerName the name of the transformer + * @param transformerInputName the label for the input wire going into the transformer + */ + public WireTransformer( + @NonNull final WiringModel model, + @NonNull final String transformerName, + @NonNull final String transformerInputName) { + + final TaskScheduler taskScheduler = model.schedulerBuilder(transformerName) + .withType(TaskSchedulerType.DIRECT_THREADSAFE) + .build() + .cast(); + + inputWire = taskScheduler.buildInputWire(transformerInputName); + outputWire = taskScheduler.getOutputWire(); + } + + /** + * Get the input wire for this transformer. + * + * @return the input wire + */ + @NonNull + public InputWire getInputWire() { + return inputWire; + } + + /** + * Get the output wire for this transformer. + * + * @return the output wire + */ + @NonNull + public OutputWire getOutputWire() { + return outputWire; + } + + /** + * Bind the transformation function to the input wire. Do not call this if the transformation function was provided + * in the constructor. Must be called prior to use if the transformation function was not provided in the + * constructor. + * + * @param transformer the transformation function + */ + public void bind(@NonNull final Function transformer) { + inputWire.bind(transformer); + } +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/SolderType.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/SolderType.java new file mode 100644 index 00000000000..5e955dc2341 --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/SolderType.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.wires; + +import com.swirlds.wiring.wires.input.InputWire; + +/** + * The type of solder connection between an output wire and an input wire. + */ +public enum SolderType { + /** + * When data is passed to the input wire, call {@link InputWire#put(Object)}. May block if the input wire has + * backpressure enabled and the input wire is full. + */ + PUT, + /** + * When data is passed to the input wire, call {@link InputWire#inject(Object)}. Ignores back pressure. + */ + INJECT, + /** + * When data is passed to the input wire, call {@link InputWire#offer(Object)}. If the input wire has backpressure + * enabled and the input wire is full, then the data will be dropped. + */ + OFFER +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/input/Bindable.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/input/Bindable.java new file mode 100644 index 00000000000..3f3480f2e3c --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/input/Bindable.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.wires.input; + +import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.function.Consumer; +import java.util.function.Function; + +/** + * An object that can be bound to a handler. + * + * @param the type of data that enters + * @param the type of data that is permitted to be passed out (non-null values are forwarded to the primary output + * wire) + */ +public interface Bindable { + + /** + * Bind this object to a handler. For things that don't send data to the output wire. + * + * @param handler the handler to bind to this input wire + * @throws IllegalStateException if a handler is already bound and this method is called a second time + */ + void bindConsumer(@NonNull Consumer handler); + + /** + * Bind this object to a handler. + * + * @param handler the handler to bind to this input task scheduler, values returned are passed to the primary output + * wire of the associated scheduler. + * @throws IllegalStateException if a handler is already bound and this method is called a second time + */ + void bind(@NonNull final Function handler); +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/input/BindableInputWire.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/input/BindableInputWire.java new file mode 100644 index 00000000000..d5cda97ec96 --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/input/BindableInputWire.java @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.wires.input; + +import static com.swirlds.wiring.schedulers.builders.TaskSchedulerType.NO_OP; + +import com.swirlds.wiring.model.TraceableWiringModel; +import com.swirlds.wiring.schedulers.TaskScheduler; +import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Objects; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Supplier; + +/** + * An input wire that can be bound to an implementation. + * + * @param the type of data that passes into the wire + * @param the type of the primary output wire for the scheduler that is associated with this object + */ +public class BindableInputWire extends InputWire implements Bindable { + + private final TaskSchedulerInput taskSchedulerInput; + private final String taskSchedulerName; + private final TraceableWiringModel model; + + /** + * Supplier for whether the task scheduler is currently squelching. + *

+ * As long as this supplier returns true, the handler will be executed as a no-op, and no data will be forwarded. + */ + private final Supplier currentlySquelching; + + /** + * True if this is a wire on a no-op scheduler. + */ + private final boolean noOp; + + /** + * Constructor. + * + * @param model the wiring model containing this input wire + * @param taskScheduler the scheduler to insert data into + * @param name the name of the input wire + */ + public BindableInputWire( + @NonNull final TraceableWiringModel model, + @NonNull final TaskScheduler taskScheduler, + @NonNull final String name) { + super(taskScheduler, name); + this.model = Objects.requireNonNull(model); + taskSchedulerInput = Objects.requireNonNull(taskScheduler); + taskSchedulerName = taskScheduler.getName(); + currentlySquelching = taskScheduler::currentlySquelching; + + noOp = taskScheduler.getType() == NO_OP; + + if (noOp) { + return; + } + model.registerInputWireCreation(taskSchedulerName, name); + } + + /** + * {@inheritDoc} + */ + @SuppressWarnings("unchecked") + public void bindConsumer(@NonNull final Consumer handler) { + Objects.requireNonNull(handler); + if (noOp) { + return; + } + setHandler(i -> { + if (currentlySquelching.get()) { + return; + } + + handler.accept((IN) i); + }); + model.registerInputWireBinding(taskSchedulerName, getName()); + } + + /** + * {@inheritDoc} + */ + @SuppressWarnings("unchecked") + public void bind(@NonNull final Function handler) { + Objects.requireNonNull(handler); + if (noOp) { + return; + } + setHandler(i -> { + if (currentlySquelching.get()) { + return; + } + + final OUT output = handler.apply((IN) i); + if (output != null) { + taskSchedulerInput.forward(output); + } + }); + model.registerInputWireBinding(taskSchedulerName, getName()); + } +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/input/InputWire.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/input/InputWire.java new file mode 100644 index 00000000000..7b71bfc6827 --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/input/InputWire.java @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.wires.input; + +import com.swirlds.wiring.schedulers.TaskScheduler; +import com.swirlds.wiring.schedulers.builders.TaskSchedulerType; +import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Objects; +import java.util.function.Consumer; + +/** + * An object that can insert work to be handled by a {@link TaskScheduler}. + * + * @param the type of data that passes into the wire + */ +public abstract class InputWire { + + private final TaskSchedulerInput taskSchedulerInput; + private Consumer handler; + private final String name; + private final String taskSchedulerName; + private final TaskSchedulerType taskSchedulerType; + + /** + * Constructor. + * + * @param taskScheduler the scheduler to insert data into + * @param name the name of the input wire + */ + protected InputWire(@NonNull final TaskScheduler taskScheduler, @NonNull final String name) { + this.taskSchedulerInput = Objects.requireNonNull(taskScheduler); + this.name = Objects.requireNonNull(name); + this.taskSchedulerName = taskScheduler.getName(); + this.taskSchedulerType = taskScheduler.getType(); + } + + /** + * Get the name of this input wire. + * + * @return the name of this input wire + */ + @NonNull + public String getName() { + return name; + } + + /** + * Get the name of the task scheduler this input channel is bound to. + * + * @return the name of the wire this input channel is bound to + */ + @NonNull + public String getTaskSchedulerName() { + return taskSchedulerName; + } + + /** + * Get the type of the task scheduler that this input channel is bound to. + * + * @return the type of the task scheduler that this input channel is bound to + */ + @NonNull + public TaskSchedulerType getTaskSchedulerType() { + return taskSchedulerType; + } + + /** + * Add a task to the task scheduler. May block if back pressure is enabled. + * + * @param data the data to be processed by the task scheduler + */ + public void put(@NonNull final IN data) { + taskSchedulerInput.put(handler, data); + } + + /** + * Add a task to the task scheduler. If backpressure is enabled and there is not immediately capacity available, + * this method will not accept the data. + * + * @param data the data to be processed by the task scheduler + * @return true if the data was accepted, false otherwise + */ + public boolean offer(@NonNull final IN data) { + return taskSchedulerInput.offer(handler, data); + } + + /** + * Inject data into the task scheduler, doing so even if it causes the number of unprocessed tasks to exceed the + * capacity specified by configured back pressure. If backpressure is disabled, this operation is logically + * equivalent to {@link #put(Object)}. + * + * @param data the data to be processed by the task scheduler + */ + public void inject(@NonNull final IN data) { + taskSchedulerInput.inject(handler, data); + } + + /** + * Set the method that will handle data traveling over this wire. + * + * @param handler the method that will handle data traveling over this wire + */ + protected void setHandler(@NonNull final Consumer handler) { + if (this.handler != null) { + throw new IllegalStateException("Handler already bound"); + } + this.handler = Objects.requireNonNull(handler); + } +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/input/NoOpInputWire.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/input/NoOpInputWire.java new file mode 100644 index 00000000000..505c4741113 --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/input/NoOpInputWire.java @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.wires.input; + +import com.swirlds.wiring.model.TraceableWiringModel; +import com.swirlds.wiring.schedulers.TaskScheduler; +import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.function.Consumer; +import java.util.function.Function; + +/** + * An input wire that doesn't actually do anything. When asked to bind a handler, it does nothing. When asked to insert + * data, it does nothing. + * + * @param the type of data that passes into the wire + * @param the type of the primary output wire for the scheduler that is associated with this object + */ +public class NoOpInputWire extends BindableInputWire { + /** + * Constructor. + * + * @param model the wiring model containing this input wire + * @param taskScheduler the scheduler to insert data into + * @param name the name of the input wire + */ + public NoOpInputWire( + @NonNull final TraceableWiringModel model, + @NonNull final TaskScheduler taskScheduler, + @NonNull final String name) { + super(model, taskScheduler, name); + } + + /** + * {@inheritDoc} + */ + @Override + public void bindConsumer(@NonNull final Consumer handler) { + // intentional no-op + } + + /** + * {@inheritDoc} + */ + @Override + public void bind(@NonNull final Function handler) { + // intentional no-op + } + + /** + * {@inheritDoc} + */ + @Override + public void put(@NonNull final IN data) { + // intentional no-op + } + + /** + * {@inheritDoc} + */ + @Override + public boolean offer(@NonNull final IN data) { + return true; + } + + /** + * {@inheritDoc} + */ + @Override + public void inject(@NonNull final IN data) { + // intentional no-op + } +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/input/TaskSchedulerInput.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/input/TaskSchedulerInput.java new file mode 100644 index 00000000000..6ef6fc9868c --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/input/TaskSchedulerInput.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.wires.input; + +import com.swirlds.wiring.schedulers.TaskScheduler; +import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.function.Consumer; + +/** + * An object that knows how to add data to a {@link TaskScheduler} for processing, and how to forward data to a task + * scheduler's output. This class is defined inside the input wire package to prevent anything that isn't an input wire + * from accessing its methods. + */ +public abstract class TaskSchedulerInput { + + /** + * Add a task to the scheduler. May block if back pressure is enabled. + * + * @param handler handles the provided data + * @param data the data to be processed by the task scheduler + */ + protected abstract void put(@NonNull Consumer handler, @NonNull Object data); + + /** + * Add a task to the scheduler. If backpressure is enabled and there is not immediately capacity available, this + * method will not accept the data. + * + * @param handler handles the provided data + * @param data the data to be processed by the scheduler + * @return true if the data was accepted, false otherwise + */ + protected abstract boolean offer(@NonNull Consumer handler, @NonNull Object data); + + /** + * Inject data into the scheduler, doing so even if it causes the number of unprocessed tasks to exceed the capacity + * specified by configured back pressure. If backpressure is disabled, this operation is logically equivalent to + * {@link #put(Consumer, Object)}. + * + * @param handler handles the provided data + * @param data the data to be processed by the scheduler + */ + protected abstract void inject(@NonNull Consumer handler, @NonNull Object data); + + /** + * Pass data to this scheduler's primary output wire. + *

+ * This method is implemented here to allow classes in this package to call forward(), which otherwise would not be + * visible. + */ + protected abstract void forward(@NonNull final OUT data); +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/output/NoOpOutputWire.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/output/NoOpOutputWire.java new file mode 100644 index 00000000000..14a77481f07 --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/output/NoOpOutputWire.java @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.wires.output; + +import com.swirlds.wiring.model.TraceableWiringModel; +import com.swirlds.wiring.transformers.AdvancedTransformation; +import com.swirlds.wiring.wires.SolderType; +import com.swirlds.wiring.wires.input.InputWire; +import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Predicate; + +/** + * An output wire that doesn't actually do anything. When asked to solder to another wire, it does nothing. When asked + * to build a transformer (or variations there upon) it produces no-op implementations. + * + * @param the type of data passed to the forwarding method + */ +public class NoOpOutputWire extends StandardOutputWire { + + /** + * Constructor. + * + * @param model the wiring model containing this output wire + * @param name the name of the output wire + */ + public NoOpOutputWire(@NonNull final TraceableWiringModel model, @NonNull final String name) { + super(model, name); + } + + /** + * {@inheritDoc} + */ + @Override + protected void addForwardingDestination(@NonNull final Consumer destination) { + // intentional no-op + } + + /** + * {@inheritDoc} + */ + @Override + public void forward(@NonNull final OUT data) { + // intentional no-op + } + + /** + * {@inheritDoc} + */ + @Override + public void solderTo(@NonNull final InputWire inputWire, @NonNull final SolderType solderType) { + // intentional no-op + } + + /** + * {@inheritDoc} + */ + @Override + public void solderTo( + @NonNull final String handlerName, + @NonNull final String inputWireLabel, + final @NonNull Consumer handler) { + // intentional no-op + } + + /** + * {@inheritDoc} + */ + @NonNull + @Override + public OutputWire buildFilter( + @NonNull final String filterName, + @NonNull final String filterInputName, + @NonNull final Predicate predicate) { + return new NoOpOutputWire<>(getModel(), filterName); + } + + /** + * {@inheritDoc} + */ + @NonNull + @Override + public OutputWire buildSplitter( + @NonNull final String splitterName, @NonNull final String splitterInputName) { + return new NoOpOutputWire<>(getModel(), splitterName); + } + + /** + * {@inheritDoc} + */ + @NonNull + @Override + public OutputWire buildTransformer( + @NonNull final String transformerName, + @NonNull final String transformerInputName, + @NonNull final Function transformer) { + return new NoOpOutputWire<>(getModel(), transformerName); + } + + /** + * {@inheritDoc} + */ + @NonNull + @Override + public OutputWire buildAdvancedTransformer( + @NonNull final AdvancedTransformation transformer) { + return new NoOpOutputWire<>(getModel(), transformer.getTransformerName()); + } +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/output/OutputWire.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/output/OutputWire.java new file mode 100644 index 00000000000..55850d520b8 --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/output/OutputWire.java @@ -0,0 +1,289 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.wires.output; + +import static com.swirlds.wiring.schedulers.builders.TaskSchedulerType.NO_OP; + +import com.swirlds.wiring.model.TraceableWiringModel; +import com.swirlds.wiring.schedulers.TaskScheduler; +import com.swirlds.wiring.schedulers.builders.TaskSchedulerType; +import com.swirlds.wiring.transformers.AdvancedTransformation; +import com.swirlds.wiring.transformers.WireFilter; +import com.swirlds.wiring.transformers.WireListSplitter; +import com.swirlds.wiring.transformers.WireTransformer; +import com.swirlds.wiring.wires.SolderType; +import com.swirlds.wiring.wires.input.BindableInputWire; +import com.swirlds.wiring.wires.input.InputWire; +import com.swirlds.wiring.wires.output.internal.TransformingOutputWire; +import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.List; +import java.util.Objects; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Predicate; + +/** + * Describes the output of a task scheduler. Can be soldered to wire inputs or lambdas. + * + * @param the output type of the object + */ +public abstract class OutputWire { + + private final TraceableWiringModel model; + private final String name; + + /** + * Constructor. + * + * @param model the wiring model containing this output wire + * @param name the name of the output wire + */ + public OutputWire(@NonNull final TraceableWiringModel model, @NonNull final String name) { + this.model = Objects.requireNonNull(model); + this.name = Objects.requireNonNull(name); + } + + /** + * Get the name of this output wire. If this object is a task scheduler, this is the same as the name of the task + * scheduler. + * + * @return the name + */ + @NonNull + public String getName() { + return name; + } + + /** + * Get the wiring model that contains this output wire. + * + * @return the wiring model + */ + @NonNull + protected TraceableWiringModel getModel() { + return model; + } + + /** + * Specify an input wire where output data should be passed. This forwarding operation respects back pressure. + * Equivalent to calling {@link #solderTo(InputWire, SolderType)} with {@link SolderType#PUT}. + * + *

+ * Soldering is the act of connecting two wires together, usually by melting a metal alloy between them. See + * wikipedia's entry on soldering. + * + *

+ * Forwarding should be fully configured prior to data being inserted into the system. Adding forwarding + * destinations after data has been inserted into the system is not thread safe and has undefined behavior. + * + * @param inputWire the input wire to forward output data to + */ + public void solderTo(@NonNull final InputWire inputWire) { + solderTo(inputWire, SolderType.PUT); + } + + /** + * A convenience method that should be used iff the order in which the {@code inputWires} are soldered is important. + * Using this method reduces the chance of inadvertent reordering when code is modified or reorganized. All + * invocations of this method should carefully document why the provided ordering is important. + *

+ * Since this method is specifically for input wires that require a certain order, at least two input wires must be + * provided. + * + * @param inputWires – an ordered list of the input wire to forward output data to + * @throws IllegalArgumentException if the size of {@code inputWires} is less than 2 + * @see #solderTo(InputWire) + */ + public void orderedSolderTo(@NonNull final List> inputWires) { + if (inputWires.size() < 2) { + throw new IllegalArgumentException("List must contain at least 2 input wires."); + } + inputWires.forEach(this::solderTo); + } + + /** + * Specify an input wire where output data should be passed. This forwarding operation respects back pressure. + * + *

+ * Soldering is the act of connecting two wires together, usually by melting a metal alloy between them. See + * wikipedia's entry on soldering. + * + *

+ * Forwarding should be fully configured prior to data being inserted into the system. Adding forwarding + * destinations after data has been inserted into the system is not thread safe and has undefined behavior. + * + * @param inputWire the input wire to forward output data to + * @param solderType the semantics of the soldering operation + */ + public void solderTo(@NonNull final InputWire inputWire, @NonNull final SolderType solderType) { + if (inputWire.getTaskSchedulerType() == NO_OP) { + return; + } + + model.registerEdge(name, inputWire.getTaskSchedulerName(), inputWire.getName(), solderType); + + switch (solderType) { + case PUT -> addForwardingDestination(inputWire::put); + case INJECT -> addForwardingDestination(inputWire::inject); + case OFFER -> addForwardingDestination(inputWire::offer); + default -> throw new IllegalArgumentException("Unknown solder type: " + solderType); + } + } + + /** + * Specify a consumer where output data should be forwarded. This method creates a direct task scheduler under the + * hood and forwards output data to it. + * + *

+ * Soldering is the act of connecting two wires together, usually by melting a metal alloy between them. See + * wikipedia's entry on soldering. + * + *

+ * Forwarding should be fully configured prior to data being inserted into the system. Adding forwarding + * destinations after data has been inserted into the system is not thread safe and has undefined behavior. + * + * @param handlerName the name of the consumer + * @param inputWireLabel the label for the input wire going into the consumer + * @param handler the consumer to forward output data to + */ + public void solderTo( + @NonNull final String handlerName, + @NonNull final String inputWireLabel, + @NonNull final Consumer handler) { + + final TaskScheduler directScheduler = model.schedulerBuilder(handlerName) + .withType(TaskSchedulerType.DIRECT) + .build() + .cast(); + + final BindableInputWire directSchedulerInputWire = directScheduler.buildInputWire(inputWireLabel); + directSchedulerInputWire.bindConsumer(handler); + + this.solderTo(directSchedulerInputWire); + } + + /** + * Build a {@link WireFilter}. The input wire to the filter is automatically soldered to this output wire (i.e. all + * data that comes out of the wire will be inserted into the filter). The output wire of the filter is returned by + * this method. + * + * @param filterName the name of the filter + * @param filterInputName the label for the input wire going into the filter + * @param predicate the predicate that filters the output of this wire + * @return the output wire of the filter + */ + @NonNull + public OutputWire buildFilter( + @NonNull final String filterName, + @NonNull final String filterInputName, + @NonNull final Predicate predicate) { + + Objects.requireNonNull(filterName); + Objects.requireNonNull(filterInputName); + Objects.requireNonNull(predicate); + + final WireFilter filter = new WireFilter<>(model, filterName, filterInputName, predicate); + solderTo(filter.getInputWire()); + return filter.getOutputWire(); + } + + /** + * Build a {@link WireListSplitter}. Creating a splitter for wires without a list output type will cause runtime + * exceptions. The input wire to the splitter is automatically soldered to this output wire (i.e. all data that + * comes out of the wire will be inserted into the splitter). The output wire of the splitter is returned by this + * method. + * + * @param the type of the list elements + * @return output wire of the splitter + */ + @SuppressWarnings("unchecked") + @NonNull + public OutputWire buildSplitter( + @NonNull final String splitterName, @NonNull final String splitterInputName) { + + Objects.requireNonNull(splitterName); + Objects.requireNonNull(splitterInputName); + + final WireListSplitter splitter = new WireListSplitter<>(model, splitterName, splitterInputName); + solderTo((InputWire) splitter.getInputWire()); + return splitter.getOutputWire(); + } + + /** + * Build a {@link WireTransformer}. The input wire to the transformer is automatically soldered to this output wire + * (i.e. all data that comes out of the wire will be inserted into the transformer). The output wire of the + * transformer is returned by this method. + * + * @param transformerName the name of the transformer + * @param transformerInputName the label for the input wire going into the transformer + * @param transformer the function that transforms the output of this wire into the output of the + * transformer. Called once per data item. Null data returned by this method is not + * forwarded. + * @param the output type of the transformer + * @return the output wire of the transformer + */ + @NonNull + public OutputWire buildTransformer( + @NonNull final String transformerName, + @NonNull final String transformerInputName, + @NonNull final Function transformer) { + + Objects.requireNonNull(transformerName); + Objects.requireNonNull(transformerInputName); + Objects.requireNonNull(transformer); + + final WireTransformer wireTransformer = + new WireTransformer<>(model, transformerName, transformerInputName, transformer); + solderTo(wireTransformer.getInputWire()); + return wireTransformer.getOutputWire(); + } + + /** + * Build a transformation wire with cleanup functionality. + *

+ * The input wire to the transformer is automatically soldered to this output wire (i.e. all data that comes out of + * the wire will be inserted into the transformer). The output wire of the transformer is returned by this method. + * Similar to {@link #buildTransformer(String, String, Function)}, but instead of the transformer method being + * called once per data item, it is called once per output per data item. + * + * @param transformer an object that manages the transformation + * @param the output type of the transformer + * @return the output wire of the transformer + */ + @NonNull + public OutputWire buildAdvancedTransformer( + @NonNull final AdvancedTransformation transformer) { + + final TransformingOutputWire outputWire = new TransformingOutputWire<>( + model, + transformer.getTransformerName(), + transformer::transform, + transformer::inputCleanup, + transformer::outputCleanup); + + solderTo(transformer.getTransformerName(), transformer.getTransformerInputName(), outputWire::forward); + + return outputWire; + } + + /** + * Creates a new forwarding destination. + * + * @param destination the destination to forward data to + */ + protected abstract void addForwardingDestination(@NonNull final Consumer destination); +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/output/StandardOutputWire.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/output/StandardOutputWire.java new file mode 100644 index 00000000000..b93be9f713f --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/output/StandardOutputWire.java @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.wires.output; + +import static com.swirlds.logging.legacy.LogMarker.EXCEPTION; + +import com.swirlds.wiring.model.TraceableWiringModel; +import com.swirlds.wiring.wires.output.internal.ForwardingOutputWire; +import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.function.Consumer; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +/** + * An output wire that will take data and forward it to its outputs. Output type is the same as the input type. + * + * @param the type of data passed to the forwarding method + */ +public class StandardOutputWire extends ForwardingOutputWire { + + private static final Logger logger = LogManager.getLogger(StandardOutputWire.class); + + private final List> forwardingDestinations = new ArrayList<>(); + + /** + * Constructor. + * + * @param model the wiring model containing this output wire + * @param name the name of the output wire + */ + public StandardOutputWire(@NonNull final TraceableWiringModel model, @NonNull final String name) { + super(model, name); + } + + /** + * {@inheritDoc} + */ + @Override + protected void addForwardingDestination(@NonNull final Consumer destination) { + Objects.requireNonNull(destination); + forwardingDestinations.add(destination); + } + + /** + * {@inheritDoc} + */ + @Override + public void forward(@NonNull final OUT data) { + for (final Consumer destination : forwardingDestinations) { + try { + destination.accept(data); + } catch (final Exception e) { + logger.error( + EXCEPTION.getMarker(), + "Exception thrown on output wire {} while forwarding data {}", + getName(), + data, + e); + } + } + } +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/output/internal/ForwardingOutputWire.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/output/internal/ForwardingOutputWire.java new file mode 100644 index 00000000000..60731fd693a --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/output/internal/ForwardingOutputWire.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.wires.output.internal; + +import com.swirlds.wiring.model.TraceableWiringModel; +import com.swirlds.wiring.wires.output.OutputWire; +import edu.umd.cs.findbugs.annotations.NonNull; + +/** + * An output wire that will take data and forward it to its outputs. + * + * @param the type of data passed to the forwarding method + * @param the type of data forwarded to things soldered to this wire + */ +public abstract class ForwardingOutputWire extends OutputWire { + + /** + * Constructor. + * + * @param model the wiring model containing this output wire + * @param name the name of the output wire + */ + protected ForwardingOutputWire(@NonNull final TraceableWiringModel model, final @NonNull String name) { + super(model, name); + } + + /** + * Forward output data to any wires/consumers that are listening for it. + *

+ * Although it will technically work, it is a violation of convention to directly put data into this output wire + * except from within code being executed by the task scheduler that owns this output wire. Don't do it. + * + * @param data the output data to forward + */ + public abstract void forward(@NonNull final IN data); +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/output/internal/TransformingOutputWire.java b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/output/internal/TransformingOutputWire.java new file mode 100644 index 00000000000..4bd7ebc3ee7 --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/output/internal/TransformingOutputWire.java @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 com.swirlds.wiring.wires.output.internal; + +import static com.swirlds.logging.legacy.LogMarker.EXCEPTION; + +import com.swirlds.wiring.model.TraceableWiringModel; +import com.swirlds.wiring.wires.SolderType; +import com.swirlds.wiring.wires.input.InputWire; +import com.swirlds.wiring.wires.output.OutputWire; +import edu.umd.cs.findbugs.annotations.NonNull; +import edu.umd.cs.findbugs.annotations.Nullable; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.function.Consumer; +import java.util.function.Function; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +/** + * An output wire that transforms data that flows across it. For advanced use cases where + * {@link OutputWire#buildTransformer(String, String, Function)} semantics are insufficient. + * + * @param the type of data passed to the forwarding method + * @param the type of data forwarded to things soldered to this wire + */ +public class TransformingOutputWire extends ForwardingOutputWire { + + private static final Logger logger = LogManager.getLogger(TransformingOutputWire.class); + private final List> forwardingDestinations = new ArrayList<>(); + + private final Function transform; + private final Consumer inputCleanup; + private final Consumer outputCleanup; + + /** + * Constructor. + * + * @param model the wiring model containing this output wire + * @param name the name of the output wire + * @param transformer the function to transform the data from the input type to the output type. Is called once + * per output per data item. If this method returns null then the data is not forwarded. + * @param inputCleanup an optional method that is called on input data after the data is forwarded to all + * destinations. The original data is passed to this method. Ignored if null. + * @param outputCleanup an optional method that is called on output data if it is rejected by a destination. This is + * possible if offer soldering is used and the destination declines to take the data. + */ + public TransformingOutputWire( + @NonNull final TraceableWiringModel model, + @NonNull final String name, + @NonNull final Function transformer, + @Nullable final Consumer inputCleanup, + @Nullable final Consumer outputCleanup) { + super(model, name); + + this.transform = Objects.requireNonNull(transformer); + this.inputCleanup = inputCleanup == null ? (data) -> {} : inputCleanup; + this.outputCleanup = outputCleanup == null ? (data) -> {} : outputCleanup; + } + + /** + * {@inheritDoc} + */ + @Override + protected void addForwardingDestination(@NonNull final Consumer destination) { + Objects.requireNonNull(destination); + forwardingDestinations.add(destination); + } + + /** + * {@inheritDoc} + */ + @Override + public void forward(@NonNull final IN data) { + for (final Consumer destination : forwardingDestinations) { + try { + final OUT transformed = transform.apply(data); + if (transformed == null) { + // Do not forward null values. + return; + } + destination.accept(transformed); + } catch (final Exception e) { + logger.error( + EXCEPTION.getMarker(), + "Exception thrown on output wire {} while forwarding data {}", + getName(), + data, + e); + } + } + inputCleanup.accept(data); + } + + /** + * {@inheritDoc} + */ + @Override + public void solderTo(@NonNull final InputWire inputWire, @NonNull final SolderType solderType) { + getModel().registerEdge(getName(), inputWire.getTaskSchedulerName(), inputWire.getName(), solderType); + + switch (solderType) { + case PUT -> addForwardingDestination(inputWire::put); + case INJECT -> addForwardingDestination(inputWire::inject); + case OFFER -> addForwardingDestination(x -> { + if (!inputWire.offer(x)) { + outputCleanup.accept(x); + } + }); + default -> throw new IllegalArgumentException("Unknown solder type: " + solderType); + } + } +} diff --git a/platform-sdk/consensus-wiring/src/main/java/module-info.java b/platform-sdk/consensus-wiring/src/main/java/module-info.java new file mode 100644 index 00000000000..f2c85372e03 --- /dev/null +++ b/platform-sdk/consensus-wiring/src/main/java/module-info.java @@ -0,0 +1,11 @@ +module com.swirlds.wiring { + exports com.swirlds.wiring; + + requires transitive com.swirlds.base; + requires transitive com.swirlds.common; + requires transitive com.swirlds.config.api; + requires com.swirlds.logging; + requires com.swirlds.metrics.api; + requires org.apache.logging.log4j; + requires static com.github.spotbugs.annotations; +} From 33695387452e2065a59402045accfce61f221f53 Mon Sep 17 00:00:00 2001 From: mxtartaglia Date: Tue, 14 Jan 2025 17:58:27 -0300 Subject: [PATCH 2/6] chore: new module for wiring framework Signed-off-by: mxtartaglia --- .../src/main/java/module-info.java | 11 - .../build.gradle.kts | 12 +- .../src/main/java/module-info.java | 27 + .../hiero/wiring/framework}/WiringConfig.java | 2 +- .../framework}/component/ComponentWiring.java | 38 +- .../framework}/component/InputWireLabel.java | 2 +- .../framework}/component/SchedulerLabel.java | 2 +- .../component/internal/FilterToBind.java | 4 +- .../component/internal/InputWireToBind.java | 4 +- .../component/internal/TransformerToBind.java | 4 +- .../internal/WiringComponentProxy.java | 4 +- .../counters/BackpressureObjectCounter.java | 2 +- .../framework}/counters/EmptyBlocker.java | 2 +- .../counters/MultiObjectCounter.java | 2 +- .../counters/NoOpObjectCounter.java | 2 +- .../framework}/counters/ObjectCounter.java | 2 +- .../counters/StandardObjectCounter.java | 2 +- .../model/DeterministicWiringModel.java | 12 +- .../framework}/model/StandardWiringModel.java | 28 +- .../model/TraceableWiringModel.java | 40 +- .../wiring/framework}/model/WiringModel.java | 14 +- .../framework}/model/WiringModelBuilder.java | 2 +- .../model/diagram/HyperlinkBuilder.java | 2 +- .../model/diagram/ModelEdgeSubstitution.java | 2 +- .../framework}/model/diagram/ModelGroup.java | 2 +- .../model/diagram/ModelManualLink.java | 2 +- .../model/internal/analysis/CycleFinder.java | 2 +- .../analysis/DirectSchedulerChecks.java | 4 +- .../model/internal/analysis/GroupVertex.java | 8 +- .../internal/analysis/InputWireChecks.java | 2 +- .../analysis/InputWireDescriptor.java | 2 +- .../analysis/MermaidNameShortener.java | 2 +- .../analysis/MermaidStyleManager.java | 2 +- .../model/internal/analysis/ModelEdge.java | 2 +- .../model/internal/analysis/ModelVertex.java | 4 +- .../analysis/ModelVertexMetaType.java | 2 +- .../internal/analysis/StandardVertex.java | 14 +- .../internal/analysis/WiringFlowchart.java | 28 +- .../DeterministicHeartbeatScheduler.java | 8 +- .../DeterministicTaskScheduler.java | 10 +- .../DeterministicTaskSchedulerBuilder.java | 18 +- .../model/internal/monitor/HealthMonitor.java | 6 +- .../internal/monitor/HealthMonitorLogger.java | 4 +- .../monitor/HealthMonitorMetrics.java | 2 +- .../standard/AbstractHeartbeatScheduler.java | 10 +- .../internal/standard/HeartbeatScheduler.java | 4 +- .../internal/standard/HeartbeatTask.java | 8 +- .../model/internal/standard/JvmAnchor.java | 2 +- .../framework}/schedulers/TaskScheduler.java | 26 +- .../builders/TaskSchedulerBuilder.java | 6 +- .../builders/TaskSchedulerConfigOption.java | 2 +- .../builders/TaskSchedulerConfiguration.java | 10 +- .../builders/TaskSchedulerType.java | 2 +- .../AbstractTaskSchedulerBuilder.java | 28 +- .../StandardTaskSchedulerBuilder.java | 22 +- .../schedulers/internal/ConcurrentTask.java | 6 +- .../internal/ConcurrentTaskScheduler.java | 10 +- .../schedulers/internal/DefaultSquelcher.java | 2 +- .../internal/DirectTaskScheduler.java | 12 +- .../internal/NoOpTaskScheduler.java | 18 +- .../schedulers/internal/SequentialTask.java | 6 +- .../internal/SequentialTaskScheduler.java | 10 +- .../internal/SequentialThreadTask.java | 2 +- .../SequentialThreadTaskScheduler.java | 10 +- .../schedulers/internal/Squelcher.java | 2 +- .../internal/ThrowingSquelcher.java | 2 +- .../wiring/framework}/tasks/AbstractTask.java | 2 +- .../transformers/AdvancedTransformation.java | 4 +- .../framework}/transformers/RoutableData.java | 2 +- .../framework}/transformers/WireFilter.java | 14 +- .../transformers/WireListSplitter.java | 16 +- .../framework}/transformers/WireRouter.java | 16 +- .../transformers/WireTransformer.java | 14 +- .../wiring/framework}/wires/SolderType.java | 4 +- .../framework}/wires/input/Bindable.java | 2 +- .../wires/input/BindableInputWire.java | 8 +- .../framework}/wires/input/InputWire.java | 6 +- .../framework}/wires/input/NoOpInputWire.java | 6 +- .../wires/input/TaskSchedulerInput.java | 4 +- .../wires/output/NoOpOutputWire.java | 10 +- .../framework}/wires/output/OutputWire.java | 26 +- .../wires/output/StandardOutputWire.java | 6 +- .../output/internal/ForwardingOutputWire.java | 6 +- .../internal/TransformingOutputWire.java | 10 +- .../framework/benchmark/WiringBenchmark.java | 134 ++ .../benchmark/WiringBenchmarkEvent.java | 37 + .../benchmark/WiringBenchmarkEventPool.java | 41 + .../WiringBenchmarkEventVerifier.java | 41 + .../benchmark/WiringBenchmarkGossip.java | 63 + ...WiringBenchmarkTopologicalEventSorter.java | 51 + .../TaskSchedulerConfigurationTests.java | 155 ++ .../component/ComponentWiringRouterTests.java | 310 +++ .../component/ComponentWiringTests.java | 537 +++++ .../WiringComponentPerformanceTests.java | 132 ++ .../BackpressureObjectCounterTests.java | 289 +++ .../counters/MultiObjectCounterTests.java | 182 ++ .../counters/NoOpObjectCounterTests.java | 39 + .../counters/StandardObjectCounterTests.java | 105 + .../DeterministicHeartbeatSchedulerTests.java | 147 ++ .../model/DeterministicModelTests.java | 570 ++++++ .../wiring/framework/model/ModelTests.java | 1763 +++++++++++++++++ .../internal/monitor/HealthMonitorTests.java | 236 +++ .../schedulers/NoOpTaskSchedulerTests.java | 111 ++ .../transformers/WireRouterTests.java | 95 + 104 files changed, 5402 insertions(+), 338 deletions(-) delete mode 100644 platform-sdk/consensus-wiring/src/main/java/module-info.java rename platform-sdk/{consensus-wiring => wiring-framework}/build.gradle.kts (75%) create mode 100644 platform-sdk/wiring-framework/src/main/java/module-info.java rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/WiringConfig.java (98%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/component/ComponentWiring.java (96%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/component/InputWireLabel.java (96%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/component/SchedulerLabel.java (96%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/component/internal/FilterToBind.java (90%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/component/internal/InputWireToBind.java (95%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/component/internal/TransformerToBind.java (91%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/component/internal/WiringComponentProxy.java (94%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/counters/BackpressureObjectCounter.java (99%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/counters/EmptyBlocker.java (97%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/counters/MultiObjectCounter.java (98%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/counters/NoOpObjectCounter.java (97%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/counters/ObjectCounter.java (98%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/counters/StandardObjectCounter.java (98%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/model/DeterministicWiringModel.java (89%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/model/StandardWiringModel.java (87%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/model/TraceableWiringModel.java (89%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/model/WiringModel.java (93%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/model/WiringModelBuilder.java (99%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/model/diagram/HyperlinkBuilder.java (98%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/model/diagram/ModelEdgeSubstitution.java (96%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/model/diagram/ModelGroup.java (96%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/model/diagram/ModelManualLink.java (95%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/model/internal/analysis/CycleFinder.java (98%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/model/internal/analysis/DirectSchedulerChecks.java (98%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/model/internal/analysis/GroupVertex.java (93%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/model/internal/analysis/InputWireChecks.java (97%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/model/internal/analysis/InputWireDescriptor.java (94%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/model/internal/analysis/MermaidNameShortener.java (96%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/model/internal/analysis/MermaidStyleManager.java (98%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/model/internal/analysis/ModelEdge.java (98%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/model/internal/analysis/ModelVertex.java (95%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/model/internal/analysis/ModelVertexMetaType.java (95%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/model/internal/analysis/StandardVertex.java (91%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/model/internal/analysis/WiringFlowchart.java (93%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/model/internal/deterministic/DeterministicHeartbeatScheduler.java (92%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/model/internal/deterministic/DeterministicTaskScheduler.java (93%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/model/internal/deterministic/DeterministicTaskSchedulerBuilder.java (84%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/model/internal/monitor/HealthMonitor.java (96%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/model/internal/monitor/HealthMonitorLogger.java (96%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/model/internal/monitor/HealthMonitorMetrics.java (97%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/model/internal/standard/AbstractHeartbeatScheduler.java (92%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/model/internal/standard/HeartbeatScheduler.java (94%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/model/internal/standard/HeartbeatTask.java (90%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/model/internal/standard/JvmAnchor.java (96%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/schedulers/TaskScheduler.java (92%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/schedulers/builders/TaskSchedulerBuilder.java (97%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/schedulers/builders/TaskSchedulerConfigOption.java (96%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/schedulers/builders/TaskSchedulerConfiguration.java (95%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/schedulers/builders/TaskSchedulerType.java (98%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/schedulers/builders/internal/AbstractTaskSchedulerBuilder.java (92%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/schedulers/builders/internal/StandardTaskSchedulerBuilder.java (89%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/schedulers/internal/ConcurrentTask.java (93%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/schedulers/internal/ConcurrentTaskScheduler.java (93%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/schedulers/internal/DefaultSquelcher.java (96%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/schedulers/internal/DirectTaskScheduler.java (92%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/schedulers/internal/NoOpTaskScheduler.java (86%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/schedulers/internal/SequentialTask.java (96%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/schedulers/internal/SequentialTaskScheduler.java (95%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/schedulers/internal/SequentialThreadTask.java (95%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/schedulers/internal/SequentialThreadTaskScheduler.java (95%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/schedulers/internal/Squelcher.java (97%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/schedulers/internal/ThrowingSquelcher.java (96%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/tasks/AbstractTask.java (98%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/transformers/AdvancedTransformation.java (95%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/transformers/RoutableData.java (95%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/transformers/WireFilter.java (90%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/transformers/WireListSplitter.java (83%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/transformers/WireRouter.java (89%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/transformers/WireTransformer.java (90%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/wires/SolderType.java (92%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/wires/input/Bindable.java (97%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/wires/input/BindableInputWire.java (93%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/wires/input/InputWire.java (95%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/wires/input/NoOpInputWire.java (93%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/wires/input/TaskSchedulerInput.java (95%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/wires/output/NoOpOutputWire.java (92%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/wires/output/OutputWire.java (93%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/wires/output/StandardOutputWire.java (92%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/wires/output/internal/ForwardingOutputWire.java (90%) rename platform-sdk/{consensus-wiring/src/main/java/com/swirlds/wiring => wiring-framework/src/main/java/org/hiero/wiring/framework}/wires/output/internal/TransformingOutputWire.java (94%) create mode 100644 platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/benchmark/WiringBenchmark.java create mode 100644 platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/benchmark/WiringBenchmarkEvent.java create mode 100644 platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/benchmark/WiringBenchmarkEventPool.java create mode 100644 platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/benchmark/WiringBenchmarkEventVerifier.java create mode 100644 platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/benchmark/WiringBenchmarkGossip.java create mode 100644 platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/benchmark/WiringBenchmarkTopologicalEventSorter.java create mode 100644 platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/builders/TaskSchedulerConfigurationTests.java create mode 100644 platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/component/ComponentWiringRouterTests.java create mode 100644 platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/component/ComponentWiringTests.java create mode 100644 platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/component/WiringComponentPerformanceTests.java create mode 100644 platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/counters/BackpressureObjectCounterTests.java create mode 100644 platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/counters/MultiObjectCounterTests.java create mode 100644 platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/counters/NoOpObjectCounterTests.java create mode 100644 platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/counters/StandardObjectCounterTests.java create mode 100644 platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/model/DeterministicHeartbeatSchedulerTests.java create mode 100644 platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/model/DeterministicModelTests.java create mode 100644 platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/model/ModelTests.java create mode 100644 platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/model/internal/monitor/HealthMonitorTests.java create mode 100644 platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/schedulers/NoOpTaskSchedulerTests.java create mode 100644 platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/transformers/WireRouterTests.java diff --git a/platform-sdk/consensus-wiring/src/main/java/module-info.java b/platform-sdk/consensus-wiring/src/main/java/module-info.java deleted file mode 100644 index f2c85372e03..00000000000 --- a/platform-sdk/consensus-wiring/src/main/java/module-info.java +++ /dev/null @@ -1,11 +0,0 @@ -module com.swirlds.wiring { - exports com.swirlds.wiring; - - requires transitive com.swirlds.base; - requires transitive com.swirlds.common; - requires transitive com.swirlds.config.api; - requires com.swirlds.logging; - requires com.swirlds.metrics.api; - requires org.apache.logging.log4j; - requires static com.github.spotbugs.annotations; -} diff --git a/platform-sdk/consensus-wiring/build.gradle.kts b/platform-sdk/wiring-framework/build.gradle.kts similarity index 75% rename from platform-sdk/consensus-wiring/build.gradle.kts rename to platform-sdk/wiring-framework/build.gradle.kts index 0031158a1b5..f620fe6f5d0 100644 --- a/platform-sdk/consensus-wiring/build.gradle.kts +++ b/platform-sdk/wiring-framework/build.gradle.kts @@ -19,7 +19,7 @@ plugins { id("org.hiero.gradle.feature.publish-artifactregistry") } -description = "Consensus Wiring" +description = "Wiring Framework" // Remove the following line to enable all 'javac' lint checks that we have turned on by default // and then fix the reported issues. @@ -28,3 +28,13 @@ tasks.withType().configureEach { "-Xlint:-exports,-lossy-conversions,-overloads,-dep-ann,-text-blocks,-varargs" ) } + +testModuleInfo { + requires("com.swirlds.common.test.fixtures") + requires("com.swirlds.base.test.fixtures") + requires("org.assertj.core") + requires("org.junit.jupiter.api") + requires("org.junit.jupiter.params") + requires("org.mockito") + requiresStatic("com.github.spotbugs.annotations") +} diff --git a/platform-sdk/wiring-framework/src/main/java/module-info.java b/platform-sdk/wiring-framework/src/main/java/module-info.java new file mode 100644 index 00000000000..6904b933eca --- /dev/null +++ b/platform-sdk/wiring-framework/src/main/java/module-info.java @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2025 Hedera Hashgraph, LLC + * + * 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. + */ + +module org.hiero.wiring.framework { + exports org.hiero.wiring.framework; + + requires transitive com.swirlds.base; + requires transitive com.swirlds.config.api; + requires com.swirlds.common; + requires com.swirlds.logging; + requires com.swirlds.metrics.api; + requires org.apache.logging.log4j; + requires static com.github.spotbugs.annotations; +} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/WiringConfig.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/WiringConfig.java similarity index 98% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/WiringConfig.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/WiringConfig.java index 4742c6ac814..a4e79740ae8 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/WiringConfig.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/WiringConfig.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.wiring; +package org.hiero.wiring.framework; import com.swirlds.config.api.ConfigData; import com.swirlds.config.api.ConfigProperty; diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/component/ComponentWiring.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/component/ComponentWiring.java similarity index 96% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/component/ComponentWiring.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/component/ComponentWiring.java index 6cabbb3df1b..03db793801b 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/component/ComponentWiring.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/component/ComponentWiring.java @@ -14,25 +14,10 @@ * limitations under the License. */ -package com.swirlds.wiring.component; - -import static com.swirlds.wiring.model.diagram.HyperlinkBuilder.platformCoreHyperlink; - -import com.swirlds.wiring.component.internal.FilterToBind; -import com.swirlds.wiring.component.internal.InputWireToBind; -import com.swirlds.wiring.component.internal.TransformerToBind; -import com.swirlds.wiring.component.internal.WiringComponentProxy; -import com.swirlds.wiring.model.WiringModel; -import com.swirlds.wiring.schedulers.TaskScheduler; -import com.swirlds.wiring.schedulers.builders.TaskSchedulerConfiguration; -import com.swirlds.wiring.schedulers.builders.TaskSchedulerType; -import com.swirlds.wiring.transformers.RoutableData; -import com.swirlds.wiring.transformers.WireFilter; -import com.swirlds.wiring.transformers.WireRouter; -import com.swirlds.wiring.transformers.WireTransformer; -import com.swirlds.wiring.wires.input.BindableInputWire; -import com.swirlds.wiring.wires.input.InputWire; -import com.swirlds.wiring.wires.output.OutputWire; +package org.hiero.wiring.framework.component; + +import static org.hiero.wiring.framework.model.diagram.HyperlinkBuilder.platformCoreHyperlink; + import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; import java.lang.reflect.Method; @@ -48,6 +33,21 @@ import java.util.function.Function; import java.util.function.Supplier; import java.util.function.ToLongFunction; +import org.hiero.wiring.framework.component.internal.FilterToBind; +import org.hiero.wiring.framework.component.internal.InputWireToBind; +import org.hiero.wiring.framework.component.internal.TransformerToBind; +import org.hiero.wiring.framework.component.internal.WiringComponentProxy; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerConfiguration; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.transformers.RoutableData; +import org.hiero.wiring.framework.transformers.WireFilter; +import org.hiero.wiring.framework.transformers.WireRouter; +import org.hiero.wiring.framework.transformers.WireTransformer; +import org.hiero.wiring.framework.wires.input.BindableInputWire; +import org.hiero.wiring.framework.wires.input.InputWire; +import org.hiero.wiring.framework.wires.output.OutputWire; /** * Builds and manages input/output wires for a component. diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/component/InputWireLabel.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/component/InputWireLabel.java similarity index 96% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/component/InputWireLabel.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/component/InputWireLabel.java index 01dcf7b3d3d..c07f3aac972 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/component/InputWireLabel.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/component/InputWireLabel.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.wiring.component; +package org.hiero.wiring.framework.component; import edu.umd.cs.findbugs.annotations.NonNull; import java.lang.annotation.ElementType; diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/component/SchedulerLabel.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/component/SchedulerLabel.java similarity index 96% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/component/SchedulerLabel.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/component/SchedulerLabel.java index f3c3227485a..5e16a7d5248 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/component/SchedulerLabel.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/component/SchedulerLabel.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.wiring.component; +package org.hiero.wiring.framework.component; import edu.umd.cs.findbugs.annotations.NonNull; import java.lang.annotation.ElementType; diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/component/internal/FilterToBind.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/component/internal/FilterToBind.java similarity index 90% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/component/internal/FilterToBind.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/component/internal/FilterToBind.java index 526c713ff12..65073018478 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/component/internal/FilterToBind.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/component/internal/FilterToBind.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package com.swirlds.wiring.component.internal; +package org.hiero.wiring.framework.component.internal; -import com.swirlds.wiring.transformers.WireFilter; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.function.BiFunction; +import org.hiero.wiring.framework.transformers.WireFilter; /** * A filter and the predicate to bind. diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/component/internal/InputWireToBind.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/component/internal/InputWireToBind.java similarity index 95% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/component/internal/InputWireToBind.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/component/internal/InputWireToBind.java index 993c978f716..84060c3c025 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/component/internal/InputWireToBind.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/component/internal/InputWireToBind.java @@ -14,15 +14,15 @@ * limitations under the License. */ -package com.swirlds.wiring.component.internal; +package org.hiero.wiring.framework.component.internal; -import com.swirlds.wiring.wires.input.BindableInputWire; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; import java.util.function.BiConsumer; import java.util.function.BiFunction; import java.util.function.Consumer; import java.util.function.Function; +import org.hiero.wiring.framework.wires.input.BindableInputWire; /** * Contains information necessary to bind an input wire when we eventually get the implementation of the component. diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/component/internal/TransformerToBind.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/component/internal/TransformerToBind.java similarity index 91% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/component/internal/TransformerToBind.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/component/internal/TransformerToBind.java index 7c0b1599765..562f1a50c6c 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/component/internal/TransformerToBind.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/component/internal/TransformerToBind.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package com.swirlds.wiring.component.internal; +package org.hiero.wiring.framework.component.internal; -import com.swirlds.wiring.transformers.WireTransformer; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.function.BiFunction; +import org.hiero.wiring.framework.transformers.WireTransformer; /** * A transformer and the transformation to bind to a component. diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/component/internal/WiringComponentProxy.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/component/internal/WiringComponentProxy.java similarity index 94% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/component/internal/WiringComponentProxy.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/component/internal/WiringComponentProxy.java index b50a4c8151f..54112ce76e3 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/component/internal/WiringComponentProxy.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/component/internal/WiringComponentProxy.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package com.swirlds.wiring.component.internal; +package org.hiero.wiring.framework.component.internal; -import com.swirlds.wiring.component.ComponentWiring; import edu.umd.cs.findbugs.annotations.NonNull; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.util.Objects; +import org.hiero.wiring.framework.component.ComponentWiring; /** * This dynamic proxy is used by the {@link ComponentWiring} to capture the most diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/counters/BackpressureObjectCounter.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/counters/BackpressureObjectCounter.java similarity index 99% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/counters/BackpressureObjectCounter.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/counters/BackpressureObjectCounter.java index 5c32836570a..e6549818ded 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/counters/BackpressureObjectCounter.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/counters/BackpressureObjectCounter.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.wiring.counters; +package org.hiero.wiring.framework.counters; import static java.util.concurrent.TimeUnit.NANOSECONDS; diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/counters/EmptyBlocker.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/counters/EmptyBlocker.java similarity index 97% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/counters/EmptyBlocker.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/counters/EmptyBlocker.java index 32d51e3e854..2818b30da4d 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/counters/EmptyBlocker.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/counters/EmptyBlocker.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.wiring.counters; +package org.hiero.wiring.framework.counters; import static java.util.concurrent.TimeUnit.NANOSECONDS; diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/counters/MultiObjectCounter.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/counters/MultiObjectCounter.java similarity index 98% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/counters/MultiObjectCounter.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/counters/MultiObjectCounter.java index 0b7227984ef..dc8026420c7 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/counters/MultiObjectCounter.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/counters/MultiObjectCounter.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.wiring.counters; +package org.hiero.wiring.framework.counters; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.Objects; diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/counters/NoOpObjectCounter.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/counters/NoOpObjectCounter.java similarity index 97% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/counters/NoOpObjectCounter.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/counters/NoOpObjectCounter.java index dec4a59ec4f..0ed9080f443 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/counters/NoOpObjectCounter.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/counters/NoOpObjectCounter.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.wiring.counters; +package org.hiero.wiring.framework.counters; /** * A counter that doesn't actually count. Saves us from having to do a (counter == null) check in the standard case. diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/counters/ObjectCounter.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/counters/ObjectCounter.java similarity index 98% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/counters/ObjectCounter.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/counters/ObjectCounter.java index d954c3b29b6..f5fd12af9d7 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/counters/ObjectCounter.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/counters/ObjectCounter.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.wiring.counters; +package org.hiero.wiring.framework.counters; /** * A class that counts the number of objects in various parts of the pipeline. diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/counters/StandardObjectCounter.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/counters/StandardObjectCounter.java similarity index 98% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/counters/StandardObjectCounter.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/counters/StandardObjectCounter.java index 456f72058e3..f040dfe74d9 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/counters/StandardObjectCounter.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/counters/StandardObjectCounter.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.wiring.counters; +package org.hiero.wiring.framework.counters; import edu.umd.cs.findbugs.annotations.NonNull; import java.time.Duration; diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/DeterministicWiringModel.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/DeterministicWiringModel.java similarity index 89% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/DeterministicWiringModel.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/DeterministicWiringModel.java index dddcc575b18..b1f0ccdbb81 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/DeterministicWiringModel.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/DeterministicWiringModel.java @@ -14,20 +14,20 @@ * limitations under the License. */ -package com.swirlds.wiring.model; +package org.hiero.wiring.framework.model; import com.swirlds.common.context.PlatformContext; -import com.swirlds.wiring.model.internal.deterministic.DeterministicHeartbeatScheduler; -import com.swirlds.wiring.model.internal.deterministic.DeterministicTaskSchedulerBuilder; -import com.swirlds.wiring.schedulers.builders.TaskSchedulerBuilder; -import com.swirlds.wiring.wires.output.NoOpOutputWire; -import com.swirlds.wiring.wires.output.OutputWire; import edu.umd.cs.findbugs.annotations.NonNull; import java.time.Duration; import java.time.Instant; import java.util.ArrayList; import java.util.List; import java.util.Objects; +import org.hiero.wiring.framework.model.internal.deterministic.DeterministicHeartbeatScheduler; +import org.hiero.wiring.framework.model.internal.deterministic.DeterministicTaskSchedulerBuilder; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerBuilder; +import org.hiero.wiring.framework.wires.output.NoOpOutputWire; +import org.hiero.wiring.framework.wires.output.OutputWire; /** * A deterministic implementation of a wiring model. Suitable for testing, not intended for production use cases. diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/StandardWiringModel.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/StandardWiringModel.java similarity index 87% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/StandardWiringModel.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/StandardWiringModel.java index 889abc672e7..b3c3ac3af5b 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/StandardWiringModel.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/StandardWiringModel.java @@ -14,23 +14,13 @@ * limitations under the License. */ -package com.swirlds.wiring.model; +package org.hiero.wiring.framework.model; -import static com.swirlds.wiring.schedulers.builders.TaskSchedulerType.NO_OP; -import static com.swirlds.wiring.schedulers.builders.TaskSchedulerType.SEQUENTIAL; -import static com.swirlds.wiring.schedulers.builders.TaskSchedulerType.SEQUENTIAL_THREAD; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.NO_OP; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.SEQUENTIAL; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.SEQUENTIAL_THREAD; import com.swirlds.common.context.PlatformContext; -import com.swirlds.wiring.model.diagram.HyperlinkBuilder; -import com.swirlds.wiring.model.internal.monitor.HealthMonitor; -import com.swirlds.wiring.model.internal.standard.HeartbeatScheduler; -import com.swirlds.wiring.model.internal.standard.JvmAnchor; -import com.swirlds.wiring.schedulers.TaskScheduler; -import com.swirlds.wiring.schedulers.builders.TaskSchedulerBuilder; -import com.swirlds.wiring.schedulers.builders.internal.StandardTaskSchedulerBuilder; -import com.swirlds.wiring.schedulers.internal.SequentialThreadTaskScheduler; -import com.swirlds.wiring.wires.input.BindableInputWire; -import com.swirlds.wiring.wires.output.OutputWire; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; import java.time.Duration; @@ -39,6 +29,16 @@ import java.util.List; import java.util.Objects; import java.util.concurrent.ForkJoinPool; +import org.hiero.wiring.framework.model.diagram.HyperlinkBuilder; +import org.hiero.wiring.framework.model.internal.monitor.HealthMonitor; +import org.hiero.wiring.framework.model.internal.standard.HeartbeatScheduler; +import org.hiero.wiring.framework.model.internal.standard.JvmAnchor; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerBuilder; +import org.hiero.wiring.framework.schedulers.builders.internal.StandardTaskSchedulerBuilder; +import org.hiero.wiring.framework.schedulers.internal.SequentialThreadTaskScheduler; +import org.hiero.wiring.framework.wires.input.BindableInputWire; +import org.hiero.wiring.framework.wires.output.OutputWire; /** * A standard implementation of a wiring model suitable for production use. diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/TraceableWiringModel.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/TraceableWiringModel.java similarity index 89% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/TraceableWiringModel.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/TraceableWiringModel.java index 9cabfc3bc5c..9f7f5876717 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/TraceableWiringModel.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/TraceableWiringModel.java @@ -14,26 +14,12 @@ * limitations under the License. */ -package com.swirlds.wiring.model; - -import static com.swirlds.wiring.model.internal.analysis.ModelVertexMetaType.SCHEDULER; -import static com.swirlds.wiring.schedulers.builders.TaskSchedulerType.DIRECT; -import static com.swirlds.wiring.schedulers.builders.TaskSchedulerType.DIRECT_THREADSAFE; - -import com.swirlds.wiring.model.diagram.ModelEdgeSubstitution; -import com.swirlds.wiring.model.diagram.ModelGroup; -import com.swirlds.wiring.model.diagram.ModelManualLink; -import com.swirlds.wiring.model.internal.analysis.CycleFinder; -import com.swirlds.wiring.model.internal.analysis.DirectSchedulerChecks; -import com.swirlds.wiring.model.internal.analysis.InputWireChecks; -import com.swirlds.wiring.model.internal.analysis.InputWireDescriptor; -import com.swirlds.wiring.model.internal.analysis.ModelEdge; -import com.swirlds.wiring.model.internal.analysis.ModelVertex; -import com.swirlds.wiring.model.internal.analysis.StandardVertex; -import com.swirlds.wiring.model.internal.analysis.WiringFlowchart; -import com.swirlds.wiring.schedulers.TaskScheduler; -import com.swirlds.wiring.schedulers.builders.TaskSchedulerType; -import com.swirlds.wiring.wires.SolderType; +package org.hiero.wiring.framework.model; + +import static org.hiero.wiring.framework.model.internal.analysis.ModelVertexMetaType.SCHEDULER; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.DIRECT; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.DIRECT_THREADSAFE; + import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; import java.util.ArrayList; @@ -43,6 +29,20 @@ import java.util.Map; import java.util.Objects; import java.util.Set; +import org.hiero.wiring.framework.model.diagram.ModelEdgeSubstitution; +import org.hiero.wiring.framework.model.diagram.ModelGroup; +import org.hiero.wiring.framework.model.diagram.ModelManualLink; +import org.hiero.wiring.framework.model.internal.analysis.CycleFinder; +import org.hiero.wiring.framework.model.internal.analysis.DirectSchedulerChecks; +import org.hiero.wiring.framework.model.internal.analysis.InputWireChecks; +import org.hiero.wiring.framework.model.internal.analysis.InputWireDescriptor; +import org.hiero.wiring.framework.model.internal.analysis.ModelEdge; +import org.hiero.wiring.framework.model.internal.analysis.ModelVertex; +import org.hiero.wiring.framework.model.internal.analysis.StandardVertex; +import org.hiero.wiring.framework.model.internal.analysis.WiringFlowchart; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.wires.SolderType; /** * Common functionality for wiring model implementations. Has methods for registering information about the topology of diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/WiringModel.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/WiringModel.java similarity index 93% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/WiringModel.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/WiringModel.java index f6448007789..cee4a1bf90a 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/WiringModel.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/WiringModel.java @@ -14,20 +14,20 @@ * limitations under the License. */ -package com.swirlds.wiring.model; +package org.hiero.wiring.framework.model; import com.swirlds.base.state.Startable; import com.swirlds.base.state.Stoppable; -import com.swirlds.wiring.model.diagram.ModelEdgeSubstitution; -import com.swirlds.wiring.model.diagram.ModelGroup; -import com.swirlds.wiring.model.diagram.ModelManualLink; -import com.swirlds.wiring.schedulers.builders.TaskSchedulerBuilder; -import com.swirlds.wiring.schedulers.builders.TaskSchedulerType; -import com.swirlds.wiring.wires.output.OutputWire; import edu.umd.cs.findbugs.annotations.NonNull; import java.time.Duration; import java.time.Instant; import java.util.List; +import org.hiero.wiring.framework.model.diagram.ModelEdgeSubstitution; +import org.hiero.wiring.framework.model.diagram.ModelGroup; +import org.hiero.wiring.framework.model.diagram.ModelManualLink; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerBuilder; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.wires.output.OutputWire; /** * A wiring model is a collection of task schedulers and the wires connecting them. It can be used to analyze the wiring diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/WiringModelBuilder.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/WiringModelBuilder.java similarity index 99% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/WiringModelBuilder.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/WiringModelBuilder.java index 2319ca5a40a..c5e179bcf7e 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/WiringModelBuilder.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/WiringModelBuilder.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.wiring.model; +package org.hiero.wiring.framework.model; import com.swirlds.common.context.PlatformContext; import edu.umd.cs.findbugs.annotations.NonNull; diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/diagram/HyperlinkBuilder.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/diagram/HyperlinkBuilder.java similarity index 98% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/diagram/HyperlinkBuilder.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/diagram/HyperlinkBuilder.java index aad92eebfa7..fdeb54443e2 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/diagram/HyperlinkBuilder.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/diagram/HyperlinkBuilder.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.wiring.model.diagram; +package org.hiero.wiring.framework.model.diagram; import edu.umd.cs.findbugs.annotations.NonNull; diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/diagram/ModelEdgeSubstitution.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/diagram/ModelEdgeSubstitution.java similarity index 96% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/diagram/ModelEdgeSubstitution.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/diagram/ModelEdgeSubstitution.java index 8eb0a04697b..c0619d12bcf 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/diagram/ModelEdgeSubstitution.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/diagram/ModelEdgeSubstitution.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.wiring.model.diagram; +package org.hiero.wiring.framework.model.diagram; import edu.umd.cs.findbugs.annotations.NonNull; diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/diagram/ModelGroup.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/diagram/ModelGroup.java similarity index 96% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/diagram/ModelGroup.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/diagram/ModelGroup.java index 89ea7d34354..6f19994a81a 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/diagram/ModelGroup.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/diagram/ModelGroup.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.wiring.model.diagram; +package org.hiero.wiring.framework.model.diagram; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.Set; diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/diagram/ModelManualLink.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/diagram/ModelManualLink.java similarity index 95% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/diagram/ModelManualLink.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/diagram/ModelManualLink.java index ad3c6f3b689..e100f3efbb3 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/diagram/ModelManualLink.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/diagram/ModelManualLink.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.wiring.model.diagram; +package org.hiero.wiring.framework.model.diagram; import edu.umd.cs.findbugs.annotations.NonNull; diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/CycleFinder.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/analysis/CycleFinder.java similarity index 98% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/CycleFinder.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/analysis/CycleFinder.java index b0c8b5a1b9d..4593a89bf6f 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/CycleFinder.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/analysis/CycleFinder.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.wiring.model.internal.analysis; +package org.hiero.wiring.framework.model.internal.analysis; import static com.swirlds.logging.legacy.LogMarker.EXCEPTION; import static com.swirlds.logging.legacy.LogMarker.STARTUP; diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/DirectSchedulerChecks.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/analysis/DirectSchedulerChecks.java similarity index 98% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/DirectSchedulerChecks.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/analysis/DirectSchedulerChecks.java index b42690038d2..d1c78547968 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/DirectSchedulerChecks.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/analysis/DirectSchedulerChecks.java @@ -14,12 +14,11 @@ * limitations under the License. */ -package com.swirlds.wiring.model.internal.analysis; +package org.hiero.wiring.framework.model.internal.analysis; import static com.swirlds.logging.legacy.LogMarker.EXCEPTION; import static com.swirlds.logging.legacy.LogMarker.STARTUP; -import com.swirlds.wiring.schedulers.builders.TaskSchedulerType; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.Collection; import java.util.Deque; @@ -30,6 +29,7 @@ import java.util.Set; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; /** * A utility for checking direct scheduler use. diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/GroupVertex.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/analysis/GroupVertex.java similarity index 93% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/GroupVertex.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/analysis/GroupVertex.java index 73602735e3d..e835a929535 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/GroupVertex.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/analysis/GroupVertex.java @@ -14,18 +14,18 @@ * limitations under the License. */ -package com.swirlds.wiring.model.internal.analysis; +package org.hiero.wiring.framework.model.internal.analysis; -import static com.swirlds.wiring.model.internal.analysis.WiringFlowchart.GROUP_COLOR; -import static com.swirlds.wiring.model.internal.analysis.WiringFlowchart.TEXT_COLOR; +import static org.hiero.wiring.framework.model.internal.analysis.WiringFlowchart.GROUP_COLOR; +import static org.hiero.wiring.framework.model.internal.analysis.WiringFlowchart.TEXT_COLOR; -import com.swirlds.wiring.schedulers.builders.TaskSchedulerType; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; import java.util.HashSet; import java.util.List; import java.util.Objects; import java.util.Set; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; /** * A vertex that represents a nexted group of vertices. diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/InputWireChecks.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/analysis/InputWireChecks.java similarity index 97% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/InputWireChecks.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/analysis/InputWireChecks.java index 4984bf804fa..533d4e767d8 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/InputWireChecks.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/analysis/InputWireChecks.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.wiring.model.internal.analysis; +package org.hiero.wiring.framework.model.internal.analysis; import static com.swirlds.logging.legacy.LogMarker.EXCEPTION; import static com.swirlds.logging.legacy.LogMarker.STARTUP; diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/InputWireDescriptor.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/analysis/InputWireDescriptor.java similarity index 94% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/InputWireDescriptor.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/analysis/InputWireDescriptor.java index 0654c4cf7d9..aadbf409ab8 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/InputWireDescriptor.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/analysis/InputWireDescriptor.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.wiring.model.internal.analysis; +package org.hiero.wiring.framework.model.internal.analysis; import edu.umd.cs.findbugs.annotations.NonNull; diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/MermaidNameShortener.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/analysis/MermaidNameShortener.java similarity index 96% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/MermaidNameShortener.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/analysis/MermaidNameShortener.java index ba81266fa67..cb649a1ec33 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/MermaidNameShortener.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/analysis/MermaidNameShortener.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.wiring.model.internal.analysis; +package org.hiero.wiring.framework.model.internal.analysis; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.HashMap; diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/MermaidStyleManager.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/analysis/MermaidStyleManager.java similarity index 98% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/MermaidStyleManager.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/analysis/MermaidStyleManager.java index 1743faf1751..fc89167efdd 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/MermaidStyleManager.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/analysis/MermaidStyleManager.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.wiring.model.internal.analysis; +package org.hiero.wiring.framework.model.internal.analysis; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.ArrayList; diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/ModelEdge.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/analysis/ModelEdge.java similarity index 98% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/ModelEdge.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/analysis/ModelEdge.java index a9d95e7e48c..f3ac2913796 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/ModelEdge.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/analysis/ModelEdge.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.wiring.model.internal.analysis; +package org.hiero.wiring.framework.model.internal.analysis; import static com.swirlds.common.utility.NonCryptographicHashing.hash32; diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/ModelVertex.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/analysis/ModelVertex.java similarity index 95% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/ModelVertex.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/analysis/ModelVertex.java index 6c1d7d52640..4ae5c3e1f1a 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/ModelVertex.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/analysis/ModelVertex.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.swirlds.wiring.model.internal.analysis; +package org.hiero.wiring.framework.model.internal.analysis; -import com.swirlds.wiring.schedulers.builders.TaskSchedulerType; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; import java.util.Set; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; /** * A vertex in a wiring model. diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/ModelVertexMetaType.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/analysis/ModelVertexMetaType.java similarity index 95% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/ModelVertexMetaType.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/analysis/ModelVertexMetaType.java index 74ec1c76014..482dca0746c 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/ModelVertexMetaType.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/analysis/ModelVertexMetaType.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.wiring.model.internal.analysis; +package org.hiero.wiring.framework.model.internal.analysis; /** * The type of a vertex in a wiring flowchart. Although the original graph will be constructed of SCHEDULER vertices diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/StandardVertex.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/analysis/StandardVertex.java similarity index 91% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/StandardVertex.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/analysis/StandardVertex.java index 52daa55b1de..1aa84fdf35a 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/StandardVertex.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/analysis/StandardVertex.java @@ -14,20 +14,20 @@ * limitations under the License. */ -package com.swirlds.wiring.model.internal.analysis; +package org.hiero.wiring.framework.model.internal.analysis; -import static com.swirlds.wiring.model.internal.analysis.WiringFlowchart.DIRECT_SCHEDULER_COLOR; -import static com.swirlds.wiring.model.internal.analysis.WiringFlowchart.GROUP_COLOR; -import static com.swirlds.wiring.model.internal.analysis.WiringFlowchart.SCHEDULER_COLOR; -import static com.swirlds.wiring.model.internal.analysis.WiringFlowchart.SUBSTITUTION_COLOR; -import static com.swirlds.wiring.model.internal.analysis.WiringFlowchart.TEXT_COLOR; +import static org.hiero.wiring.framework.model.internal.analysis.WiringFlowchart.DIRECT_SCHEDULER_COLOR; +import static org.hiero.wiring.framework.model.internal.analysis.WiringFlowchart.GROUP_COLOR; +import static org.hiero.wiring.framework.model.internal.analysis.WiringFlowchart.SCHEDULER_COLOR; +import static org.hiero.wiring.framework.model.internal.analysis.WiringFlowchart.SUBSTITUTION_COLOR; +import static org.hiero.wiring.framework.model.internal.analysis.WiringFlowchart.TEXT_COLOR; -import com.swirlds.wiring.schedulers.builders.TaskSchedulerType; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; import java.util.HashSet; import java.util.Objects; import java.util.Set; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; /** * A standard vertex in a wiring model. Does not contain sub-vertices. diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/WiringFlowchart.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/analysis/WiringFlowchart.java similarity index 93% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/WiringFlowchart.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/analysis/WiringFlowchart.java index 788dba7c9c7..9782ccb8c11 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/analysis/WiringFlowchart.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/analysis/WiringFlowchart.java @@ -14,20 +14,16 @@ * limitations under the License. */ -package com.swirlds.wiring.model.internal.analysis; - -import static com.swirlds.wiring.model.internal.analysis.ModelVertexMetaType.SCHEDULER; -import static com.swirlds.wiring.model.internal.analysis.ModelVertexMetaType.SUBSTITUTION; -import static com.swirlds.wiring.schedulers.builders.TaskSchedulerType.CONCURRENT; -import static com.swirlds.wiring.schedulers.builders.TaskSchedulerType.DIRECT; -import static com.swirlds.wiring.schedulers.builders.TaskSchedulerType.DIRECT_THREADSAFE; -import static com.swirlds.wiring.schedulers.builders.TaskSchedulerType.SEQUENTIAL; -import static com.swirlds.wiring.schedulers.builders.TaskSchedulerType.SEQUENTIAL_THREAD; - -import com.swirlds.wiring.model.diagram.ModelEdgeSubstitution; -import com.swirlds.wiring.model.diagram.ModelGroup; -import com.swirlds.wiring.model.diagram.ModelManualLink; -import com.swirlds.wiring.schedulers.builders.TaskSchedulerType; +package org.hiero.wiring.framework.model.internal.analysis; + +import static org.hiero.wiring.framework.model.internal.analysis.ModelVertexMetaType.SCHEDULER; +import static org.hiero.wiring.framework.model.internal.analysis.ModelVertexMetaType.SUBSTITUTION; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.CONCURRENT; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.DIRECT; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.DIRECT_THREADSAFE; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.SEQUENTIAL; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.SEQUENTIAL_THREAD; + import edu.umd.cs.findbugs.annotations.NonNull; import java.util.ArrayList; import java.util.Collections; @@ -38,6 +34,10 @@ import java.util.Map; import java.util.Objects; import java.util.Set; +import org.hiero.wiring.framework.model.diagram.ModelEdgeSubstitution; +import org.hiero.wiring.framework.model.diagram.ModelGroup; +import org.hiero.wiring.framework.model.diagram.ModelManualLink; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; /** * A readable wiring flowchart. diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/deterministic/DeterministicHeartbeatScheduler.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/deterministic/DeterministicHeartbeatScheduler.java similarity index 92% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/deterministic/DeterministicHeartbeatScheduler.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/deterministic/DeterministicHeartbeatScheduler.java index 3ee3efdb3e8..9adc40c25d8 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/deterministic/DeterministicHeartbeatScheduler.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/deterministic/DeterministicHeartbeatScheduler.java @@ -14,14 +14,11 @@ * limitations under the License. */ -package com.swirlds.wiring.model.internal.deterministic; +package org.hiero.wiring.framework.model.internal.deterministic; import static com.swirlds.common.utility.CompareTo.isGreaterThanOrEqualTo; import com.swirlds.base.time.Time; -import com.swirlds.wiring.model.TraceableWiringModel; -import com.swirlds.wiring.model.internal.standard.AbstractHeartbeatScheduler; -import com.swirlds.wiring.model.internal.standard.HeartbeatTask; import edu.umd.cs.findbugs.annotations.NonNull; import java.time.Duration; import java.time.Instant; @@ -30,6 +27,9 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; +import org.hiero.wiring.framework.model.TraceableWiringModel; +import org.hiero.wiring.framework.model.internal.standard.AbstractHeartbeatScheduler; +import org.hiero.wiring.framework.model.internal.standard.HeartbeatTask; /** * A deterministic implementation of a heartbeat scheduler. diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/deterministic/DeterministicTaskScheduler.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/deterministic/DeterministicTaskScheduler.java similarity index 93% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/deterministic/DeterministicTaskScheduler.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/deterministic/DeterministicTaskScheduler.java index 0589705d5c0..567e55cc89d 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/deterministic/DeterministicTaskScheduler.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/deterministic/DeterministicTaskScheduler.java @@ -14,15 +14,15 @@ * limitations under the License. */ -package com.swirlds.wiring.model.internal.deterministic; +package org.hiero.wiring.framework.model.internal.deterministic; -import com.swirlds.wiring.counters.ObjectCounter; -import com.swirlds.wiring.model.TraceableWiringModel; -import com.swirlds.wiring.schedulers.TaskScheduler; -import com.swirlds.wiring.schedulers.builders.TaskSchedulerType; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.Objects; import java.util.function.Consumer; +import org.hiero.wiring.framework.counters.ObjectCounter; +import org.hiero.wiring.framework.model.TraceableWiringModel; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; /** * A deterministic implementation of a task scheduler. diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/deterministic/DeterministicTaskSchedulerBuilder.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/deterministic/DeterministicTaskSchedulerBuilder.java similarity index 84% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/deterministic/DeterministicTaskSchedulerBuilder.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/deterministic/DeterministicTaskSchedulerBuilder.java index c51b8ed5591..4044b008a42 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/deterministic/DeterministicTaskSchedulerBuilder.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/deterministic/DeterministicTaskSchedulerBuilder.java @@ -14,24 +14,24 @@ * limitations under the License. */ -package com.swirlds.wiring.model.internal.deterministic; +package org.hiero.wiring.framework.model.internal.deterministic; -import static com.swirlds.wiring.schedulers.builders.TaskSchedulerType.DIRECT_THREADSAFE; -import static com.swirlds.wiring.schedulers.builders.TaskSchedulerType.NO_OP; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.DIRECT_THREADSAFE; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.NO_OP; import com.swirlds.common.context.PlatformContext; import com.swirlds.common.metrics.extensions.FractionalTimer; import com.swirlds.common.metrics.extensions.NoOpFractionalTimer; -import com.swirlds.wiring.model.DeterministicWiringModel; -import com.swirlds.wiring.model.TraceableWiringModel; -import com.swirlds.wiring.schedulers.TaskScheduler; -import com.swirlds.wiring.schedulers.builders.internal.AbstractTaskSchedulerBuilder; -import com.swirlds.wiring.schedulers.internal.DirectTaskScheduler; -import com.swirlds.wiring.schedulers.internal.NoOpTaskScheduler; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.Objects; import java.util.concurrent.ForkJoinPool; import java.util.function.Consumer; +import org.hiero.wiring.framework.model.DeterministicWiringModel; +import org.hiero.wiring.framework.model.TraceableWiringModel; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.schedulers.builders.internal.AbstractTaskSchedulerBuilder; +import org.hiero.wiring.framework.schedulers.internal.DirectTaskScheduler; +import org.hiero.wiring.framework.schedulers.internal.NoOpTaskScheduler; /** * Builds schedulers for a {@link DeterministicWiringModel}. diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/monitor/HealthMonitor.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/monitor/HealthMonitor.java similarity index 96% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/monitor/HealthMonitor.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/monitor/HealthMonitor.java index 0f63ef7615b..8b26517831e 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/monitor/HealthMonitor.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/monitor/HealthMonitor.java @@ -14,13 +14,11 @@ * limitations under the License. */ -package com.swirlds.wiring.model.internal.monitor; +package org.hiero.wiring.framework.model.internal.monitor; import static com.swirlds.common.utility.CompareTo.isGreaterThan; import com.swirlds.common.context.PlatformContext; -import com.swirlds.wiring.schedulers.TaskScheduler; -import com.swirlds.wiring.schedulers.builders.TaskSchedulerBuilder; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; import java.time.Duration; @@ -29,6 +27,8 @@ import java.util.List; import java.util.Objects; import java.util.concurrent.atomic.AtomicReference; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerBuilder; /** * Monitors the health of a wiring model. A healthy wiring model is a model without too much work backed up in queues. diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/monitor/HealthMonitorLogger.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/monitor/HealthMonitorLogger.java similarity index 96% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/monitor/HealthMonitorLogger.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/monitor/HealthMonitorLogger.java index eb5db196c3d..289040df12a 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/monitor/HealthMonitorLogger.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/monitor/HealthMonitorLogger.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.wiring.model.internal.monitor; +package org.hiero.wiring.framework.model.internal.monitor; import static com.swirlds.common.units.TimeUnit.UNIT_NANOSECONDS; import static com.swirlds.logging.legacy.LogMarker.STARTUP; @@ -22,7 +22,6 @@ import com.swirlds.common.context.PlatformContext; import com.swirlds.common.utility.CompareTo; import com.swirlds.common.utility.throttle.RateLimitedLogger; -import com.swirlds.wiring.schedulers.TaskScheduler; import edu.umd.cs.findbugs.annotations.NonNull; import java.time.Duration; import java.util.HashMap; @@ -30,6 +29,7 @@ import java.util.Map; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.hiero.wiring.framework.schedulers.TaskScheduler; /** * Encapsulates logging for the wiring health monitor. diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/monitor/HealthMonitorMetrics.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/monitor/HealthMonitorMetrics.java similarity index 97% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/monitor/HealthMonitorMetrics.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/monitor/HealthMonitorMetrics.java index 3e69d441b5e..4ae63a86359 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/monitor/HealthMonitorMetrics.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/monitor/HealthMonitorMetrics.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.wiring.model.internal.monitor; +package org.hiero.wiring.framework.model.internal.monitor; import static com.swirlds.common.utility.CompareTo.isLessThan; diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/standard/AbstractHeartbeatScheduler.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/standard/AbstractHeartbeatScheduler.java similarity index 92% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/standard/AbstractHeartbeatScheduler.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/standard/AbstractHeartbeatScheduler.java index 8d622581c15..25a260b88b8 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/standard/AbstractHeartbeatScheduler.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/standard/AbstractHeartbeatScheduler.java @@ -14,20 +14,20 @@ * limitations under the License. */ -package com.swirlds.wiring.model.internal.standard; +package org.hiero.wiring.framework.model.internal.standard; -import static com.swirlds.wiring.model.diagram.HyperlinkBuilder.platformCommonHyperlink; +import static org.hiero.wiring.framework.model.diagram.HyperlinkBuilder.platformCommonHyperlink; import com.swirlds.base.time.Time; -import com.swirlds.wiring.model.TraceableWiringModel; -import com.swirlds.wiring.schedulers.builders.TaskSchedulerType; -import com.swirlds.wiring.wires.output.OutputWire; import edu.umd.cs.findbugs.annotations.NonNull; import java.time.Duration; import java.time.Instant; import java.util.ArrayList; import java.util.List; import java.util.Objects; +import org.hiero.wiring.framework.model.TraceableWiringModel; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.wires.output.OutputWire; /** * A scheduler that produces heartbeats at a specified rate. diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/standard/HeartbeatScheduler.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/standard/HeartbeatScheduler.java similarity index 94% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/standard/HeartbeatScheduler.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/standard/HeartbeatScheduler.java index 112ea7fe2a8..378fcdea49f 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/standard/HeartbeatScheduler.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/standard/HeartbeatScheduler.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.swirlds.wiring.model.internal.standard; +package org.hiero.wiring.framework.model.internal.standard; import com.swirlds.base.time.Time; -import com.swirlds.wiring.model.StandardWiringModel; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.Timer; +import org.hiero.wiring.framework.model.StandardWiringModel; /** * A scheduler that produces heartbeats at a specified rate. diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/standard/HeartbeatTask.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/standard/HeartbeatTask.java similarity index 90% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/standard/HeartbeatTask.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/standard/HeartbeatTask.java index 2e4f8dc7ac2..3777137e63a 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/standard/HeartbeatTask.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/standard/HeartbeatTask.java @@ -14,17 +14,17 @@ * limitations under the License. */ -package com.swirlds.wiring.model.internal.standard; +package org.hiero.wiring.framework.model.internal.standard; import com.swirlds.base.time.Time; -import com.swirlds.wiring.model.TraceableWiringModel; -import com.swirlds.wiring.wires.output.OutputWire; -import com.swirlds.wiring.wires.output.StandardOutputWire; import edu.umd.cs.findbugs.annotations.NonNull; import java.time.Duration; import java.time.Instant; import java.util.Objects; import java.util.TimerTask; +import org.hiero.wiring.framework.model.TraceableWiringModel; +import org.hiero.wiring.framework.wires.output.OutputWire; +import org.hiero.wiring.framework.wires.output.StandardOutputWire; /** * A task that produces a heartbeat at a specified rate. diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/standard/JvmAnchor.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/standard/JvmAnchor.java similarity index 96% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/standard/JvmAnchor.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/standard/JvmAnchor.java index 4085bc52601..c28cbadc709 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/model/internal/standard/JvmAnchor.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/model/internal/standard/JvmAnchor.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.wiring.model.internal.standard; +package org.hiero.wiring.framework.model.internal.standard; import static java.util.concurrent.TimeUnit.SECONDS; diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/TaskScheduler.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/schedulers/TaskScheduler.java similarity index 92% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/TaskScheduler.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/schedulers/TaskScheduler.java index f0029a43721..e5f6519b3cb 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/TaskScheduler.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/schedulers/TaskScheduler.java @@ -14,24 +14,24 @@ * limitations under the License. */ -package com.swirlds.wiring.schedulers; +package org.hiero.wiring.framework.schedulers; -import com.swirlds.wiring.counters.ObjectCounter; -import com.swirlds.wiring.model.TraceableWiringModel; -import com.swirlds.wiring.schedulers.builders.TaskSchedulerBuilder; -import com.swirlds.wiring.schedulers.builders.TaskSchedulerType; -import com.swirlds.wiring.schedulers.internal.DefaultSquelcher; -import com.swirlds.wiring.schedulers.internal.Squelcher; -import com.swirlds.wiring.schedulers.internal.ThrowingSquelcher; -import com.swirlds.wiring.wires.input.BindableInputWire; -import com.swirlds.wiring.wires.input.InputWire; -import com.swirlds.wiring.wires.input.TaskSchedulerInput; -import com.swirlds.wiring.wires.output.OutputWire; -import com.swirlds.wiring.wires.output.StandardOutputWire; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.Objects; import java.util.function.Consumer; import java.util.function.Function; +import org.hiero.wiring.framework.counters.ObjectCounter; +import org.hiero.wiring.framework.model.TraceableWiringModel; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerBuilder; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.schedulers.internal.DefaultSquelcher; +import org.hiero.wiring.framework.schedulers.internal.Squelcher; +import org.hiero.wiring.framework.schedulers.internal.ThrowingSquelcher; +import org.hiero.wiring.framework.wires.input.BindableInputWire; +import org.hiero.wiring.framework.wires.input.InputWire; +import org.hiero.wiring.framework.wires.input.TaskSchedulerInput; +import org.hiero.wiring.framework.wires.output.OutputWire; +import org.hiero.wiring.framework.wires.output.StandardOutputWire; /** * Schedules tasks for a component. diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/builders/TaskSchedulerBuilder.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/schedulers/builders/TaskSchedulerBuilder.java similarity index 97% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/builders/TaskSchedulerBuilder.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/schedulers/builders/TaskSchedulerBuilder.java index 498032acada..48bad3e8456 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/builders/TaskSchedulerBuilder.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/schedulers/builders/TaskSchedulerBuilder.java @@ -14,16 +14,16 @@ * limitations under the License. */ -package com.swirlds.wiring.schedulers.builders; +package org.hiero.wiring.framework.schedulers.builders; -import com.swirlds.wiring.counters.ObjectCounter; -import com.swirlds.wiring.schedulers.TaskScheduler; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; import java.lang.Thread.UncaughtExceptionHandler; import java.time.Duration; import java.util.concurrent.ForkJoinPool; import java.util.function.ToLongFunction; +import org.hiero.wiring.framework.counters.ObjectCounter; +import org.hiero.wiring.framework.schedulers.TaskScheduler; /** * A builder for {@link TaskScheduler}s. diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/builders/TaskSchedulerConfigOption.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/schedulers/builders/TaskSchedulerConfigOption.java similarity index 96% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/builders/TaskSchedulerConfigOption.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/schedulers/builders/TaskSchedulerConfigOption.java index 6c8af48fa12..702c2176bb2 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/builders/TaskSchedulerConfigOption.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/schedulers/builders/TaskSchedulerConfigOption.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.wiring.schedulers.builders; +package org.hiero.wiring.framework.schedulers.builders; /** * Various configuration options for a task scheduler. Note that the task scheduler type uses values from diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/builders/TaskSchedulerConfiguration.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/schedulers/builders/TaskSchedulerConfiguration.java similarity index 95% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/builders/TaskSchedulerConfiguration.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/schedulers/builders/TaskSchedulerConfiguration.java index f0116271655..dfd10c10883 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/builders/TaskSchedulerConfiguration.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/schedulers/builders/TaskSchedulerConfiguration.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.swirlds.wiring.schedulers.builders; +package org.hiero.wiring.framework.schedulers.builders; -import static com.swirlds.wiring.schedulers.builders.TaskSchedulerConfigOption.BUSY_FRACTION_METRIC; -import static com.swirlds.wiring.schedulers.builders.TaskSchedulerConfigOption.FLUSHABLE; -import static com.swirlds.wiring.schedulers.builders.TaskSchedulerConfigOption.SQUELCHABLE; -import static com.swirlds.wiring.schedulers.builders.TaskSchedulerConfigOption.UNHANDLED_TASK_METRIC; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerConfigOption.BUSY_FRACTION_METRIC; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerConfigOption.FLUSHABLE; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerConfigOption.SQUELCHABLE; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerConfigOption.UNHANDLED_TASK_METRIC; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/builders/TaskSchedulerType.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/schedulers/builders/TaskSchedulerType.java similarity index 98% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/builders/TaskSchedulerType.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/schedulers/builders/TaskSchedulerType.java index a536df9a178..fefb11a70dd 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/builders/TaskSchedulerType.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/schedulers/builders/TaskSchedulerType.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.wiring.schedulers.builders; +package org.hiero.wiring.framework.schedulers.builders; /** * Various types of task schedulers. Pass one of these types to {@link TaskSchedulerBuilder#withType(TaskSchedulerType)} diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/builders/internal/AbstractTaskSchedulerBuilder.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/schedulers/builders/internal/AbstractTaskSchedulerBuilder.java similarity index 92% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/builders/internal/AbstractTaskSchedulerBuilder.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/schedulers/builders/internal/AbstractTaskSchedulerBuilder.java index d646955f473..f5ff1ca3649 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/builders/internal/AbstractTaskSchedulerBuilder.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/schedulers/builders/internal/AbstractTaskSchedulerBuilder.java @@ -14,24 +14,14 @@ * limitations under the License. */ -package com.swirlds.wiring.schedulers.builders.internal; +package org.hiero.wiring.framework.schedulers.builders.internal; import static com.swirlds.logging.legacy.LogMarker.EXCEPTION; -import static com.swirlds.wiring.schedulers.builders.TaskSchedulerType.DIRECT; -import static com.swirlds.wiring.schedulers.builders.TaskSchedulerType.DIRECT_THREADSAFE; -import static com.swirlds.wiring.schedulers.builders.TaskSchedulerType.NO_OP; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.DIRECT; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.DIRECT_THREADSAFE; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.NO_OP; import com.swirlds.common.context.PlatformContext; -import com.swirlds.wiring.counters.BackpressureObjectCounter; -import com.swirlds.wiring.counters.MultiObjectCounter; -import com.swirlds.wiring.counters.NoOpObjectCounter; -import com.swirlds.wiring.counters.ObjectCounter; -import com.swirlds.wiring.counters.StandardObjectCounter; -import com.swirlds.wiring.model.TraceableWiringModel; -import com.swirlds.wiring.schedulers.TaskScheduler; -import com.swirlds.wiring.schedulers.builders.TaskSchedulerBuilder; -import com.swirlds.wiring.schedulers.builders.TaskSchedulerConfiguration; -import com.swirlds.wiring.schedulers.builders.TaskSchedulerType; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; import java.lang.Thread.UncaughtExceptionHandler; @@ -41,6 +31,16 @@ import java.util.function.ToLongFunction; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.hiero.wiring.framework.counters.BackpressureObjectCounter; +import org.hiero.wiring.framework.counters.MultiObjectCounter; +import org.hiero.wiring.framework.counters.NoOpObjectCounter; +import org.hiero.wiring.framework.counters.ObjectCounter; +import org.hiero.wiring.framework.counters.StandardObjectCounter; +import org.hiero.wiring.framework.model.TraceableWiringModel; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerBuilder; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerConfiguration; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; /** * A builder for {@link TaskScheduler}s. diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/builders/internal/StandardTaskSchedulerBuilder.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/schedulers/builders/internal/StandardTaskSchedulerBuilder.java similarity index 89% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/builders/internal/StandardTaskSchedulerBuilder.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/schedulers/builders/internal/StandardTaskSchedulerBuilder.java index edd89d11f0f..f58bf6c1691 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/builders/internal/StandardTaskSchedulerBuilder.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/schedulers/builders/internal/StandardTaskSchedulerBuilder.java @@ -14,29 +14,29 @@ * limitations under the License. */ -package com.swirlds.wiring.schedulers.builders.internal; +package org.hiero.wiring.framework.schedulers.builders.internal; -import static com.swirlds.wiring.schedulers.builders.TaskSchedulerType.DIRECT_THREADSAFE; -import static com.swirlds.wiring.schedulers.builders.TaskSchedulerType.NO_OP; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.DIRECT_THREADSAFE; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.NO_OP; import com.swirlds.common.context.PlatformContext; import com.swirlds.common.metrics.FunctionGauge; import com.swirlds.common.metrics.extensions.FractionalTimer; import com.swirlds.common.metrics.extensions.NoOpFractionalTimer; import com.swirlds.common.metrics.extensions.StandardFractionalTimer; -import com.swirlds.wiring.model.StandardWiringModel; -import com.swirlds.wiring.schedulers.TaskScheduler; -import com.swirlds.wiring.schedulers.builders.TaskSchedulerType; -import com.swirlds.wiring.schedulers.internal.ConcurrentTaskScheduler; -import com.swirlds.wiring.schedulers.internal.DirectTaskScheduler; -import com.swirlds.wiring.schedulers.internal.NoOpTaskScheduler; -import com.swirlds.wiring.schedulers.internal.SequentialTaskScheduler; -import com.swirlds.wiring.schedulers.internal.SequentialThreadTaskScheduler; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; import java.util.Objects; import java.util.concurrent.ForkJoinPool; import java.util.function.Supplier; +import org.hiero.wiring.framework.model.StandardWiringModel; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.schedulers.internal.ConcurrentTaskScheduler; +import org.hiero.wiring.framework.schedulers.internal.DirectTaskScheduler; +import org.hiero.wiring.framework.schedulers.internal.NoOpTaskScheduler; +import org.hiero.wiring.framework.schedulers.internal.SequentialTaskScheduler; +import org.hiero.wiring.framework.schedulers.internal.SequentialThreadTaskScheduler; /** * A builder for {@link TaskScheduler}s. diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/ConcurrentTask.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/schedulers/internal/ConcurrentTask.java similarity index 93% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/ConcurrentTask.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/schedulers/internal/ConcurrentTask.java index 0f058cad6ee..6cc66afcd2b 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/ConcurrentTask.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/schedulers/internal/ConcurrentTask.java @@ -14,15 +14,15 @@ * limitations under the License. */ -package com.swirlds.wiring.schedulers.internal; +package org.hiero.wiring.framework.schedulers.internal; -import com.swirlds.wiring.counters.ObjectCounter; -import com.swirlds.wiring.tasks.AbstractTask; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; import java.lang.Thread.UncaughtExceptionHandler; import java.util.concurrent.ForkJoinPool; import java.util.function.Consumer; +import org.hiero.wiring.framework.counters.ObjectCounter; +import org.hiero.wiring.framework.tasks.AbstractTask; /** * A task in a {@link ConcurrentTaskScheduler}. diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/ConcurrentTaskScheduler.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/schedulers/internal/ConcurrentTaskScheduler.java similarity index 93% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/ConcurrentTaskScheduler.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/schedulers/internal/ConcurrentTaskScheduler.java index ab350857ae0..423faaf625f 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/ConcurrentTaskScheduler.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/schedulers/internal/ConcurrentTaskScheduler.java @@ -14,17 +14,17 @@ * limitations under the License. */ -package com.swirlds.wiring.schedulers.internal; +package org.hiero.wiring.framework.schedulers.internal; -import com.swirlds.wiring.counters.ObjectCounter; -import com.swirlds.wiring.model.TraceableWiringModel; -import com.swirlds.wiring.schedulers.TaskScheduler; -import com.swirlds.wiring.schedulers.builders.TaskSchedulerType; import edu.umd.cs.findbugs.annotations.NonNull; import java.lang.Thread.UncaughtExceptionHandler; import java.util.Objects; import java.util.concurrent.ForkJoinPool; import java.util.function.Consumer; +import org.hiero.wiring.framework.counters.ObjectCounter; +import org.hiero.wiring.framework.model.TraceableWiringModel; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; /** * A {@link TaskScheduler} that permits parallel execution of tasks. diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/DefaultSquelcher.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/schedulers/internal/DefaultSquelcher.java similarity index 96% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/DefaultSquelcher.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/schedulers/internal/DefaultSquelcher.java index a430e40e2ba..7c1512d5702 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/DefaultSquelcher.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/schedulers/internal/DefaultSquelcher.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.wiring.schedulers.internal; +package org.hiero.wiring.framework.schedulers.internal; import java.util.concurrent.atomic.AtomicBoolean; diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/DirectTaskScheduler.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/schedulers/internal/DirectTaskScheduler.java similarity index 92% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/DirectTaskScheduler.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/schedulers/internal/DirectTaskScheduler.java index 8c1d1e812d9..08e991d2acc 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/DirectTaskScheduler.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/schedulers/internal/DirectTaskScheduler.java @@ -14,19 +14,19 @@ * limitations under the License. */ -package com.swirlds.wiring.schedulers.internal; +package org.hiero.wiring.framework.schedulers.internal; -import static com.swirlds.wiring.schedulers.builders.TaskSchedulerBuilder.UNLIMITED_CAPACITY; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerBuilder.UNLIMITED_CAPACITY; import com.swirlds.common.metrics.extensions.FractionalTimer; -import com.swirlds.wiring.counters.ObjectCounter; -import com.swirlds.wiring.model.TraceableWiringModel; -import com.swirlds.wiring.schedulers.TaskScheduler; -import com.swirlds.wiring.schedulers.builders.TaskSchedulerType; import edu.umd.cs.findbugs.annotations.NonNull; import java.lang.Thread.UncaughtExceptionHandler; import java.util.Objects; import java.util.function.Consumer; +import org.hiero.wiring.framework.counters.ObjectCounter; +import org.hiero.wiring.framework.model.TraceableWiringModel; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; /** * A scheduler that performs work immediately on the caller's thread. diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/NoOpTaskScheduler.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/schedulers/internal/NoOpTaskScheduler.java similarity index 86% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/NoOpTaskScheduler.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/schedulers/internal/NoOpTaskScheduler.java index c41bc4e3c98..3b0768a62aa 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/NoOpTaskScheduler.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/schedulers/internal/NoOpTaskScheduler.java @@ -14,20 +14,20 @@ * limitations under the License. */ -package com.swirlds.wiring.schedulers.internal; +package org.hiero.wiring.framework.schedulers.internal; -import static com.swirlds.wiring.schedulers.builders.TaskSchedulerBuilder.UNLIMITED_CAPACITY; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerBuilder.UNLIMITED_CAPACITY; -import com.swirlds.wiring.model.TraceableWiringModel; -import com.swirlds.wiring.schedulers.TaskScheduler; -import com.swirlds.wiring.schedulers.builders.TaskSchedulerType; -import com.swirlds.wiring.wires.input.BindableInputWire; -import com.swirlds.wiring.wires.input.NoOpInputWire; -import com.swirlds.wiring.wires.output.NoOpOutputWire; -import com.swirlds.wiring.wires.output.StandardOutputWire; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.Objects; import java.util.function.Consumer; +import org.hiero.wiring.framework.model.TraceableWiringModel; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.wires.input.BindableInputWire; +import org.hiero.wiring.framework.wires.input.NoOpInputWire; +import org.hiero.wiring.framework.wires.output.NoOpOutputWire; +import org.hiero.wiring.framework.wires.output.StandardOutputWire; /** * A no-op task scheduler that does nothing. diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/SequentialTask.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/schedulers/internal/SequentialTask.java similarity index 96% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/SequentialTask.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/schedulers/internal/SequentialTask.java index dcc1402d587..0b7facb31ae 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/SequentialTask.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/schedulers/internal/SequentialTask.java @@ -14,16 +14,16 @@ * limitations under the License. */ -package com.swirlds.wiring.schedulers.internal; +package org.hiero.wiring.framework.schedulers.internal; import com.swirlds.common.metrics.extensions.FractionalTimer; -import com.swirlds.wiring.counters.ObjectCounter; -import com.swirlds.wiring.tasks.AbstractTask; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; import java.lang.Thread.UncaughtExceptionHandler; import java.util.concurrent.ForkJoinPool; import java.util.function.Consumer; +import org.hiero.wiring.framework.counters.ObjectCounter; +import org.hiero.wiring.framework.tasks.AbstractTask; /** * A task in a {@link SequentialTaskScheduler}. diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/SequentialTaskScheduler.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/schedulers/internal/SequentialTaskScheduler.java similarity index 95% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/SequentialTaskScheduler.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/schedulers/internal/SequentialTaskScheduler.java index d5b0f3be84f..4698a5efdb2 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/SequentialTaskScheduler.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/schedulers/internal/SequentialTaskScheduler.java @@ -14,19 +14,19 @@ * limitations under the License. */ -package com.swirlds.wiring.schedulers.internal; +package org.hiero.wiring.framework.schedulers.internal; import com.swirlds.common.metrics.extensions.FractionalTimer; -import com.swirlds.wiring.counters.ObjectCounter; -import com.swirlds.wiring.model.TraceableWiringModel; -import com.swirlds.wiring.schedulers.TaskScheduler; -import com.swirlds.wiring.schedulers.builders.TaskSchedulerType; import edu.umd.cs.findbugs.annotations.NonNull; import java.lang.Thread.UncaughtExceptionHandler; import java.util.Objects; import java.util.concurrent.ForkJoinPool; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; +import org.hiero.wiring.framework.counters.ObjectCounter; +import org.hiero.wiring.framework.model.TraceableWiringModel; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; /** * A {@link TaskScheduler} that guarantees that tasks are executed sequentially in the order they are received. diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/SequentialThreadTask.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/schedulers/internal/SequentialThreadTask.java similarity index 95% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/SequentialThreadTask.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/schedulers/internal/SequentialThreadTask.java index d5adf7ddbb6..069d14baa9e 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/SequentialThreadTask.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/schedulers/internal/SequentialThreadTask.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.wiring.schedulers.internal; +package org.hiero.wiring.framework.schedulers.internal; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.function.Consumer; diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/SequentialThreadTaskScheduler.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/schedulers/internal/SequentialThreadTaskScheduler.java similarity index 95% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/SequentialThreadTaskScheduler.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/schedulers/internal/SequentialThreadTaskScheduler.java index 289e909a6bf..524e2affe39 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/SequentialThreadTaskScheduler.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/schedulers/internal/SequentialThreadTaskScheduler.java @@ -14,15 +14,11 @@ * limitations under the License. */ -package com.swirlds.wiring.schedulers.internal; +package org.hiero.wiring.framework.schedulers.internal; import com.swirlds.base.state.Startable; import com.swirlds.base.state.Stoppable; import com.swirlds.common.metrics.extensions.FractionalTimer; -import com.swirlds.wiring.counters.ObjectCounter; -import com.swirlds.wiring.model.TraceableWiringModel; -import com.swirlds.wiring.schedulers.TaskScheduler; -import com.swirlds.wiring.schedulers.builders.TaskSchedulerType; import edu.umd.cs.findbugs.annotations.NonNull; import java.lang.Thread.UncaughtExceptionHandler; import java.util.ArrayList; @@ -33,6 +29,10 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Consumer; import java.util.function.ToLongFunction; +import org.hiero.wiring.framework.counters.ObjectCounter; +import org.hiero.wiring.framework.model.TraceableWiringModel; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; /** * A scheduler that performs work sequentially on a dedicated thread. This class has very similar semantics to diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/Squelcher.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/schedulers/internal/Squelcher.java similarity index 97% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/Squelcher.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/schedulers/internal/Squelcher.java index 5b7639a29be..05a01f48052 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/Squelcher.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/schedulers/internal/Squelcher.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.wiring.schedulers.internal; +package org.hiero.wiring.framework.schedulers.internal; /** * Manages whether or not tasks scheduled by a given task scheduler should be squelched. diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/ThrowingSquelcher.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/schedulers/internal/ThrowingSquelcher.java similarity index 96% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/ThrowingSquelcher.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/schedulers/internal/ThrowingSquelcher.java index 9abaae540fa..2e54381322d 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/schedulers/internal/ThrowingSquelcher.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/schedulers/internal/ThrowingSquelcher.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.wiring.schedulers.internal; +package org.hiero.wiring.framework.schedulers.internal; /** * A squelcher object that does not support squelching. diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/tasks/AbstractTask.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/tasks/AbstractTask.java similarity index 98% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/tasks/AbstractTask.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/tasks/AbstractTask.java index 64a9cdb0e23..82e7527712d 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/tasks/AbstractTask.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/tasks/AbstractTask.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.wiring.tasks; +package org.hiero.wiring.framework.tasks; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.concurrent.ForkJoinPool; diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/transformers/AdvancedTransformation.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/transformers/AdvancedTransformation.java similarity index 95% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/transformers/AdvancedTransformation.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/transformers/AdvancedTransformation.java index 2c00ddb954f..165d6873083 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/transformers/AdvancedTransformation.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/transformers/AdvancedTransformation.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package com.swirlds.wiring.transformers; +package org.hiero.wiring.framework.transformers; -import com.swirlds.wiring.wires.output.OutputWire; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; +import org.hiero.wiring.framework.wires.output.OutputWire; /** * Executes a transformation for an advanced transformer as created by diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/transformers/RoutableData.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/transformers/RoutableData.java similarity index 95% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/transformers/RoutableData.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/transformers/RoutableData.java index 206db31ac7e..a80a7b292da 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/transformers/RoutableData.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/transformers/RoutableData.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.wiring.transformers; +package org.hiero.wiring.framework.transformers; import edu.umd.cs.findbugs.annotations.NonNull; diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/transformers/WireFilter.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/transformers/WireFilter.java similarity index 90% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/transformers/WireFilter.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/transformers/WireFilter.java index ecf4cd70f03..e925153c38f 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/transformers/WireFilter.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/transformers/WireFilter.java @@ -14,17 +14,17 @@ * limitations under the License. */ -package com.swirlds.wiring.transformers; +package org.hiero.wiring.framework.transformers; -import com.swirlds.wiring.model.WiringModel; -import com.swirlds.wiring.schedulers.TaskScheduler; -import com.swirlds.wiring.schedulers.builders.TaskSchedulerType; -import com.swirlds.wiring.wires.input.BindableInputWire; -import com.swirlds.wiring.wires.input.InputWire; -import com.swirlds.wiring.wires.output.OutputWire; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.Objects; import java.util.function.Predicate; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.wires.input.BindableInputWire; +import org.hiero.wiring.framework.wires.input.InputWire; +import org.hiero.wiring.framework.wires.output.OutputWire; /** * Filters out data, allowing some objects to pass and blocking others. diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/transformers/WireListSplitter.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/transformers/WireListSplitter.java similarity index 83% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/transformers/WireListSplitter.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/transformers/WireListSplitter.java index 48536e512b1..98612ce4be9 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/transformers/WireListSplitter.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/transformers/WireListSplitter.java @@ -14,17 +14,17 @@ * limitations under the License. */ -package com.swirlds.wiring.transformers; +package org.hiero.wiring.framework.transformers; -import com.swirlds.wiring.model.WiringModel; -import com.swirlds.wiring.schedulers.TaskScheduler; -import com.swirlds.wiring.schedulers.builders.TaskSchedulerType; -import com.swirlds.wiring.wires.input.BindableInputWire; -import com.swirlds.wiring.wires.input.InputWire; -import com.swirlds.wiring.wires.output.OutputWire; -import com.swirlds.wiring.wires.output.StandardOutputWire; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.List; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.wires.input.BindableInputWire; +import org.hiero.wiring.framework.wires.input.InputWire; +import org.hiero.wiring.framework.wires.output.OutputWire; +import org.hiero.wiring.framework.wires.output.StandardOutputWire; /** * Transforms a list of items to a sequence of individual items. Expects that there will not be any null values in the diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/transformers/WireRouter.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/transformers/WireRouter.java similarity index 89% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/transformers/WireRouter.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/transformers/WireRouter.java index 9f2c2103c36..da2ad7c5c5d 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/transformers/WireRouter.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/transformers/WireRouter.java @@ -14,19 +14,19 @@ * limitations under the License. */ -package com.swirlds.wiring.transformers; +package org.hiero.wiring.framework.transformers; -import static com.swirlds.wiring.schedulers.builders.TaskSchedulerType.DIRECT_THREADSAFE; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.DIRECT_THREADSAFE; -import com.swirlds.wiring.model.WiringModel; -import com.swirlds.wiring.schedulers.TaskScheduler; -import com.swirlds.wiring.wires.input.BindableInputWire; -import com.swirlds.wiring.wires.input.InputWire; -import com.swirlds.wiring.wires.output.OutputWire; -import com.swirlds.wiring.wires.output.StandardOutputWire; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.ArrayList; import java.util.List; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.wires.input.BindableInputWire; +import org.hiero.wiring.framework.wires.input.InputWire; +import org.hiero.wiring.framework.wires.output.OutputWire; +import org.hiero.wiring.framework.wires.output.StandardOutputWire; /** * Create a wire router. A wire router takes a single input and splits data into multiple outputs with different diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/transformers/WireTransformer.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/transformers/WireTransformer.java similarity index 90% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/transformers/WireTransformer.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/transformers/WireTransformer.java index 99dcffc2152..0da8bb7f780 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/transformers/WireTransformer.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/transformers/WireTransformer.java @@ -14,17 +14,17 @@ * limitations under the License. */ -package com.swirlds.wiring.transformers; +package org.hiero.wiring.framework.transformers; -import com.swirlds.wiring.model.WiringModel; -import com.swirlds.wiring.schedulers.TaskScheduler; -import com.swirlds.wiring.schedulers.builders.TaskSchedulerType; -import com.swirlds.wiring.wires.input.BindableInputWire; -import com.swirlds.wiring.wires.input.InputWire; -import com.swirlds.wiring.wires.output.OutputWire; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.Objects; import java.util.function.Function; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.wires.input.BindableInputWire; +import org.hiero.wiring.framework.wires.input.InputWire; +import org.hiero.wiring.framework.wires.output.OutputWire; /** * Transforms data on a wire from one type to another. diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/SolderType.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/wires/SolderType.java similarity index 92% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/SolderType.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/wires/SolderType.java index 5e955dc2341..9bc14b30c53 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/SolderType.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/wires/SolderType.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package com.swirlds.wiring.wires; +package org.hiero.wiring.framework.wires; -import com.swirlds.wiring.wires.input.InputWire; +import org.hiero.wiring.framework.wires.input.InputWire; /** * The type of solder connection between an output wire and an input wire. diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/input/Bindable.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/wires/input/Bindable.java similarity index 97% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/input/Bindable.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/wires/input/Bindable.java index 3f3480f2e3c..54045c83eff 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/input/Bindable.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/wires/input/Bindable.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.wiring.wires.input; +package org.hiero.wiring.framework.wires.input; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.function.Consumer; diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/input/BindableInputWire.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/wires/input/BindableInputWire.java similarity index 93% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/input/BindableInputWire.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/wires/input/BindableInputWire.java index d5cda97ec96..e0e703b3c41 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/input/BindableInputWire.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/wires/input/BindableInputWire.java @@ -14,17 +14,17 @@ * limitations under the License. */ -package com.swirlds.wiring.wires.input; +package org.hiero.wiring.framework.wires.input; -import static com.swirlds.wiring.schedulers.builders.TaskSchedulerType.NO_OP; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.NO_OP; -import com.swirlds.wiring.model.TraceableWiringModel; -import com.swirlds.wiring.schedulers.TaskScheduler; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.Objects; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Supplier; +import org.hiero.wiring.framework.model.TraceableWiringModel; +import org.hiero.wiring.framework.schedulers.TaskScheduler; /** * An input wire that can be bound to an implementation. diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/input/InputWire.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/wires/input/InputWire.java similarity index 95% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/input/InputWire.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/wires/input/InputWire.java index 7b71bfc6827..ca80cc36e6b 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/input/InputWire.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/wires/input/InputWire.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package com.swirlds.wiring.wires.input; +package org.hiero.wiring.framework.wires.input; -import com.swirlds.wiring.schedulers.TaskScheduler; -import com.swirlds.wiring.schedulers.builders.TaskSchedulerType; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.Objects; import java.util.function.Consumer; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; /** * An object that can insert work to be handled by a {@link TaskScheduler}. diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/input/NoOpInputWire.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/wires/input/NoOpInputWire.java similarity index 93% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/input/NoOpInputWire.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/wires/input/NoOpInputWire.java index 505c4741113..f6eb8810d9f 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/input/NoOpInputWire.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/wires/input/NoOpInputWire.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package com.swirlds.wiring.wires.input; +package org.hiero.wiring.framework.wires.input; -import com.swirlds.wiring.model.TraceableWiringModel; -import com.swirlds.wiring.schedulers.TaskScheduler; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.function.Consumer; import java.util.function.Function; +import org.hiero.wiring.framework.model.TraceableWiringModel; +import org.hiero.wiring.framework.schedulers.TaskScheduler; /** * An input wire that doesn't actually do anything. When asked to bind a handler, it does nothing. When asked to insert diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/input/TaskSchedulerInput.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/wires/input/TaskSchedulerInput.java similarity index 95% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/input/TaskSchedulerInput.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/wires/input/TaskSchedulerInput.java index 6ef6fc9868c..ee3ffe36f12 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/input/TaskSchedulerInput.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/wires/input/TaskSchedulerInput.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package com.swirlds.wiring.wires.input; +package org.hiero.wiring.framework.wires.input; -import com.swirlds.wiring.schedulers.TaskScheduler; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.function.Consumer; +import org.hiero.wiring.framework.schedulers.TaskScheduler; /** * An object that knows how to add data to a {@link TaskScheduler} for processing, and how to forward data to a task diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/output/NoOpOutputWire.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/wires/output/NoOpOutputWire.java similarity index 92% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/output/NoOpOutputWire.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/wires/output/NoOpOutputWire.java index 14a77481f07..c90f00cee8f 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/output/NoOpOutputWire.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/wires/output/NoOpOutputWire.java @@ -14,16 +14,16 @@ * limitations under the License. */ -package com.swirlds.wiring.wires.output; +package org.hiero.wiring.framework.wires.output; -import com.swirlds.wiring.model.TraceableWiringModel; -import com.swirlds.wiring.transformers.AdvancedTransformation; -import com.swirlds.wiring.wires.SolderType; -import com.swirlds.wiring.wires.input.InputWire; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Predicate; +import org.hiero.wiring.framework.model.TraceableWiringModel; +import org.hiero.wiring.framework.transformers.AdvancedTransformation; +import org.hiero.wiring.framework.wires.SolderType; +import org.hiero.wiring.framework.wires.input.InputWire; /** * An output wire that doesn't actually do anything. When asked to solder to another wire, it does nothing. When asked diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/output/OutputWire.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/wires/output/OutputWire.java similarity index 93% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/output/OutputWire.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/wires/output/OutputWire.java index 55850d520b8..887f25fcdc8 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/output/OutputWire.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/wires/output/OutputWire.java @@ -14,27 +14,27 @@ * limitations under the License. */ -package com.swirlds.wiring.wires.output; +package org.hiero.wiring.framework.wires.output; -import static com.swirlds.wiring.schedulers.builders.TaskSchedulerType.NO_OP; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.NO_OP; -import com.swirlds.wiring.model.TraceableWiringModel; -import com.swirlds.wiring.schedulers.TaskScheduler; -import com.swirlds.wiring.schedulers.builders.TaskSchedulerType; -import com.swirlds.wiring.transformers.AdvancedTransformation; -import com.swirlds.wiring.transformers.WireFilter; -import com.swirlds.wiring.transformers.WireListSplitter; -import com.swirlds.wiring.transformers.WireTransformer; -import com.swirlds.wiring.wires.SolderType; -import com.swirlds.wiring.wires.input.BindableInputWire; -import com.swirlds.wiring.wires.input.InputWire; -import com.swirlds.wiring.wires.output.internal.TransformingOutputWire; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.List; import java.util.Objects; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Predicate; +import org.hiero.wiring.framework.model.TraceableWiringModel; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.transformers.AdvancedTransformation; +import org.hiero.wiring.framework.transformers.WireFilter; +import org.hiero.wiring.framework.transformers.WireListSplitter; +import org.hiero.wiring.framework.transformers.WireTransformer; +import org.hiero.wiring.framework.wires.SolderType; +import org.hiero.wiring.framework.wires.input.BindableInputWire; +import org.hiero.wiring.framework.wires.input.InputWire; +import org.hiero.wiring.framework.wires.output.internal.TransformingOutputWire; /** * Describes the output of a task scheduler. Can be soldered to wire inputs or lambdas. diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/output/StandardOutputWire.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/wires/output/StandardOutputWire.java similarity index 92% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/output/StandardOutputWire.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/wires/output/StandardOutputWire.java index b93be9f713f..1415bdb9fa5 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/output/StandardOutputWire.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/wires/output/StandardOutputWire.java @@ -14,12 +14,10 @@ * limitations under the License. */ -package com.swirlds.wiring.wires.output; +package org.hiero.wiring.framework.wires.output; import static com.swirlds.logging.legacy.LogMarker.EXCEPTION; -import com.swirlds.wiring.model.TraceableWiringModel; -import com.swirlds.wiring.wires.output.internal.ForwardingOutputWire; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.ArrayList; import java.util.List; @@ -27,6 +25,8 @@ import java.util.function.Consumer; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.hiero.wiring.framework.model.TraceableWiringModel; +import org.hiero.wiring.framework.wires.output.internal.ForwardingOutputWire; /** * An output wire that will take data and forward it to its outputs. Output type is the same as the input type. diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/output/internal/ForwardingOutputWire.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/wires/output/internal/ForwardingOutputWire.java similarity index 90% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/output/internal/ForwardingOutputWire.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/wires/output/internal/ForwardingOutputWire.java index 60731fd693a..5d7a677f5b5 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/output/internal/ForwardingOutputWire.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/wires/output/internal/ForwardingOutputWire.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package com.swirlds.wiring.wires.output.internal; +package org.hiero.wiring.framework.wires.output.internal; -import com.swirlds.wiring.model.TraceableWiringModel; -import com.swirlds.wiring.wires.output.OutputWire; import edu.umd.cs.findbugs.annotations.NonNull; +import org.hiero.wiring.framework.model.TraceableWiringModel; +import org.hiero.wiring.framework.wires.output.OutputWire; /** * An output wire that will take data and forward it to its outputs. diff --git a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/output/internal/TransformingOutputWire.java b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/wires/output/internal/TransformingOutputWire.java similarity index 94% rename from platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/output/internal/TransformingOutputWire.java rename to platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/wires/output/internal/TransformingOutputWire.java index 4bd7ebc3ee7..6fe70d952a7 100644 --- a/platform-sdk/consensus-wiring/src/main/java/com/swirlds/wiring/wires/output/internal/TransformingOutputWire.java +++ b/platform-sdk/wiring-framework/src/main/java/org/hiero/wiring/framework/wires/output/internal/TransformingOutputWire.java @@ -14,14 +14,10 @@ * limitations under the License. */ -package com.swirlds.wiring.wires.output.internal; +package org.hiero.wiring.framework.wires.output.internal; import static com.swirlds.logging.legacy.LogMarker.EXCEPTION; -import com.swirlds.wiring.model.TraceableWiringModel; -import com.swirlds.wiring.wires.SolderType; -import com.swirlds.wiring.wires.input.InputWire; -import com.swirlds.wiring.wires.output.OutputWire; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; import java.util.ArrayList; @@ -31,6 +27,10 @@ import java.util.function.Function; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.hiero.wiring.framework.model.TraceableWiringModel; +import org.hiero.wiring.framework.wires.SolderType; +import org.hiero.wiring.framework.wires.input.InputWire; +import org.hiero.wiring.framework.wires.output.OutputWire; /** * An output wire that transforms data that flows across it. For advanced use cases where diff --git a/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/benchmark/WiringBenchmark.java b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/benchmark/WiringBenchmark.java new file mode 100644 index 00000000000..9a9ea28394a --- /dev/null +++ b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/benchmark/WiringBenchmark.java @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 org.hiero.wiring.framework.benchmark; + +import static java.util.concurrent.ForkJoinPool.defaultForkJoinWorkerThreadFactory; +import static java.util.concurrent.TimeUnit.SECONDS; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import com.swirlds.common.context.PlatformContext; +import com.swirlds.common.test.fixtures.platform.TestPlatformContextBuilder; +import java.time.Duration; +import java.util.concurrent.ForkJoinPool; +import org.hiero.wiring.framework.counters.BackpressureObjectCounter; +import org.hiero.wiring.framework.counters.ObjectCounter; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.model.WiringModelBuilder; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.wires.input.BindableInputWire; + +class WiringBenchmark { + + /* Data flow for this benchmark: + + gossip -> event verifier -> orphan buffer + ^ | + | | + --------------------------------- + + */ + + static void basicBenchmark() throws InterruptedException { + + // We will use this executor for starting all threads. Maybe we should only use it for temporary threads? + final ForkJoinPool executor = new ForkJoinPool( + Runtime.getRuntime().availableProcessors(), + defaultForkJoinWorkerThreadFactory, + (t, e) -> { + System.out.println("Uncaught exception in thread " + t.getName()); + e.printStackTrace(); + }, + true); + + final PlatformContext platformContext = + TestPlatformContextBuilder.create().build(); + final WiringModel model = WiringModelBuilder.create(platformContext).build(); + + // Ensures that we have no more than 10,000 events in the pipeline at any given time + final ObjectCounter backpressure = new BackpressureObjectCounter("backpressure", 10_000, Duration.ZERO); + + final TaskScheduler verificationTaskScheduler = model.schedulerBuilder("verification") + .withPool(executor) + .withType(TaskSchedulerType.CONCURRENT) + .withOnRamp(backpressure) + .withExternalBackPressure(true) + .build() + .cast(); + + final TaskScheduler orphanBufferTaskScheduler = model.schedulerBuilder("orphanBuffer") + .withPool(executor) + .withType(TaskSchedulerType.SEQUENTIAL) + .withExternalBackPressure(true) + .build() + .cast(); + + final TaskScheduler eventPoolTaskScheduler = model.schedulerBuilder("eventPool") + .withPool(executor) + .withType(TaskSchedulerType.SEQUENTIAL) + .withOffRamp(backpressure) + .withExternalBackPressure(true) + .build() + .cast(); + + final BindableInputWire eventsToOrphanBuffer = + orphanBufferTaskScheduler.buildInputWire("unordered events"); + + final BindableInputWire eventsToBeVerified = + verificationTaskScheduler.buildInputWire("unverified events"); + + final BindableInputWire eventsToInsertBackIntoEventPool = + eventPoolTaskScheduler.buildInputWire("verified events"); + + verificationTaskScheduler.getOutputWire().solderTo(eventsToOrphanBuffer); + orphanBufferTaskScheduler.getOutputWire().solderTo(eventsToInsertBackIntoEventPool); + + final WiringBenchmarkEventPool eventPool = new WiringBenchmarkEventPool(); + final WiringBenchmarkTopologicalEventSorter orphanBuffer = new WiringBenchmarkTopologicalEventSorter(); + final WiringBenchmarkEventVerifier verifier = new WiringBenchmarkEventVerifier(); + final WiringBenchmarkGossip gossip = new WiringBenchmarkGossip(executor, eventPool, eventsToBeVerified::put); + + eventsToOrphanBuffer.bind(orphanBuffer); + eventsToBeVerified.bind(verifier); + eventsToInsertBackIntoEventPool.bindConsumer(eventPool::checkin); + + // Create a user thread for running "gossip". It will continue to generate events until explicitly stopped. + System.out.println("Starting gossip"); + gossip.start(); + SECONDS.sleep(120); + gossip.stop(); + + // Validate that all events have been seen by orphanBuffer + final long timeout = System.currentTimeMillis() + 1000; + boolean success = false; + while (System.currentTimeMillis() < timeout) { + if (orphanBuffer.getCheckSum() == gossip.getCheckSum()) { + success = true; + break; + } + } + assertTrue(success); + } + + public static void main(String[] args) { + try { + basicBenchmark(); + } catch (final Throwable t) { + t.printStackTrace(); + } + } +} diff --git a/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/benchmark/WiringBenchmarkEvent.java b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/benchmark/WiringBenchmarkEvent.java new file mode 100644 index 00000000000..31f4ea2ee75 --- /dev/null +++ b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/benchmark/WiringBenchmarkEvent.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 org.hiero.wiring.framework.benchmark; + +public final class WiringBenchmarkEvent { + private long number = -1; // We'll let the orphan buffer assign this, although I think consensus actually does + private final byte[] data = new byte[1024 * 32]; // Just gotta have some bytes. Whatever. + + public WiringBenchmarkEvent() {} + + void reset(long number) { + this.number = number; + } + + @Override + public String toString() { + return "Event {number=" + number + "}"; + } + + public long number() { + return number; + } +} diff --git a/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/benchmark/WiringBenchmarkEventPool.java b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/benchmark/WiringBenchmarkEventPool.java new file mode 100644 index 00000000000..4f1cc250c7d --- /dev/null +++ b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/benchmark/WiringBenchmarkEventPool.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 org.hiero.wiring.framework.benchmark; + +import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; + +public final class WiringBenchmarkEventPool { + private final BlockingQueue pool = new LinkedBlockingQueue<>(); + + public WiringBenchmarkEventPool() {} + + @NonNull + public WiringBenchmarkEvent checkout(long number) { + WiringBenchmarkEvent event = pool.poll(); + if (event == null) { + event = new WiringBenchmarkEvent(); + } + event.reset(number); + return event; + } + + public void checkin(WiringBenchmarkEvent event) { + pool.add(event); + } +} diff --git a/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/benchmark/WiringBenchmarkEventVerifier.java b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/benchmark/WiringBenchmarkEventVerifier.java new file mode 100644 index 00000000000..4038add9929 --- /dev/null +++ b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/benchmark/WiringBenchmarkEventVerifier.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 org.hiero.wiring.framework.benchmark; + +import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.function.Function; + +public class WiringBenchmarkEventVerifier implements Function { + + public WiringBenchmarkEventVerifier() {} + + @Override + @NonNull + public WiringBenchmarkEvent apply(@NonNull final WiringBenchmarkEvent event) { + // Pretend like we did verification by sleeping for a few microseconds + busySleep(2000); + return event; + } + + public static void busySleep(long nanos) { + long elapsed; + final long startTime = System.nanoTime(); + do { + elapsed = System.nanoTime() - startTime; + } while (elapsed < nanos); + } +} diff --git a/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/benchmark/WiringBenchmarkGossip.java b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/benchmark/WiringBenchmarkGossip.java new file mode 100644 index 00000000000..0bbd650c894 --- /dev/null +++ b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/benchmark/WiringBenchmarkGossip.java @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 org.hiero.wiring.framework.benchmark; + +import java.util.concurrent.Executor; +import java.util.concurrent.atomic.AtomicLong; +import java.util.function.Consumer; + +/** + * A quick and dirty simulation of gossip :-). It will generate events like crazy. + */ +public class WiringBenchmarkGossip { + private final Executor executor; + private final WiringBenchmarkEventPool eventPool; + private final Consumer toEventVerifier; + private final AtomicLong eventNumber = new AtomicLong(); + private volatile boolean stopped = false; + private volatile long checkSum; + + public WiringBenchmarkGossip( + Executor executor, WiringBenchmarkEventPool eventPool, Consumer toEventVerifier) { + this.executor = executor; + this.toEventVerifier = toEventVerifier; + this.eventPool = eventPool; + } + + public void start() { + eventNumber.set(0); + checkSum = 0; + executor.execute(this::generateEvents); + } + + private void generateEvents() { + while (!stopped) { + final var event = eventPool.checkout(eventNumber.getAndIncrement()); + toEventVerifier.accept(event); + } + long lastNumber = eventNumber.get(); + checkSum = lastNumber * (lastNumber + 1) / 2; + } + + public void stop() { + stopped = true; + } + + public long getCheckSum() { + return checkSum; + } +} diff --git a/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/benchmark/WiringBenchmarkTopologicalEventSorter.java b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/benchmark/WiringBenchmarkTopologicalEventSorter.java new file mode 100644 index 00000000000..4d8edb1143a --- /dev/null +++ b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/benchmark/WiringBenchmarkTopologicalEventSorter.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 org.hiero.wiring.framework.benchmark; + +import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.function.Function; + +public class WiringBenchmarkTopologicalEventSorter implements Function { + private static final int PRINT_FREQUENCY = 10_000_000; + private long lastTimestamp; + private long checkSum; + + public WiringBenchmarkTopologicalEventSorter() { + this.checkSum = 0; + } + + @NonNull + @Override + public WiringBenchmarkEvent apply(@NonNull final WiringBenchmarkEvent event) { + final long number = event.number(); + checkSum += number + 1; // make 0 contribute to the sum + if (number % PRINT_FREQUENCY == 0) { + long curTimestamp = System.currentTimeMillis(); + if (number != 0) { + System.out.format( + "Handled %d events, TPS: %d%n", + number, PRINT_FREQUENCY * 1000L / (curTimestamp - lastTimestamp)); + } + lastTimestamp = curTimestamp; + } + return event; + } + + public long getCheckSum() { + return checkSum; + } +} diff --git a/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/builders/TaskSchedulerConfigurationTests.java b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/builders/TaskSchedulerConfigurationTests.java new file mode 100644 index 00000000000..c63dc999fbf --- /dev/null +++ b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/builders/TaskSchedulerConfigurationTests.java @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC + * + * 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 org.hiero.wiring.framework.builders; + +import static com.swirlds.common.test.fixtures.RandomUtils.getRandomPrintSeed; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.Random; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerConfiguration; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; +import org.junit.jupiter.api.Test; + +class TaskSchedulerConfigurationTests { + + @Test + void defaultValuesTest() { + final String configString = ""; + final TaskSchedulerConfiguration config = TaskSchedulerConfiguration.parse(configString); + + assertNull(config.type()); + assertNull(config.unhandledTaskCapacity()); + assertNull(config.unhandledTaskMetricEnabled()); + assertNull(config.busyFractionMetricEnabled()); + assertNull(config.flushingEnabled()); + assertNull(config.squelchingEnabled()); + } + + @Test + void randomValuesTest() { + final Random random = getRandomPrintSeed(); + + for (int i = 0; i < 100; i++) { + final StringBuilder configStringBuilder = new StringBuilder(); + + final TaskSchedulerType expectedTaskSchedulerType; + if (random.nextBoolean()) { + expectedTaskSchedulerType = + TaskSchedulerType.values()[random.nextInt(TaskSchedulerType.values().length)]; + configStringBuilder.append(expectedTaskSchedulerType).append(" "); + } else { + expectedTaskSchedulerType = null; + } + + final Long expectedUnhandledTaskCapacity; + if (random.nextBoolean()) { + expectedUnhandledTaskCapacity = random.nextLong(0, 100); + configStringBuilder + .append("CAPACITY(") + .append(expectedUnhandledTaskCapacity) + .append(") "); + } else { + expectedUnhandledTaskCapacity = null; + } + + final Boolean expectedUnhandledTaskMetricEnabled; + if (random.nextBoolean()) { + expectedUnhandledTaskMetricEnabled = random.nextBoolean(); + configStringBuilder.append( + expectedUnhandledTaskMetricEnabled ? "UNHANDLED_TASK_METRIC " : "!UNHANDLED_TASK_METRIC "); + } else { + expectedUnhandledTaskMetricEnabled = null; + } + + final Boolean expectedBusyFractionMetricEnabled; + if (random.nextBoolean()) { + expectedBusyFractionMetricEnabled = random.nextBoolean(); + configStringBuilder.append( + expectedBusyFractionMetricEnabled ? "BUSY_FRACTION_METRIC " : "!BUSY_FRACTION_METRIC "); + } else { + expectedBusyFractionMetricEnabled = null; + } + + final Boolean expectedFlushingEnabled; + if (random.nextBoolean()) { + expectedFlushingEnabled = random.nextBoolean(); + configStringBuilder.append(expectedFlushingEnabled ? "FLUSHABLE " : "!FLUSHABLE "); + } else { + expectedFlushingEnabled = null; + } + + final Boolean expectedSquelchingEnabled; + if (random.nextBoolean()) { + expectedSquelchingEnabled = random.nextBoolean(); + configStringBuilder.append(expectedSquelchingEnabled ? "SQUELCHABLE " : "!SQUELCHABLE "); + } else { + expectedSquelchingEnabled = null; + } + + final String configString = configStringBuilder.toString(); + + final TaskSchedulerConfiguration config = TaskSchedulerConfiguration.parse(configString); + + assertEquals(expectedTaskSchedulerType, config.type()); + assertEquals(expectedUnhandledTaskCapacity, config.unhandledTaskCapacity()); + assertEquals(expectedUnhandledTaskMetricEnabled, config.unhandledTaskMetricEnabled()); + assertEquals(expectedBusyFractionMetricEnabled, config.busyFractionMetricEnabled()); + assertEquals(expectedFlushingEnabled, config.flushingEnabled()); + assertEquals(expectedSquelchingEnabled, config.squelchingEnabled()); + } + } + + /** + * Test what happens if a configuration string contains multiple values for the same configuration option. + */ + @Test + void doubleConfigurationTest() { + assertThrows(IllegalArgumentException.class, () -> TaskSchedulerConfiguration.parse("DIRECT DIRECT")); + assertThrows(IllegalArgumentException.class, () -> TaskSchedulerConfiguration.parse("DIRECT SEQUENTIAL")); + assertThrows( + IllegalArgumentException.class, + () -> TaskSchedulerConfiguration.parse("CAPACITY(1234) CAPACITY(1234)")); + assertThrows( + IllegalArgumentException.class, + () -> TaskSchedulerConfiguration.parse("CAPACITY(1234) CAPACITY(5678)")); + assertThrows( + IllegalArgumentException.class, + () -> TaskSchedulerConfiguration.parse("UNHANDLED_TASK_METRIC UNHANDLED_TASK_METRIC")); + assertThrows( + IllegalArgumentException.class, + () -> TaskSchedulerConfiguration.parse("UNHANDLED_TASK_METRIC !UNHANDLED_TASK_METRIC")); + assertThrows( + IllegalArgumentException.class, + () -> TaskSchedulerConfiguration.parse("BUSY_FRACTION_METRIC BUSY_FRACTION_METRIC")); + assertThrows( + IllegalArgumentException.class, + () -> TaskSchedulerConfiguration.parse("BUSY_FRACTION_METRIC !BUSY_FRACTION_METRIC")); + assertThrows(IllegalArgumentException.class, () -> TaskSchedulerConfiguration.parse("FLUSHABLE !FLUSHABLE")); + assertThrows(IllegalArgumentException.class, () -> TaskSchedulerConfiguration.parse("FLUSHABLE FLUSHABLE")); + assertThrows( + IllegalArgumentException.class, () -> TaskSchedulerConfiguration.parse("SQUELCHABLE !SQUELCHABLE")); + assertThrows(IllegalArgumentException.class, () -> TaskSchedulerConfiguration.parse("SQUELCHABLE SQUELCHABLE")); + } + + @Test + void unmatchedFieldTest() { + assertThrows( + IllegalArgumentException.class, () -> TaskSchedulerConfiguration.parse("DIRECT CAPACITY(100) QWERTY")); + } +} diff --git a/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/component/ComponentWiringRouterTests.java b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/component/ComponentWiringRouterTests.java new file mode 100644 index 00000000000..7e2daf4edc9 --- /dev/null +++ b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/component/ComponentWiringRouterTests.java @@ -0,0 +1,310 @@ +/* + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC + * + * 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 org.hiero.wiring.framework.component; + +import static com.swirlds.common.test.fixtures.RandomUtils.getRandomPrintSeed; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerConfiguration.DIRECT_CONFIGURATION; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import com.swirlds.common.context.PlatformContext; +import com.swirlds.common.test.fixtures.platform.TestPlatformContextBuilder; +import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicLong; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.model.WiringModelBuilder; +import org.hiero.wiring.framework.transformers.RoutableData; +import org.hiero.wiring.framework.wires.output.OutputWire; +import org.junit.jupiter.api.Test; + +class ComponentWiringRouterTests { + + private enum TestDataType { + FOO, // Long values + BAR, // Long values + BAZ; // Boolean values + + /** + * Create a new {@link RoutableData} object with the given data. + * + * @param data the data + * @return the new {@link RoutableData} object + */ + @NonNull + public RoutableData of(@NonNull final Object data) { + return new RoutableData<>(this, data); + } + } + + private enum TestDataType2 { + FOO, // Long values + BAR, // Long values + BAZ; // Boolean values + + /** + * Create a new {@link RoutableData} object with the given data. + * + * @param data the data + * @return the new {@link RoutableData} object + */ + @NonNull + public RoutableData of(@NonNull final Object data) { + return new RoutableData<>(this, data); + } + } + + private interface TestComponent { + @NonNull + RoutableData doWork(@NonNull Integer input); + } + + private static class TestComponentImpl implements TestComponent { + @NonNull + @Override + public RoutableData doWork(@NonNull final Integer input) { + if (input % 3 == 0) { + return TestDataType.FOO.of(input.longValue()); + } else if (input % 3 == 1) { + return TestDataType.BAR.of(input.longValue()); + } else { + return TestDataType.BAZ.of(input % 2 == 0); + } + } + } + + private interface TestListComponent { + @NonNull + List> doWork(@NonNull Integer input); + } + + private static class TestListComponentImpl implements TestListComponent { + @NonNull + @Override + public List> doWork(@NonNull final Integer input) { + + final List> output = new ArrayList<>(); + + if (input % 3 == 0) { + output.add(TestDataType.FOO.of(input.longValue())); + } else if (input % 3 == 1) { + output.add(TestDataType.BAR.of(input.longValue())); + } else { + output.add(TestDataType.BAZ.of(input % 2 == 0)); + } + + if (input % 2 == 0) { + output.add(TestDataType.FOO.of(input.longValue() / 2)); + } else { + output.add(TestDataType.BAR.of(input.longValue() / 2)); + } + + if (input % 5 == 0) { + output.add(TestDataType.FOO.of(input.longValue() / 5)); + } + + return output; + } + } + + @Test + void basicBehaviorTest() { + final Random random = getRandomPrintSeed(); + + final PlatformContext platformContext = + TestPlatformContextBuilder.create().build(); + final WiringModel model = WiringModelBuilder.create(platformContext).build(); + + final ComponentWiring> wiring = + new ComponentWiring<>(model, TestComponent.class, DIRECT_CONFIGURATION); + + wiring.bind(new TestComponentImpl()); + + final AtomicLong latestFoo = new AtomicLong(); + final AtomicLong latestBar = new AtomicLong(); + final AtomicBoolean latestBaz = new AtomicBoolean(); + + final OutputWire fooOutput = wiring.getRoutedOutput(TestDataType.FOO); + final OutputWire barOutput = wiring.getRoutedOutput(TestDataType.BAR); + final OutputWire bazOutput = wiring.getRoutedOutput(TestDataType.BAZ); + + fooOutput.solderTo("fooHandler", "fooInput", latestFoo::set); + barOutput.solderTo("barHandler", "barInput", latestBar::set); + bazOutput.solderTo("bazHandler", "bazInput", latestBaz::set); + + long expectedFoo = 0; + long expectedBar = 0; + boolean expectedBaz = false; + + // Intentional: we have to create all wires prior to starting the model + wiring.getInputWire(TestComponent::doWork); + + model.start(); + + for (int i = 0; i < 1000; i++) { + final int value = random.nextInt(); + if (value % 3 == 0) { + expectedFoo = value; + } else if (value % 3 == 1) { + expectedBar = value; + } else { + expectedBaz = value % 2 == 0; + } + wiring.getInputWire(TestComponent::doWork).put(value); + + assertEquals(expectedFoo, latestFoo.get()); + assertEquals(expectedBar, latestBar.get()); + assertEquals(expectedBaz, latestBaz.get()); + } + } + + @Test + void basicSplitBehaviorTest() { + final Random random = getRandomPrintSeed(); + + final PlatformContext platformContext = + TestPlatformContextBuilder.create().build(); + final WiringModel model = WiringModelBuilder.create(platformContext).build(); + + final ComponentWiring>> wiring = + new ComponentWiring<>(model, TestListComponent.class, DIRECT_CONFIGURATION); + + wiring.bind(new TestListComponentImpl()); + + final AtomicLong latestFoo = new AtomicLong(); + final AtomicLong latestBar = new AtomicLong(); + final AtomicBoolean latestBaz = new AtomicBoolean(); + + final OutputWire fooOutput = wiring.getSplitAndRoutedOutput(TestDataType.FOO); + final OutputWire barOutput = wiring.getSplitAndRoutedOutput(TestDataType.BAR); + final OutputWire bazOutput = wiring.getSplitAndRoutedOutput(TestDataType.BAZ); + + fooOutput.solderTo("fooHandler", "fooInput", latestFoo::getAndAdd); + barOutput.solderTo("barHandler", "barInput", latestBar::getAndAdd); + bazOutput.solderTo("bazHandler", "bazInput", latestBaz::set); + + long expectedFoo = 0; + long expectedBar = 0; + boolean expectedBaz = false; + + // Intentional: we have to create all wires prior to starting the model + wiring.getInputWire(TestListComponent::doWork); + + model.start(); + + for (int i = 0; i < 1000; i++) { + final int value = random.nextInt(); + + if (value % 3 == 0) { + expectedFoo += value; + } else if (value % 3 == 1) { + expectedBar += value; + } else { + expectedBaz = value % 2 == 0; + } + + if (value % 2 == 0) { + expectedFoo += value / 2; + } else { + expectedBar += value / 2; + } + + if (value % 5 == 0) { + expectedFoo += value / 5; + } + + wiring.getInputWire(TestListComponent::doWork).put(value); + + assertEquals(expectedFoo, latestFoo.get()); + assertEquals(expectedBar, latestBar.get()); + assertEquals(expectedBaz, latestBaz.get()); + } + } + + /** + * It is not allowed to create multiple routers with different enum types from the same component. + */ + @Test + void multipleRoutersForbiddenTest() { + final PlatformContext platformContext = + TestPlatformContextBuilder.create().build(); + final WiringModel model = WiringModelBuilder.create(platformContext).build(); + + final ComponentWiring> wiring = + new ComponentWiring<>(model, TestComponent.class, DIRECT_CONFIGURATION); + + wiring.getRoutedOutput(TestDataType.FOO); + + assertThrows(IllegalArgumentException.class, () -> wiring.getRoutedOutput(TestDataType2.FOO)); + } + + /** + * It is not allowed to create multiple routers with different enum types from the same component. + */ + @Test + void multipleSplitRoutersForbiddenTest() { + final PlatformContext platformContext = + TestPlatformContextBuilder.create().build(); + final WiringModel model = WiringModelBuilder.create(platformContext).build(); + + final ComponentWiring> wiring = + new ComponentWiring<>(model, TestListComponent.class, DIRECT_CONFIGURATION); + + wiring.getRoutedOutput(TestDataType.FOO); + + assertThrows(IllegalArgumentException.class, () -> wiring.getRoutedOutput(TestDataType2.FOO)); + } + + /** + * We shouldn't be able to create a router that uses unsplit data, followed by creating a router that uses split + * data. + */ + @Test + void unsplitThenSplitRoutersForbiddenTest() { + final PlatformContext platformContext = + TestPlatformContextBuilder.create().build(); + final WiringModel model = WiringModelBuilder.create(platformContext).build(); + + final ComponentWiring> wiring = + new ComponentWiring<>(model, TestComponent.class, DIRECT_CONFIGURATION); + + wiring.getRoutedOutput(TestDataType.FOO); + + assertThrows(IllegalStateException.class, () -> wiring.getSplitAndRoutedOutput(TestDataType2.FOO)); + } + + /** + * We shouldn't be able to create a router that uses split data, followed by creating a router that uses unsplit + * data. + */ + @Test + void splitThenUnsplitRoutersForbiddenTest() { + final PlatformContext platformContext = + TestPlatformContextBuilder.create().build(); + final WiringModel model = WiringModelBuilder.create(platformContext).build(); + + final ComponentWiring> wiring = + new ComponentWiring<>(model, TestListComponent.class, DIRECT_CONFIGURATION); + + wiring.getSplitAndRoutedOutput(TestDataType.FOO); + + assertThrows(IllegalStateException.class, () -> wiring.getRoutedOutput(TestDataType2.FOO)); + } +} diff --git a/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/component/ComponentWiringTests.java b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/component/ComponentWiringTests.java new file mode 100644 index 00000000000..b6f5fcc1fec --- /dev/null +++ b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/component/ComponentWiringTests.java @@ -0,0 +1,537 @@ +/* + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC + * + * 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 org.hiero.wiring.framework.component; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import com.swirlds.common.context.PlatformContext; +import com.swirlds.common.test.fixtures.platform.TestPlatformContextBuilder; +import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.atomic.AtomicReference; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.model.WiringModelBuilder; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerConfiguration; +import org.hiero.wiring.framework.wires.input.InputWire; +import org.hiero.wiring.framework.wires.output.OutputWire; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +public class ComponentWiringTests { + + private interface FooBarBaz { + @NonNull + Long handleFoo(@NonNull Integer foo); + + @InputWireLabel("bar") + @NonNull + Long handleBar(@NonNull Boolean bar); + + void handleBaz(@NonNull String baz); + + @InputWireLabel("trigger") + @NonNull + Long triggerQux(); + + void triggerCorge(); + + @InputWireLabel("data to be transformed") + @SchedulerLabel("transformer") + @NonNull + default String transformer(@NonNull final Long baseOutput) { + handleBar(true); + return "" + baseOutput; + } + + @InputWireLabel("data to be filtered") + @SchedulerLabel("filter") + default Boolean filter(@NonNull final Long baseOutput) { + return baseOutput % 2 == 0; + } + } + + private static class FooBarBazImpl implements FooBarBaz { + private long runningValue = 0; + + @Override + @NonNull + public Long handleFoo(@NonNull final Integer foo) { + runningValue += foo; + return runningValue; + } + + @Override + @NonNull + public Long handleBar(@NonNull final Boolean bar) { + runningValue *= bar ? 1 : -1; + return runningValue; + } + + @Override + public void handleBaz(@NonNull final String baz) { + runningValue *= baz.hashCode(); + } + + @Override + @NonNull + public Long triggerQux() { + runningValue -= 1; + return runningValue; + } + + @Override + public void triggerCorge() { + runningValue *= 1.5; + } + + public long getRunningValue() { + return runningValue; + } + } + + @SchedulerLabel("actuallyCallThisSomethingDifferent") + private interface ComponentWithListOutput { + @NonNull + List handleInputA(@NonNull String s); + + @NonNull + List handleInputB(@NonNull Long l); + + @NonNull + default Boolean filter(@NonNull final String baseOutput) { + return baseOutput.hashCode() % 2 == 0; + } + + @NonNull + default String transformer(@NonNull final String baseOutput) { + return "(" + baseOutput + ")"; + } + } + + private static class ComponentWithListOutputImpl implements ComponentWithListOutput { + + @NonNull + @Override + public List handleInputA(@NonNull final String s) { + return List.of(s.split("")); + } + + @NonNull + @Override + public List handleInputB(@NonNull final Long l) { + final String s = l.toString(); + // return a list of characters + return List.of(s.split("")); + } + } + + /** + * The framework should not permit methods that aren't on the component to be wired. + */ + @Test + void methodNotOnComponentTest() { + final PlatformContext platformContext = + TestPlatformContextBuilder.create().build(); + + final WiringModel wiringModel = + WiringModelBuilder.create(platformContext).build(); + + final TaskSchedulerConfiguration schedulerConfiguration = TaskSchedulerConfiguration.parse("DIRECT"); + + final ComponentWiring fooBarBazWiring = + new ComponentWiring<>(wiringModel, FooBarBaz.class, schedulerConfiguration); + assertEquals("FooBarBaz", fooBarBazWiring.getSchedulerName()); + + assertThrows(IllegalArgumentException.class, () -> fooBarBazWiring.getInputWire((x, y) -> 0L)); + assertThrows(IllegalArgumentException.class, () -> fooBarBazWiring.getInputWire((x, y) -> {})); + assertThrows(IllegalArgumentException.class, () -> fooBarBazWiring.getInputWire((x) -> 1L)); + assertThrows(IllegalArgumentException.class, () -> fooBarBazWiring.getInputWire((x) -> {})); + assertThrows(IllegalArgumentException.class, () -> fooBarBazWiring.getTransformedOutput((x, y) -> 0L)); + } + + @ParameterizedTest + @ValueSource(ints = {0, 1, 2, 3}) + void simpleComponentTest(final int bindLocation) { + final PlatformContext platformContext = + TestPlatformContextBuilder.create().build(); + + final WiringModel wiringModel = + WiringModelBuilder.create(platformContext).build(); + + final TaskSchedulerConfiguration schedulerConfiguration = TaskSchedulerConfiguration.parse("DIRECT"); + + final ComponentWiring fooBarBazWiring = + new ComponentWiring<>(wiringModel, FooBarBaz.class, schedulerConfiguration); + assertEquals("FooBarBaz", fooBarBazWiring.getSchedulerName()); + + final FooBarBazImpl fooBarBazImpl = new FooBarBazImpl(); + + if (bindLocation == 0) { + fooBarBazWiring.bind(fooBarBazImpl); + } + + final InputWire fooInput = fooBarBazWiring.getInputWire(FooBarBaz::handleFoo); + assertEquals("handleFoo", fooInput.getName()); + final InputWire barInput = fooBarBazWiring.getInputWire(FooBarBaz::handleBar); + assertEquals("bar", barInput.getName()); + + if (bindLocation == 1) { + fooBarBazWiring.bind(fooBarBazImpl); + } + + final InputWire bazInput = fooBarBazWiring.getInputWire(FooBarBaz::handleBaz); + assertEquals("handleBaz", bazInput.getName()); + final InputWire triggerQux = fooBarBazWiring.getInputWire(FooBarBaz::triggerQux); + assertEquals("trigger", triggerQux.getName()); + final InputWire triggerCorge = fooBarBazWiring.getInputWire(FooBarBaz::triggerCorge); + assertEquals("triggerCorge", triggerCorge.getName()); + + final OutputWire output = fooBarBazWiring.getOutputWire(); + + if (bindLocation == 2) { + fooBarBazWiring.bind(fooBarBazImpl); + } + + final AtomicLong outputValue = new AtomicLong(); + output.solderTo("outputHandler", "output", outputValue::set); + + // Getting the same input wire multiple times should yield the same instance + assertSame(fooInput, fooBarBazWiring.getInputWire(FooBarBaz::handleFoo)); + assertSame(barInput, fooBarBazWiring.getInputWire(FooBarBaz::handleBar)); + assertSame(bazInput, fooBarBazWiring.getInputWire(FooBarBaz::handleBaz)); + assertSame(triggerQux, fooBarBazWiring.getInputWire(FooBarBaz::triggerQux)); + assertSame(triggerCorge, fooBarBazWiring.getInputWire(FooBarBaz::triggerCorge)); + + // Getting the output wire multiple times should yield the same instance + assertSame(output, fooBarBazWiring.getOutputWire()); + + if (bindLocation == 3) { + fooBarBazWiring.bind(fooBarBazImpl); + } + + long expectedRunningValue = 0; + for (int i = 0; i < 1000; i++) { + if (i % 5 == 0) { + expectedRunningValue += i; + fooInput.put(i); + assertEquals(expectedRunningValue, fooBarBazImpl.getRunningValue()); + assertEquals(expectedRunningValue, outputValue.get()); + } else if (i % 5 == 1) { + final boolean choice = i % 7 == 0; + expectedRunningValue *= choice ? 1 : -1; + barInput.put(choice); + assertEquals(expectedRunningValue, fooBarBazImpl.getRunningValue()); + assertEquals(expectedRunningValue, outputValue.get()); + } else if (i % 5 == 2) { + final String value = "value" + i; + expectedRunningValue *= value.hashCode(); + bazInput.put(value); + assertEquals(expectedRunningValue, fooBarBazImpl.getRunningValue()); + } else if (i % 5 == 3) { + expectedRunningValue -= 1; + triggerQux.put(null); + assertEquals(expectedRunningValue, fooBarBazImpl.getRunningValue()); + } else { + expectedRunningValue *= 1.5; + triggerCorge.put(null); + assertEquals(expectedRunningValue, fooBarBazImpl.getRunningValue()); + } + } + } + + @ParameterizedTest + @ValueSource(ints = {0, 1}) + void transformerTest(final int bindLocation) { + final PlatformContext platformContext = + TestPlatformContextBuilder.create().build(); + + final WiringModel wiringModel = + WiringModelBuilder.create(platformContext).build(); + + final TaskSchedulerConfiguration schedulerConfiguration = TaskSchedulerConfiguration.parse("DIRECT"); + + final FooBarBazImpl fooBarBazImpl = new FooBarBazImpl(); + + final ComponentWiring fooBarBazWiring = + new ComponentWiring<>(wiringModel, FooBarBaz.class, schedulerConfiguration); + assertEquals("FooBarBaz", fooBarBazWiring.getSchedulerName()); + + if (bindLocation == 0) { + fooBarBazWiring.bind(fooBarBazImpl); + } + + final InputWire fooInput = fooBarBazWiring.getInputWire(FooBarBaz::handleFoo); + final InputWire barInput = fooBarBazWiring.getInputWire(FooBarBaz::handleBar); + final InputWire bazInput = fooBarBazWiring.getInputWire(FooBarBaz::handleBaz); + final InputWire triggerQux = fooBarBazWiring.getInputWire(FooBarBaz::triggerQux); + final InputWire triggerCorge = fooBarBazWiring.getInputWire(FooBarBaz::triggerCorge); + + final OutputWire output = fooBarBazWiring.getTransformedOutput(FooBarBaz::transformer); + + // Getting the same transformer multiple times should yield the same instance + assertSame(output, fooBarBazWiring.getTransformedOutput(FooBarBaz::transformer)); + + if (bindLocation == 1) { + fooBarBazWiring.bind(fooBarBazImpl); + } + + final AtomicReference outputValue = new AtomicReference<>("0"); + output.solderTo("outputHandler", "output", outputValue::set); + + long expectedRunningValue = 0; + for (int i = 0; i < 1000; i++) { + if (i % 5 == 0) { + expectedRunningValue += i; + fooInput.put(i); + assertEquals(expectedRunningValue, fooBarBazImpl.getRunningValue()); + assertEquals("" + expectedRunningValue, outputValue.get()); + } else if (i % 5 == 1) { + final boolean choice = i % 7 == 0; + expectedRunningValue *= choice ? 1 : -1; + barInput.put(choice); + assertEquals(expectedRunningValue, fooBarBazImpl.getRunningValue()); + assertEquals("" + expectedRunningValue, outputValue.get()); + } else if (i % 5 == 2) { + final String value = "value" + i; + expectedRunningValue *= value.hashCode(); + bazInput.put(value); + assertEquals(expectedRunningValue, fooBarBazImpl.getRunningValue()); + } else if (i % 5 == 3) { + expectedRunningValue -= 1; + triggerQux.put(null); + assertEquals(expectedRunningValue, fooBarBazImpl.getRunningValue()); + assertEquals("" + expectedRunningValue, outputValue.get()); + } else { + expectedRunningValue *= 1.5; + triggerCorge.put(null); + assertEquals(expectedRunningValue, fooBarBazImpl.getRunningValue()); + } + } + } + + @ParameterizedTest + @ValueSource(ints = {0, 1}) + void filterTest(final int bindLocation) { + final PlatformContext platformContext = + TestPlatformContextBuilder.create().build(); + + final WiringModel wiringModel = + WiringModelBuilder.create(platformContext).build(); + + final TaskSchedulerConfiguration schedulerConfiguration = TaskSchedulerConfiguration.parse("DIRECT"); + + final FooBarBazImpl fooBarBazImpl = new FooBarBazImpl(); + + final ComponentWiring fooBarBazWiring = + new ComponentWiring<>(wiringModel, FooBarBaz.class, schedulerConfiguration); + assertEquals("FooBarBaz", fooBarBazWiring.getSchedulerName()); + + if (bindLocation == 0) { + fooBarBazWiring.bind(fooBarBazImpl); + } + + final InputWire fooInput = fooBarBazWiring.getInputWire(FooBarBaz::handleFoo); + final InputWire barInput = fooBarBazWiring.getInputWire(FooBarBaz::handleBar); + final InputWire bazInput = fooBarBazWiring.getInputWire(FooBarBaz::handleBaz); + final InputWire triggerQux = fooBarBazWiring.getInputWire(FooBarBaz::triggerQux); + final InputWire triggerCorge = fooBarBazWiring.getInputWire(FooBarBaz::triggerCorge); + + final OutputWire output = fooBarBazWiring.getFilteredOutput(FooBarBaz::filter); + + // Getting the same filter multiple times should yield the same instance + assertSame(output, fooBarBazWiring.getFilteredOutput(FooBarBaz::filter)); + + if (bindLocation == 1) { + fooBarBazWiring.bind(fooBarBazImpl); + } + + final AtomicReference outputValue = new AtomicReference<>(); + output.solderTo("outputHandler", "output", outputValue::set); + + long expectedRunningValue = 0; + for (int i = 0; i < 1000; i++) { + outputValue.set(null); + if (i % 5 == 0) { + expectedRunningValue += i; + fooInput.put(i); + assertEquals(expectedRunningValue, fooBarBazImpl.getRunningValue()); + final Long expectedValue = expectedRunningValue % 2 == 0 ? expectedRunningValue : null; + assertEquals(expectedValue, outputValue.get()); + } else if (i % 5 == 1) { + final boolean choice = i % 7 == 0; + expectedRunningValue *= choice ? 1 : -1; + barInput.put(choice); + final Long expectedValue = expectedRunningValue % 2 == 0 ? expectedRunningValue : null; + assertEquals(expectedValue, outputValue.get()); + } else if (i % 5 == 2) { + final String value = "value" + i; + expectedRunningValue *= value.hashCode(); + bazInput.put(value); + assertEquals(expectedRunningValue, fooBarBazImpl.getRunningValue()); + } else if (i % 5 == 3) { + expectedRunningValue -= 1; + triggerQux.put(null); + final Long expectedValue = expectedRunningValue % 2 == 0 ? expectedRunningValue : null; + assertEquals(expectedValue, outputValue.get()); + } else { + expectedRunningValue *= 1.5; + triggerCorge.put(null); + assertEquals(expectedRunningValue, fooBarBazImpl.getRunningValue()); + } + } + } + + @ParameterizedTest + @ValueSource(ints = {0, 1}) + void splitterTest(final int bindLocation) { + final PlatformContext platformContext = + TestPlatformContextBuilder.create().build(); + + final WiringModel wiringModel = + WiringModelBuilder.create(platformContext).build(); + + final TaskSchedulerConfiguration schedulerConfiguration = TaskSchedulerConfiguration.parse("DIRECT"); + + final ComponentWiring> componentWiring = + new ComponentWiring<>(wiringModel, ComponentWithListOutput.class, schedulerConfiguration); + assertEquals("actuallyCallThisSomethingDifferent", componentWiring.getSchedulerName()); + + if (bindLocation == 0) { + componentWiring.bind(new ComponentWithListOutputImpl()); + } + + final OutputWire splitOutput = componentWiring.getSplitOutput(); + assertSame(splitOutput, componentWiring.getSplitOutput()); + + final List outputData = new ArrayList<>(); + splitOutput.solderTo("addToOutputData", "split data", outputData::add); + + final List expectedOutputData = new ArrayList<>(); + + if (bindLocation == 1) { + componentWiring.bind(new ComponentWithListOutputImpl()); + } + + componentWiring.getInputWire(ComponentWithListOutput::handleInputA).put("hello world"); + expectedOutputData.addAll(List.of("h", "e", "l", "l", "o", " ", "w", "o", "r", "l", "d")); + + componentWiring.getInputWire(ComponentWithListOutput::handleInputB).put(123L); + expectedOutputData.addAll(List.of("1", "2", "3")); + + assertEquals(expectedOutputData, outputData); + } + + @ParameterizedTest + @ValueSource(ints = {0, 1}) + void filteredSplitterTest(final int bindLocation) { + final PlatformContext platformContext = + TestPlatformContextBuilder.create().build(); + + final WiringModel wiringModel = + WiringModelBuilder.create(platformContext).build(); + + final TaskSchedulerConfiguration schedulerConfiguration = TaskSchedulerConfiguration.parse("DIRECT"); + + final ComponentWiring> componentWiring = + new ComponentWiring<>(wiringModel, ComponentWithListOutput.class, schedulerConfiguration); + assertEquals("actuallyCallThisSomethingDifferent", componentWiring.getSchedulerName()); + + if (bindLocation == 0) { + componentWiring.bind(new ComponentWithListOutputImpl()); + } + + final OutputWire filteredOutput = + componentWiring.getSplitAndFilteredOutput(ComponentWithListOutput::filter); + assertSame(filteredOutput, componentWiring.getSplitAndFilteredOutput(ComponentWithListOutput::filter)); + + final List outputData = new ArrayList<>(); + filteredOutput.solderTo("addToOutputData", "split data", outputData::add); + + final List expectedOutputData = new ArrayList<>(); + + if (bindLocation == 1) { + componentWiring.bind(new ComponentWithListOutputImpl()); + } + + componentWiring.getInputWire(ComponentWithListOutput::handleInputA).put("hello world"); + for (final String s : "hello world".split("")) { + if (s.hashCode() % 2 == 0) { + expectedOutputData.add(s); + } + } + + componentWiring.getInputWire(ComponentWithListOutput::handleInputB).put(123L); + for (final String s : "123".split("")) { + if (s.hashCode() % 2 == 0) { + expectedOutputData.add(s); + } + } + + assertEquals(expectedOutputData, outputData); + } + + @ParameterizedTest + @ValueSource(ints = {0, 1}) + void transformedSplitterTest(final int bindLocation) { + final PlatformContext platformContext = + TestPlatformContextBuilder.create().build(); + + final WiringModel wiringModel = + WiringModelBuilder.create(platformContext).build(); + + final TaskSchedulerConfiguration schedulerConfiguration = TaskSchedulerConfiguration.parse("DIRECT"); + + final ComponentWiring> componentWiring = + new ComponentWiring<>(wiringModel, ComponentWithListOutput.class, schedulerConfiguration); + assertEquals("actuallyCallThisSomethingDifferent", componentWiring.getSchedulerName()); + + if (bindLocation == 0) { + componentWiring.bind(new ComponentWithListOutputImpl()); + } + + final OutputWire transformedOutput = + componentWiring.getSplitAndTransformedOutput(ComponentWithListOutput::transformer); + assertSame( + transformedOutput, componentWiring.getSplitAndTransformedOutput(ComponentWithListOutput::transformer)); + + final List outputData = new ArrayList<>(); + transformedOutput.solderTo("addToOutputData", "split data", outputData::add); + + final List expectedOutputData = new ArrayList<>(); + + if (bindLocation == 1) { + componentWiring.bind(new ComponentWithListOutputImpl()); + } + + componentWiring.getInputWire(ComponentWithListOutput::handleInputA).put("hello world"); + for (final String s : "hello world".split("")) { + expectedOutputData.add("(" + s + ")"); + } + + componentWiring.getInputWire(ComponentWithListOutput::handleInputB).put(123L); + for (final String s : "123".split("")) { + expectedOutputData.add("(" + s + ")"); + } + + assertEquals(expectedOutputData, outputData); + } +} diff --git a/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/component/WiringComponentPerformanceTests.java b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/component/WiringComponentPerformanceTests.java new file mode 100644 index 00000000000..4edff729197 --- /dev/null +++ b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/component/WiringComponentPerformanceTests.java @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC + * + * 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 org.hiero.wiring.framework.component; + +import com.swirlds.common.test.fixtures.platform.TestPlatformContextBuilder; +import edu.umd.cs.findbugs.annotations.NonNull; +import java.time.Duration; +import java.time.Instant; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.model.WiringModelBuilder; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.wires.input.BindableInputWire; +import org.hiero.wiring.framework.wires.input.InputWire; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; + +@Disabled // Do not merge with this class enabled +class WiringComponentPerformanceTests { + + private interface SimpleComponent { + void handleInput(@NonNull Long input); + } + + private static class SimpleComponentImpl implements SimpleComponent { + private long runningValue = 0; + + @Override + public void handleInput(@NonNull final Long input) { + runningValue += input; + } + + public long getRunningValue() { + return runningValue; + } + } + + @NonNull + private InputWire buildOldStyleComponent(@NonNull final SimpleComponent component) { + final WiringModel model = WiringModelBuilder.create( + TestPlatformContextBuilder.create().build()) + .build(); + + final TaskScheduler scheduler = model.schedulerBuilder("test") + .withType(TaskSchedulerType.DIRECT) + .build(); + + final BindableInputWire inputWire = scheduler.buildInputWire("input"); + inputWire.bindConsumer(component::handleInput); + + return inputWire; + } + + @NonNull + private InputWire buildAutomaticComponent(@NonNull final SimpleComponent component) { + + final WiringModel model = WiringModelBuilder.create( + TestPlatformContextBuilder.create().build()) + .build(); + + final TaskScheduler scheduler = model.schedulerBuilder("test") + .withType(TaskSchedulerType.DIRECT) + .build() + .cast(); + + final ComponentWiring componentWiring = + new ComponentWiring<>(model, SimpleComponent.class, scheduler); + final InputWire inputWire = componentWiring.getInputWire(SimpleComponent::handleInput); + componentWiring.bind(component); + + return inputWire; + } + + // When testing locally on my macbook (m1), the old style component took 0.76s to run 100,000,000 iterations, + // and the automatic component took 0.79s to run 100,000,000 iterations. + + @Test + void oldStylePerformanceTest() { + final long iterations = 100_000_000; + + final SimpleComponentImpl component = new SimpleComponentImpl(); + final InputWire inputWire = buildOldStyleComponent(component); + + final Instant start = Instant.now(); + + for (long i = 0; i < iterations; i++) { + inputWire.put(i); + } + + final Instant end = Instant.now(); + final Duration duration = Duration.between(start, end); + System.out.println("Time required: " + duration.toMillis() + "ms"); + + // Just in case the compiler wants to get cheeky and avoid doing computation + System.out.println("value = " + component.getRunningValue()); + } + + @Test + void automaticComponentPerformanceTest() { + final long iterations = 100_000_000; + + final SimpleComponentImpl component = new SimpleComponentImpl(); + final InputWire inputWire = buildAutomaticComponent(component); + + final Instant start = Instant.now(); + + for (long i = 0; i < iterations; i++) { + inputWire.put(i); + } + + final Instant end = Instant.now(); + final Duration duration = Duration.between(start, end); + System.out.println("Time required: " + duration.toMillis() + "ms"); + + // Just in case the compiler wants to get cheeky and avoid doing computation + System.out.println("value = " + component.getRunningValue()); + } +} diff --git a/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/counters/BackpressureObjectCounterTests.java b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/counters/BackpressureObjectCounterTests.java new file mode 100644 index 00000000000..63b4b52a1ff --- /dev/null +++ b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/counters/BackpressureObjectCounterTests.java @@ -0,0 +1,289 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 org.hiero.wiring.framework.counters; + +import static com.swirlds.common.test.fixtures.AssertionUtils.assertEventuallyEquals; +import static com.swirlds.common.test.fixtures.AssertionUtils.assertEventuallyTrue; +import static com.swirlds.common.test.fixtures.RandomUtils.getRandomPrintSeed; +import static com.swirlds.common.threading.manager.AdHocThreadManager.getStaticThreadManager; +import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import com.swirlds.common.threading.framework.config.ThreadConfiguration; +import java.time.Duration; +import java.util.Random; +import java.util.concurrent.ForkJoinPool; +import java.util.concurrent.ForkJoinPool.ManagedBlocker; +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +class BackpressureObjectCounterTests { + + /** + * Choose a capacity that is sufficiently high as to never trigger. Validate that the counting part of this + * implementation works as expected. + */ + @Test + void countWithHighCapacityTest() { + final Random random = getRandomPrintSeed(); + + final ObjectCounter counter = new BackpressureObjectCounter("test", 1_000_000_000, Duration.ofMillis(1)); + + int count = 0; + for (int i = 0; i < 1000; i++) { + + final boolean increment = count == 0 || random.nextBoolean(); + + if (increment) { + count++; + + // All of these methods are logically equivalent with current capacity. + final int choice = random.nextInt(3); + switch (choice) { + case 0 -> counter.onRamp(); + case 1 -> counter.attemptOnRamp(); + case 2 -> counter.forceOnRamp(); + default -> throw new IllegalStateException("Unexpected value: " + choice); + } + + } else { + count--; + counter.offRamp(); + } + + assertEquals(count, counter.getCount()); + } + } + + @ParameterizedTest + @ValueSource(ints = {0, 1}) + void onRampTest(final int sleepMillis) throws InterruptedException { + final Duration sleepDuration = Duration.ofMillis(sleepMillis); + + final ObjectCounter counter = new BackpressureObjectCounter("test", 10, sleepDuration); + + // Fill up the counter to capacity + for (int i = 0; i < 10; i++) { + counter.onRamp(); + } + + assertEquals(10, counter.getCount()); + + // Attempt to add one more, should block. + final AtomicBoolean added = new AtomicBoolean(false); + final AtomicReference interrupted = new AtomicReference<>(); + final Thread thread = new ThreadConfiguration(getStaticThreadManager()) + .setRunnable(() -> { + counter.onRamp(); + added.set(true); + + interrupted.set(Thread.currentThread().isInterrupted()); + }) + .build(true); + + assertEquals(10, counter.getCount()); + + // Sleep for a little while. Thread should be unable to on ramp another element. + // Count can briefly overflow to 11, but should quickly return to 10. + MILLISECONDS.sleep(50); + final long count1 = counter.getCount(); + assertTrue(count1 == 10 || count1 == 11, "unexpected count " + count1); + + // Interrupting the thread should not unblock us. + thread.interrupt(); + MILLISECONDS.sleep(50); + // Count can briefly overflow to 11, but should quickly return to 10. + final long count2 = counter.getCount(); + assertTrue(count2 == 10 || count2 == 11, "unexpected count " + count2); + + // Off ramp one element. Thread should become unblocked. + counter.offRamp(); + + assertEventuallyTrue(added::get, Duration.ofSeconds(10), "Thread should have been unblocked"); + + // even though the interrupt did not unblock the thread, the interrupt should not have been squelched. + assertEventuallyEquals(true, interrupted::get, Duration.ofSeconds(10), "Thread should have been interrupted"); + + assertEquals(10, counter.getCount()); + } + + @Test + void attemptOnRampTest() { + final ObjectCounter counter = new BackpressureObjectCounter("test", 10, Duration.ofMillis(1)); + + // Fill up the counter to capacity + for (int i = 0; i < 10; i++) { + assertTrue(counter.attemptOnRamp()); + } + + assertEquals(10, counter.getCount()); + + // Attempt to add one more, should block immediately fail and return false. + assertFalse(counter.attemptOnRamp()); + + assertEquals(10, counter.getCount()); + } + + @Test + void forceOnRampTest() { + final ObjectCounter counter = new BackpressureObjectCounter("test", 10, Duration.ofMillis(1)); + + // Fill up the counter to capacity + for (int i = 0; i < 10; i++) { + counter.forceOnRamp(); + } + + assertEquals(10, counter.getCount()); + + // Attempt to add one more, should work even though it violates capacity restrictions + counter.forceOnRamp(); + + assertEquals(11, counter.getCount()); + } + + @Test + void waitUntilEmptyTest() throws InterruptedException { + final ObjectCounter counter = new BackpressureObjectCounter("test", 1000, Duration.ofMillis(1)); + + for (int i = 0; i < 100; i++) { + counter.onRamp(); + } + + final AtomicBoolean empty = new AtomicBoolean(false); + final Thread thread = new ThreadConfiguration(getStaticThreadManager()) + .setRunnable(() -> { + counter.waitUntilEmpty(); + empty.set(true); + }) + .build(true); + + // Should be blocked. + MILLISECONDS.sleep(50); + assertFalse(empty.get()); + + // Draining most of the things from the counter should still block. + for (int i = 0; i < 90; i++) { + counter.offRamp(); + } + MILLISECONDS.sleep(50); + assertFalse(empty.get()); + + // Interrupting the thread should have no effect. + thread.interrupt(); + MILLISECONDS.sleep(50); + assertFalse(empty.get()); + + // Removing remaining things from the counter should unblock. + for (int i = 0; i < 10; i++) { + counter.offRamp(); + } + + assertEventuallyTrue(empty::get, Duration.ofSeconds(10), "Counter did not empty in time."); + } + + /** + * If the fork join pool runs out of threads, back pressure should handle the situation gracefully. + */ + @Test + void backpressureDoesntOverwhelmForkJoinPool() throws InterruptedException { + + final int maxPoolSize = 10; + final ForkJoinPool pool = new ForkJoinPool( + 5, + ForkJoinPool.defaultForkJoinWorkerThreadFactory, + null, + false, + 0, + maxPoolSize, + 1, + null, + 60, + TimeUnit.SECONDS); + + final AtomicBoolean blocked = new AtomicBoolean(true); + final ManagedBlocker dummyBlocker = new ManagedBlocker() { + @Override + public boolean block() throws InterruptedException { + MILLISECONDS.sleep(1); + return false; + } + + @Override + public boolean isReleasable() { + return !blocked.get(); + } + }; + + // Keep submitting managed blockers until the fork join pool taps out. + final AtomicBoolean poolIsSaturated = new AtomicBoolean(false); + for (int i = 0; i < maxPoolSize; i++) { + pool.submit(() -> { + int tries = 1000; + while (tries-- > 0) { + try { + ForkJoinPool.managedBlock(dummyBlocker); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } catch (final RejectedExecutionException ex) { + poolIsSaturated.set(true); + } + } + }); + } + + assertEventuallyTrue(poolIsSaturated::get, Duration.ofSeconds(10), "Fork join pool did not saturate in time."); + + // Now, see if a backpressure counter can block without throwing. + + final ObjectCounter counter = new BackpressureObjectCounter("test", 1, Duration.ofMillis(1)); + counter.onRamp(); + + final AtomicBoolean taskCompleted = new AtomicBoolean(false); + final AtomicBoolean exceptionThrown = new AtomicBoolean(false); + pool.submit(() -> { + + // This should block until we off ramp. + try { + counter.onRamp(); + } catch (final Throwable t) { + exceptionThrown.set(true); + return; + } + + taskCompleted.set(true); + }); + + // Sleep for a while, the task should not be able to complete. + MILLISECONDS.sleep(50); + assertFalse(taskCompleted.get()); + assertFalse(exceptionThrown.get()); + + // Unblock the counter, the task should complete. + counter.offRamp(); + assertEventuallyTrue(taskCompleted::get, Duration.ofSeconds(10), "Task did not complete in time."); + assertFalse(exceptionThrown.get()); + + pool.shutdown(); + } +} diff --git a/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/counters/MultiObjectCounterTests.java b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/counters/MultiObjectCounterTests.java new file mode 100644 index 00000000000..78e518657a0 --- /dev/null +++ b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/counters/MultiObjectCounterTests.java @@ -0,0 +1,182 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 org.hiero.wiring.framework.counters; + +import static com.swirlds.common.test.fixtures.AssertionUtils.assertEventuallyTrue; +import static com.swirlds.common.test.fixtures.RandomUtils.getRandomPrintSeed; +import static com.swirlds.common.threading.manager.AdHocThreadManager.getStaticThreadManager; +import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; + +import com.swirlds.common.threading.framework.config.ThreadConfiguration; +import java.time.Duration; +import java.util.Random; +import java.util.concurrent.atomic.AtomicBoolean; +import org.junit.jupiter.api.Test; + +class MultiObjectCounterTests { + + @Test + void onRampOffRampTest() { + final Random random = getRandomPrintSeed(); + + final ObjectCounter counterA = new StandardObjectCounter(Duration.ofSeconds(1)); + final ObjectCounter counterB = new StandardObjectCounter(Duration.ofSeconds(1)); + final ObjectCounter counterC = new StandardObjectCounter(Duration.ofSeconds(1)); + + final MultiObjectCounter counter = new MultiObjectCounter(counterA, counterB, counterC); + + int expectedCount = 0; + for (int i = 0; i < 1000; i++) { + + if (expectedCount == 0 || random.nextDouble() < 0.75) { + counter.onRamp(); + expectedCount++; + } else { + counter.offRamp(); + expectedCount--; + } + + assertEquals(expectedCount, counter.getCount()); + assertEquals(expectedCount, counterA.getCount()); + assertEquals(expectedCount, counterB.getCount()); + assertEquals(expectedCount, counterC.getCount()); + } + } + + @Test + void attemptOnRampTest() { + final Random random = getRandomPrintSeed(); + + // When attempting an on ramp, only the first counter's capacity should be consulted. + + final ObjectCounter counterA = new BackpressureObjectCounter("test", 10, Duration.ofSeconds(1)); + final ObjectCounter counterB = new BackpressureObjectCounter("test", 5, Duration.ofSeconds(1)); + final ObjectCounter counterC = new StandardObjectCounter(Duration.ofSeconds(1)); + + final MultiObjectCounter counter = new MultiObjectCounter(counterA, counterB, counterC); + + int expectedCount = 0; + for (int i = 0; i < 1000; i++) { + if (expectedCount == 0 || random.nextDouble() < 0.75) { + if (counter.attemptOnRamp()) { + expectedCount++; + } + } else { + counter.offRamp(); + expectedCount--; + } + + assertEquals(expectedCount, counter.getCount()); + assertEquals(expectedCount, counterA.getCount()); + assertEquals(expectedCount, counterB.getCount()); + assertEquals(expectedCount, counterC.getCount()); + } + } + + @Test + void forceOnRampTest() { + final Random random = getRandomPrintSeed(); + + // When attempting an on ramp, only the first counter's capacity should be consulted. + + final ObjectCounter counterA = new BackpressureObjectCounter("test", 10, Duration.ofSeconds(1)); + final ObjectCounter counterB = new BackpressureObjectCounter("test", 5, Duration.ofSeconds(1)); + final ObjectCounter counterC = new StandardObjectCounter(Duration.ofSeconds(1)); + + final MultiObjectCounter counter = new MultiObjectCounter(counterA, counterB, counterC); + + int expectedCount = 0; + for (int i = 0; i < 1000; i++) { + if (expectedCount == 0 || random.nextDouble() < 0.75) { + counter.forceOnRamp(); + expectedCount++; + } else { + counter.offRamp(); + expectedCount--; + } + + assertEquals(expectedCount, counter.getCount()); + assertEquals(expectedCount, counterA.getCount()); + assertEquals(expectedCount, counterB.getCount()); + assertEquals(expectedCount, counterC.getCount()); + } + } + + @Test + void waitUntilEmptyTest() throws InterruptedException { + final ObjectCounter counterA = new BackpressureObjectCounter("test", 10, Duration.ofSeconds(1)); + final ObjectCounter counterB = new BackpressureObjectCounter("test", 5, Duration.ofSeconds(1)); + final ObjectCounter counterC = new StandardObjectCounter(Duration.ofSeconds(1)); + + final MultiObjectCounter counter = new MultiObjectCounter(counterA, counterB, counterC); + + for (int i = 0; i < 100; i++) { + counter.forceOnRamp(); + } + + counterB.forceOnRamp(); + + counterC.forceOnRamp(); + counterC.forceOnRamp(); + + final AtomicBoolean empty = new AtomicBoolean(false); + final Thread thread = new ThreadConfiguration(getStaticThreadManager()) + .setRunnable(() -> { + counter.waitUntilEmpty(); + empty.set(true); + }) + .build(true); + + // Should be blocked. + MILLISECONDS.sleep(50); + assertFalse(empty.get()); + + // Draining most of the things from the counter should still block. + for (int i = 0; i < 90; i++) { + counter.offRamp(); + } + MILLISECONDS.sleep(50); + assertFalse(empty.get()); + + // Interrupting the thread should have no effect. + thread.interrupt(); + MILLISECONDS.sleep(50); + assertFalse(empty.get()); + + // Remove enough things so that counterA is unblocked. + for (int i = 0; i < 10; i++) { + counter.offRamp(); + } + + MILLISECONDS.sleep(50); + assertFalse(empty.get()); + + // Reduce counter B to zero. + counterB.offRamp(); + + MILLISECONDS.sleep(50); + assertFalse(empty.get()); + + // Finally, remove all elements from counter C. + counterC.offRamp(); + counterC.offRamp(); + + assertEventuallyTrue(empty::get, Duration.ofSeconds(1), "Counter did not empty in time."); + } +} diff --git a/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/counters/NoOpObjectCounterTests.java b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/counters/NoOpObjectCounterTests.java new file mode 100644 index 00000000000..fb580471808 --- /dev/null +++ b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/counters/NoOpObjectCounterTests.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 org.hiero.wiring.framework.counters; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +class NoOpObjectCounterTests { + + /** + * The most important part of the no-op implementation is that it doesn't throw exceptions. + */ + @Test + void noThrowingTest() { + final NoOpObjectCounter counter = NoOpObjectCounter.getInstance(); + + counter.onRamp(); + counter.attemptOnRamp(); + counter.forceOnRamp(); + counter.offRamp(); + counter.waitUntilEmpty(); + assertEquals(-1, counter.getCount()); + } +} diff --git a/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/counters/StandardObjectCounterTests.java b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/counters/StandardObjectCounterTests.java new file mode 100644 index 00000000000..91d99833247 --- /dev/null +++ b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/counters/StandardObjectCounterTests.java @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 org.hiero.wiring.framework.counters; + +import static com.swirlds.common.test.fixtures.AssertionUtils.assertEventuallyTrue; +import static com.swirlds.common.test.fixtures.RandomUtils.getRandomPrintSeed; +import static com.swirlds.common.threading.manager.AdHocThreadManager.getStaticThreadManager; +import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; + +import com.swirlds.common.threading.framework.config.ThreadConfiguration; +import java.time.Duration; +import java.util.Random; +import java.util.concurrent.atomic.AtomicBoolean; +import org.junit.jupiter.api.Test; + +class StandardObjectCounterTests { + + @Test + void basicOperationTest() { + final Random random = getRandomPrintSeed(); + + final ObjectCounter counter = new StandardObjectCounter(Duration.ofMillis(1)); + + int count = 0; + for (int i = 0; i < 1000; i++) { + + final boolean increment = count == 0 || random.nextBoolean(); + + if (increment) { + count++; + + // All of these methods are logically equivalent for this implementation. + final int choice = random.nextInt(3); + switch (choice) { + case 0 -> counter.onRamp(); + case 1 -> counter.attemptOnRamp(); + case 2 -> counter.forceOnRamp(); + default -> throw new IllegalStateException("Unexpected value: " + choice); + } + + } else { + count--; + counter.offRamp(); + } + + assertEquals(count, counter.getCount()); + } + } + + @Test + void waitUntilEmptyTest() throws InterruptedException { + final ObjectCounter counter = new StandardObjectCounter(Duration.ofMillis(1)); + + for (int i = 0; i < 100; i++) { + counter.onRamp(); + } + + final AtomicBoolean empty = new AtomicBoolean(false); + final Thread thread = new ThreadConfiguration(getStaticThreadManager()) + .setRunnable(() -> { + counter.waitUntilEmpty(); + empty.set(true); + }) + .build(true); + + // Should be blocked. + MILLISECONDS.sleep(50); + assertFalse(empty.get()); + + // Draining most of the things from the counter should still block. + for (int i = 0; i < 90; i++) { + counter.offRamp(); + } + MILLISECONDS.sleep(50); + assertFalse(empty.get()); + + // Interrupting the thread should have no effect. + thread.interrupt(); + MILLISECONDS.sleep(50); + assertFalse(empty.get()); + + // Removing remaining things from the counter should unblock. + for (int i = 0; i < 10; i++) { + counter.offRamp(); + } + + assertEventuallyTrue(empty::get, Duration.ofSeconds(1), "Counter did not empty in time."); + } +} diff --git a/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/model/DeterministicHeartbeatSchedulerTests.java b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/model/DeterministicHeartbeatSchedulerTests.java new file mode 100644 index 00000000000..32abfe613ab --- /dev/null +++ b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/model/DeterministicHeartbeatSchedulerTests.java @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC + * + * 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 org.hiero.wiring.framework.model; + +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerBuilder.UNLIMITED_CAPACITY; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.swirlds.base.test.fixtures.time.FakeTime; +import com.swirlds.common.context.PlatformContext; +import com.swirlds.common.test.fixtures.platform.TestPlatformContextBuilder; +import java.time.Duration; +import java.time.Instant; +import java.util.concurrent.atomic.AtomicLong; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.wires.input.BindableInputWire; +import org.junit.jupiter.api.Test; + +public class DeterministicHeartbeatSchedulerTests { + + @Test + void heartbeatByFrequencyTest() { + final FakeTime time = new FakeTime(); + final PlatformContext platformContext = + TestPlatformContextBuilder.create().withTime(time).build(); + final DeterministicWiringModel model = WiringModelBuilder.create(platformContext) + .withDeterministicModeEnabled(true) + .build(); + ; + + final TaskScheduler scheduler = + model.schedulerBuilder("test").build().cast(); + + final BindableInputWire heartbeatBindable = scheduler.buildInputWire("heartbeat"); + model.buildHeartbeatWire(100).solderTo(heartbeatBindable); + + final AtomicLong counter = new AtomicLong(0); + heartbeatBindable.bindConsumer((now) -> counter.incrementAndGet()); + + model.start(); + int milliseconds = 0; + while (milliseconds <= 1000) { + time.tick(Duration.ofMillis(1)); + milliseconds += 1; + model.tick(); + } + model.stop(); + + assertEquals(100, counter.get()); + } + + @Test + void heartbeatByPeriodTest() { + final FakeTime time = new FakeTime(); + final PlatformContext platformContext = + TestPlatformContextBuilder.create().withTime(time).build(); + final DeterministicWiringModel model = WiringModelBuilder.create(platformContext) + .withDeterministicModeEnabled(true) + .build(); + ; + + final TaskScheduler scheduler = + model.schedulerBuilder("test").build().cast(); + + final BindableInputWire heartbeatBindable = scheduler.buildInputWire("heartbeat"); + model.buildHeartbeatWire(Duration.ofMillis(10)).solderTo(heartbeatBindable); + + final AtomicLong counter = new AtomicLong(0); + heartbeatBindable.bindConsumer((now) -> counter.incrementAndGet()); + + model.start(); + int milliseconds = 0; + while (milliseconds <= 1000) { + time.tick(Duration.ofMillis(1)); + milliseconds += 1; + model.tick(); + } + model.stop(); + + assertEquals(100, counter.get()); + } + + @Test + void heartbeatsAtDifferentRates() { + final FakeTime time = new FakeTime(); + final PlatformContext platformContext = + TestPlatformContextBuilder.create().withTime(time).build(); + final DeterministicWiringModel model = WiringModelBuilder.create(platformContext) + .withDeterministicModeEnabled(true) + .build(); + ; + + final TaskScheduler scheduler = model.schedulerBuilder("test") + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .build() + .cast(); + + final BindableInputWire heartbeatBindableA = scheduler.buildInputWire("heartbeatA"); + final BindableInputWire heartbeatBindableB = scheduler.buildInputWire("heartbeatB"); + final BindableInputWire heartbeatBindableC = scheduler.buildInputWire("heartbeatC"); + final BindableInputWire heartbeatBindableD = scheduler.buildInputWire("heartbeatD"); + + model.buildHeartbeatWire(100).solderTo(heartbeatBindableA); + model.buildHeartbeatWire(Duration.ofMillis(5)).solderTo(heartbeatBindableB); + model.buildHeartbeatWire(Duration.ofMillis(50)).solderTo(heartbeatBindableC); + model.buildHeartbeatWire(Duration.ofMillis(50)).solderTo(heartbeatBindableD); + + final AtomicLong counterA = new AtomicLong(0); + heartbeatBindableA.bindConsumer((now) -> counterA.incrementAndGet()); + + final AtomicLong counterB = new AtomicLong(0); + heartbeatBindableB.bindConsumer((now) -> counterB.incrementAndGet()); + + final AtomicLong counterC = new AtomicLong(0); + heartbeatBindableC.bindConsumer((now) -> counterC.incrementAndGet()); + + final AtomicLong counterD = new AtomicLong(0); + heartbeatBindableD.bindConsumer((now) -> counterD.incrementAndGet()); + + model.start(); + int milliseconds = 0; + while (milliseconds <= 1000) { + time.tick(Duration.ofMillis(1)); + milliseconds += 1; + model.tick(); + } + model.stop(); + + assertEquals(100, counterA.get()); + assertEquals(200, counterB.get()); + assertEquals(20, counterC.get()); + assertEquals(20, counterD.get()); + } +} diff --git a/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/model/DeterministicModelTests.java b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/model/DeterministicModelTests.java new file mode 100644 index 00000000000..807083b4ae7 --- /dev/null +++ b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/model/DeterministicModelTests.java @@ -0,0 +1,570 @@ +/* + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC + * + * 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 org.hiero.wiring.framework.model; + +import static com.swirlds.common.test.fixtures.RandomUtils.getRandomPrintSeed; +import static com.swirlds.common.test.fixtures.RandomUtils.randomInstant; +import static com.swirlds.common.utility.NonCryptographicHashing.hash32; +import static java.util.concurrent.TimeUnit.MICROSECONDS; +import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static org.assertj.core.api.Fail.fail; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerBuilder.UNLIMITED_CAPACITY; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.CONCURRENT; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.DIRECT; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.DIRECT_THREADSAFE; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.NO_OP; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.SEQUENTIAL; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.SEQUENTIAL_THREAD; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import com.swirlds.base.test.fixtures.time.FakeTime; +import com.swirlds.common.context.PlatformContext; +import com.swirlds.common.test.fixtures.platform.TestPlatformContextBuilder; +import com.swirlds.common.utility.NonCryptographicHashing; +import edu.umd.cs.findbugs.annotations.NonNull; +import java.time.Duration; +import java.time.Instant; +import java.util.Random; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.locks.ReentrantLock; +import java.util.function.BooleanSupplier; +import java.util.function.Function; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.wires.input.BindableInputWire; +import org.hiero.wiring.framework.wires.input.InputWire; +import org.hiero.wiring.framework.wires.output.OutputWire; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +class DeterministicModelTests { + + /** + * Build a handler method for "components" in the wiring generated by generateWiringMesh(). The goal of these + * handlers is to be extremely race condition prone if executed in parallel or in different serial order. + * + * @param random a random number generator + * @param discardChance a chance out of 1 that an input is simply discarded + * @param lock grab and release this lock each time the handler is called. This is a quick and dirty + * mechanism we can use to check for quiescence in a thread safe manner. + * @return a new handler + */ + @NonNull + private static Function buildHandler( + @NonNull final Random random, final double discardChance, final ReentrantLock lock) { + + final AtomicLong innerValue = new AtomicLong(); + return input -> { + + // This is locked by the outside scope when we are attempting + // to determine if the system is in a quiescent state. + lock.lock(); + lock.unlock(); + + if (discardChance > 0 && (random.nextDouble() < discardChance)) { + // Discard this input + return null; + } + + final long newValue = NonCryptographicHashing.hash64(innerValue.get(), input, random.nextLong()); + innerValue.set(newValue); + + // Sleep half a millisecond, on average. + final long sleepMicros = Math.abs(newValue) % 1000; + try { + MICROSECONDS.sleep(sleepMicros); + } catch (final InterruptedException e) { + Thread.currentThread().interrupt(); + throw new RuntimeException(e); + } + + return newValue; + }; + } + + /** + * A test wiring mesh for testing deterministic behavior + * + * @param inputWire the input wire for the mesh + * @param outputValue contains the final result (when isQuiescent() returns true) + * @param isQuiescent returns true when there is no longer data flowing through the mesh + */ + private record WiringMesh( + @NonNull InputWire inputWire, + @NonNull AtomicLong outputValue, + @NonNull BooleanSupplier isQuiescent) {} + + /** + * Generates a wiring mesh that yields non-deterministic results when data is fed in using the standard wiring + * model. + * + * @param seed the seed to use for the random number generator + * @param wiringModel the wiring model to use + * @param enableHeartbeat whether to enable a heartbeat scheduler, useful for ensuring that the standard case is + * non-deterministic even without a heartbeat introducing artifacts from the wall clock + * @return the input wire to feed data into the mesh + */ + @NonNull + private static WiringMesh generateWiringMesh( + final long seed, @NonNull final WiringModel wiringModel, final boolean enableHeartbeat) { + + // - Data is fed into A + // - Data comes out of J + // - B is a concurrent scheduler + // - H and I are direct schedulers + // - K is a no op scheduler + // - All other schedulers are sequential or sequential thread + // - Scheduler D discards 60% of all input. This means that the probability of data cycling an infinite + // number of times in the loop asymptotically approaches 0 over time. + // - All other schedulers discard 1% of their input. + + /* + + A + | + v + B <---------- Heartbeat (5ms) + | + v + C + | + v + D -----> E K + ^ | ^ + | v | + G <----- F -----> H -----> I -----> J + + */ + + final Random random = new Random(seed); + + final ReentrantLock lock = new ReentrantLock(); + + final TaskScheduler schedulerA = wiringModel + .schedulerBuilder("A") + .withType(SEQUENTIAL) + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .withFlushingEnabled(true) + .build() + .cast(); + final BindableInputWire inA = schedulerA.buildInputWire("inA"); + inA.bind(buildHandler(random, 0.01, lock)); + final OutputWire outA = schedulerA.getOutputWire(); + + final TaskScheduler schedulerB = wiringModel + .schedulerBuilder("B") + .withType(CONCURRENT) + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .withFlushingEnabled(true) + .build() + .cast(); + final BindableInputWire inB = schedulerB.buildInputWire("inB"); + inB.bind(buildHandler(random, 0.01, lock)); + final BindableInputWire schedulerBHeartbeat = schedulerB.buildInputWire("heartbeatB"); + final Function heartbeatHandler = buildHandler(random, 0, lock); + schedulerBHeartbeat.bind(instant -> { + System.out.println(instant); + return heartbeatHandler.apply(instant.toEpochMilli()); + }); + final OutputWire outB = schedulerB.getOutputWire(); + + final TaskScheduler schedulerC = wiringModel + .schedulerBuilder("C") + .withType(SEQUENTIAL_THREAD) + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .withFlushingEnabled(true) + .build() + .cast(); + final BindableInputWire inC = schedulerC.buildInputWire("inC"); + inC.bind(buildHandler(random, 0.01, lock)); + final OutputWire outC = schedulerC.getOutputWire(); + + final TaskScheduler schedulerD = wiringModel + .schedulerBuilder("D") + .withType(SEQUENTIAL) + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .withFlushingEnabled(true) + .build() + .cast(); + final BindableInputWire inD = schedulerD.buildInputWire("inD"); + inD.bind(buildHandler(random, 0.6, lock)); // This must be >0.5 else risk infinite loop + final OutputWire outD = schedulerD.getOutputWire(); + + final TaskScheduler schedulerE = wiringModel + .schedulerBuilder("E") + .withType(SEQUENTIAL) + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .withFlushingEnabled(true) + .build() + .cast(); + final BindableInputWire inE = schedulerE.buildInputWire("inE"); + inE.bind(buildHandler(random, 0.01, lock)); + final OutputWire outE = schedulerE.getOutputWire(); + + final TaskScheduler schedulerF = wiringModel + .schedulerBuilder("F") + .withType(SEQUENTIAL) + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .withFlushingEnabled(true) + .build() + .cast(); + final BindableInputWire inF = schedulerF.buildInputWire("inF"); + inF.bind(buildHandler(random, 0.01, lock)); + final OutputWire outF = schedulerF.getOutputWire(); + + final TaskScheduler schedulerG = wiringModel + .schedulerBuilder("G") + .withType(SEQUENTIAL) + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .withFlushingEnabled(true) + .build() + .cast(); + final BindableInputWire inG = schedulerG.buildInputWire("inG"); + inG.bind(buildHandler(random, 0.01, lock)); + final OutputWire outG = schedulerG.getOutputWire(); + + final TaskScheduler schedulerH = wiringModel + .schedulerBuilder("H") + .withType(DIRECT) + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .withFlushingEnabled(true) + .build() + .cast(); + final BindableInputWire inH = schedulerH.buildInputWire("inH"); + inH.bind(buildHandler(random, 0.01, lock)); + final OutputWire outH = schedulerH.getOutputWire(); + + final TaskScheduler schedulerI = wiringModel + .schedulerBuilder("I") + .withType(DIRECT_THREADSAFE) + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .withFlushingEnabled(true) + .build() + .cast(); + final BindableInputWire inI = schedulerI.buildInputWire("inI"); + inI.bind(buildHandler(random, 0.01, lock)); + final OutputWire outI = schedulerI.getOutputWire(); + + final TaskScheduler schedulerJ = wiringModel + .schedulerBuilder("J") + .withType(SEQUENTIAL) + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .withFlushingEnabled(true) + .build() + .cast(); + final BindableInputWire inJ = schedulerJ.buildInputWire("inJ"); + inJ.bind(buildHandler(random, 0.01, lock)); + final OutputWire outJ = schedulerJ.getOutputWire(); + + final TaskScheduler schedulerK = wiringModel + .schedulerBuilder("K") + .withType(NO_OP) + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .withFlushingEnabled(true) + .build() + .cast(); + final BindableInputWire inK = schedulerK.buildInputWire("inK"); + inK.bind(buildHandler(random, 0.01, lock)); + + outA.solderTo(inB); + if (enableHeartbeat) { + wiringModel.buildHeartbeatWire(Duration.ofMillis(5)).solderTo(schedulerBHeartbeat); + } + outB.solderTo(inC); + outC.solderTo(inD); + outD.solderTo(inE); + outE.solderTo(inF); + outF.solderTo(inG); + outG.solderTo(inD); + outF.solderTo(inH); + outH.solderTo(inI); + outI.solderTo(inJ); + outI.solderTo(inK); + + // Write the final output to the atomic long provided + final AtomicLong outputValue = new AtomicLong(); + outJ.solderTo("finalOutput", "data", outputValue::set); + + final BooleanSupplier isQuiescent = () -> { + lock.lock(); + try { + return schedulerA.getUnprocessedTaskCount() == 0 + && schedulerB.getUnprocessedTaskCount() == 0 + && schedulerC.getUnprocessedTaskCount() == 0 + && schedulerD.getUnprocessedTaskCount() == 0 + && schedulerE.getUnprocessedTaskCount() == 0 + && schedulerF.getUnprocessedTaskCount() == 0 + && schedulerG.getUnprocessedTaskCount() == 0 + && schedulerH.getUnprocessedTaskCount() == 0 + && schedulerI.getUnprocessedTaskCount() == 0 + && schedulerJ.getUnprocessedTaskCount() == 0 + && schedulerK.getUnprocessedTaskCount() == 0; + } finally { + lock.unlock(); + } + }; + + wiringModel.start(); + + // Enable this and copy it into mermaid.live to visualize the wiring in this test + // final String diagram = wiringModel.generateWiringDiagram(List.of(), List.of(), List.of(), false); + // System.out.println(diagram); + + return new WiringMesh(inA, outputValue, isQuiescent); + } + + /** + * Feed a bunch of data into the mesh and return the value once all data has been processed. + * + * @param seed the seed to use for the random number generator + * @param mesh the wiring mesh to evaluate + * @param waitForNextCycle a runnable that will be called each time the mesh is checked for quiescence + */ + private static long evaluateMesh( + @NonNull final long seed, @NonNull final WiringMesh mesh, @NonNull final Runnable waitForNextCycle) { + + final Random random = new Random(seed); + + // Feed in data + for (long i = 0; i < 100; i++) { + final long next = random.nextLong(); + mesh.inputWire.put(next); + } + + int maxIterations = 20_000; + while (!mesh.isQuiescent.getAsBoolean()) { + waitForNextCycle.run(); + + maxIterations--; + assertTrue(maxIterations > 0, "mesh did not quiesce in time"); + } + + return mesh.outputValue.get(); + } + + /** + * The purpose of this test is to verify that the test setup is non-deterministic when using the standard wiring + * model. + */ + @ParameterizedTest + @ValueSource(booleans = {true, false}) + void verifyStandardNondeterminism(final boolean enableHeartbeat) { + final Random random = getRandomPrintSeed(); + final long meshSeed = random.nextLong(); + final long dataSeed = random.nextLong(); + + final PlatformContext platformContext = + TestPlatformContextBuilder.create().build(); + + final long value1 = evaluateMesh( + dataSeed, + generateWiringMesh( + meshSeed, WiringModelBuilder.create(platformContext).build(), enableHeartbeat), + () -> { + try { + MILLISECONDS.sleep(1); + } catch (final InterruptedException e) { + Thread.currentThread().interrupt(); + throw new RuntimeException(e); + } + }); + + final long value2 = evaluateMesh( + dataSeed, + generateWiringMesh( + meshSeed, WiringModelBuilder.create(platformContext).build(), enableHeartbeat), + () -> { + try { + MILLISECONDS.sleep(1); + } catch (final InterruptedException e) { + Thread.currentThread().interrupt(); + throw new RuntimeException(e); + } + }); + + assertNotEquals(value1, value2); + } + + @Test + void verifyDeterministicModel() { + final Random random = getRandomPrintSeed(); + final long meshSeed = random.nextLong(); + final long dataSeed = random.nextLong(); + + final FakeTime time = new FakeTime(randomInstant(random), Duration.ZERO); + final PlatformContext platformContext = + TestPlatformContextBuilder.create().withTime(time).build(); + + final DeterministicWiringModel deterministicWiringModel1 = WiringModelBuilder.create(platformContext) + .withDeterministicModeEnabled(true) + .build(); + final long value1 = + evaluateMesh(dataSeed, generateWiringMesh(meshSeed, deterministicWiringModel1, true), () -> { + time.tick(Duration.ofMillis(1)); + deterministicWiringModel1.tick(); + }); + + time.reset(); + final DeterministicWiringModel deterministicWiringModel2 = WiringModelBuilder.create(platformContext) + .withDeterministicModeEnabled(true) + .build(); + final long value2 = + evaluateMesh(dataSeed, generateWiringMesh(meshSeed, deterministicWiringModel2, true), () -> { + time.tick(Duration.ofMillis(1)); + deterministicWiringModel2.tick(); + }); + + assertEquals(value1, value2); + } + + /** + * Test a scenario where there is a circular data flow formed by wires. + *

+ * In this test, all data is passed from A to B to C to D. All data that is a multiple of 7 is passed from D to A as + * a negative value, but is not passed around the loop again. + * + *

+     * A -------> B
+     * ^          |
+     * |          |
+     * |          V
+     * D <------- C
+     * 
+ */ + @Test + void circularDataFlowTest() { + final PlatformContext platformContext = + TestPlatformContextBuilder.create().build(); + final DeterministicWiringModel model = WiringModelBuilder.create(platformContext) + .withDeterministicModeEnabled(true) + .build(); + + final AtomicInteger countA = new AtomicInteger(); + final AtomicInteger negativeCountA = new AtomicInteger(); + final AtomicInteger countB = new AtomicInteger(); + final AtomicInteger countC = new AtomicInteger(); + final AtomicInteger countD = new AtomicInteger(); + + final TaskScheduler taskSchedulerToA = model.schedulerBuilder("wireToA") + .withType(SEQUENTIAL) + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .build() + .cast(); + final TaskScheduler taskSchedulerToB = model.schedulerBuilder("wireToB") + .withType(SEQUENTIAL_THREAD) + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .build() + .cast(); + final TaskScheduler taskSchedulerToC = model.schedulerBuilder("wireToC") + .withType(CONCURRENT) + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .build() + .cast(); + final TaskScheduler taskSchedulerToD = model.schedulerBuilder("wireToD") + .withType(DIRECT) + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .build() + .cast(); + + final BindableInputWire channelToA = taskSchedulerToA.buildInputWire("channelToA"); + final BindableInputWire channelToB = taskSchedulerToB.buildInputWire("channelToB"); + final BindableInputWire channelToC = taskSchedulerToC.buildInputWire("channelToC"); + final BindableInputWire channelToD = taskSchedulerToD.buildInputWire("channelToD"); + + final Function handlerA = x -> { + if (x > 0) { + countA.set(hash32(x, countA.get())); + return x; + } else { + negativeCountA.set(hash32(x, negativeCountA.get())); + // negative values are values that have been passed around the loop + // Don't pass them on again or else we will get an infinite loop + return null; + } + }; + + final Function handlerB = x -> { + countB.set(hash32(x, countB.get())); + return x; + }; + + final Function handlerC = x -> { + countC.set(hash32(x, countC.get())); + return x; + }; + + final Function handlerD = x -> { + countD.set(hash32(x, countD.get())); + if (x % 7 == 0) { + return -x; + } else { + return null; + } + }; + + taskSchedulerToA.getOutputWire().solderTo(channelToB); + taskSchedulerToB.getOutputWire().solderTo(channelToC); + taskSchedulerToC.getOutputWire().solderTo(channelToD); + taskSchedulerToD.getOutputWire().solderTo(channelToA); + + channelToA.bind(handlerA); + channelToB.bind(handlerB); + channelToC.bind(handlerC); + channelToD.bind(handlerD); + + model.start(); + + int expectedCountA = 0; + int expectedNegativeCountA = 0; + int expectedCountB = 0; + int expectedCountC = 0; + int expectedCountD = 0; + + for (int i = 1; i < 1000; i++) { + channelToA.put(i); + + expectedCountA = hash32(i, expectedCountA); + expectedCountB = hash32(i, expectedCountB); + expectedCountC = hash32(i, expectedCountC); + expectedCountD = hash32(i, expectedCountD); + + if (i % 7 == 0) { + expectedNegativeCountA = hash32(-i, expectedNegativeCountA); + } + } + + int maxTicks = 10_000; + while (true) { + if (maxTicks-- == 0) { + fail("Model did not quiesce in time"); + } + model.tick(); + if (expectedCountA == countA.get() + && expectedNegativeCountA == negativeCountA.get() + && expectedCountB == countB.get() + && expectedCountC == countC.get() + && expectedCountD == countD.get()) { + break; + } + } + + model.stop(); + } +} diff --git a/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/model/ModelTests.java b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/model/ModelTests.java new file mode 100644 index 00000000000..ce69e6e6680 --- /dev/null +++ b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/model/ModelTests.java @@ -0,0 +1,1763 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * 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 org.hiero.wiring.framework.model; + +import static com.swirlds.common.threading.framework.internal.AbstractQueueThreadConfiguration.UNLIMITED_CAPACITY; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import com.swirlds.common.test.fixtures.platform.TestPlatformContextBuilder; +import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.List; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.wires.SolderType; +import org.hiero.wiring.framework.wires.input.BindableInputWire; +import org.hiero.wiring.framework.wires.input.InputWire; +import org.hiero.wiring.framework.wires.output.OutputWire; +import org.junit.jupiter.api.Test; + +class ModelTests { + + /** + * For debugging with a human in the loop. + */ + private static final boolean printMermaidDiagram = false; + + /** + * Validate the model. + * + * @param model the model to validate + * @param cycleExpected true if a cycle is expected, false otherwise + * @param illegalDirectSchedulerUseExpected true if illegal direct scheduler use is expected, false otherwise + */ + private static void validateModel( + @NonNull final WiringModel model, + final boolean cycleExpected, + final boolean illegalDirectSchedulerUseExpected) { + + final boolean cycleDetected = model.checkForCyclicalBackpressure(); + assertEquals(cycleExpected, cycleDetected); + + final boolean illegalDirectSchedulerUseDetected = model.checkForIllegalDirectSchedulerUsage(); + assertEquals(illegalDirectSchedulerUseExpected, illegalDirectSchedulerUseDetected); + + // Should not throw. + final String diagram = model.generateWiringDiagram(List.of(), List.of(), List.of(), false); + if (printMermaidDiagram) { + System.out.println(diagram); + } + } + + @Test + void emptyModelTest() { + final WiringModel model = WiringModelBuilder.create( + TestPlatformContextBuilder.create().build()) + .build(); + validateModel(model, false, false); + } + + @Test + void singleVertexTest() { + final WiringModel model = WiringModelBuilder.create( + TestPlatformContextBuilder.create().build()) + .build(); + + /* + + A + + */ + + final TaskScheduler taskSchedulerA = model.schedulerBuilder("A") + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .build() + .cast(); + + validateModel(model, false, false); + } + + @Test + void shortChainTest() { + final WiringModel model = WiringModelBuilder.create( + TestPlatformContextBuilder.create().build()) + .build(); + + /* + + A -> B -> C + + */ + + final TaskScheduler taskSchedulerA = + model.schedulerBuilder("A").withUnhandledTaskCapacity(1).build().cast(); + + final TaskScheduler taskSchedulerB = + model.schedulerBuilder("B").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputB = taskSchedulerB.buildInputWire("inputB"); + + final TaskScheduler taskSchedulerC = + model.schedulerBuilder("C").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputC = taskSchedulerC.buildInputWire("inputC"); + + taskSchedulerA.getOutputWire().solderTo(inputB); + taskSchedulerB.getOutputWire().solderTo(inputC); + + validateModel(model, false, false); + } + + @Test + void loopSizeOneTest() { + final WiringModel model = WiringModelBuilder.create( + TestPlatformContextBuilder.create().build()) + .build(); + + /* + + A --| + ^ | + |---| + + */ + + final TaskScheduler taskSchedulerA = + model.schedulerBuilder("A").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputA = taskSchedulerA.buildInputWire("inputA"); + + taskSchedulerA.getOutputWire().solderTo(inputA); + + validateModel(model, true, false); + } + + @Test + void loopSizeOneBrokenByInjectionTest() { + final WiringModel model = WiringModelBuilder.create( + TestPlatformContextBuilder.create().build()) + .build(); + + /* + + A --| + ^ | + |---| + + */ + + final TaskScheduler taskSchedulerA = + model.schedulerBuilder("A").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputA = taskSchedulerA.buildInputWire("inputA"); + + taskSchedulerA.getOutputWire().solderTo(inputA, SolderType.INJECT); + + validateModel(model, false, false); + } + + @Test + void loopSizeTwoTest() { + final WiringModel model = WiringModelBuilder.create( + TestPlatformContextBuilder.create().build()) + .build(); + + /* + + A -> B + ^ | + |----| + + */ + + final TaskScheduler taskSchedulerA = + model.schedulerBuilder("A").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputA = taskSchedulerA.buildInputWire("inputA"); + + final TaskScheduler taskSchedulerB = + model.schedulerBuilder("B").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputB = taskSchedulerB.buildInputWire("inputB"); + + taskSchedulerA.getOutputWire().solderTo(inputB); + taskSchedulerB.getOutputWire().solderTo(inputA); + + validateModel(model, true, false); + } + + @Test + void loopSizeTwoBrokenByInjectionTest() { + final WiringModel model = WiringModelBuilder.create( + TestPlatformContextBuilder.create().build()) + .build(); + + /* + + A -> B + ^ | + |----| + + */ + + final TaskScheduler taskSchedulerA = + model.schedulerBuilder("A").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputA = taskSchedulerA.buildInputWire("inputA"); + + final TaskScheduler taskSchedulerB = + model.schedulerBuilder("B").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputB = taskSchedulerB.buildInputWire("inputB"); + + taskSchedulerA.getOutputWire().solderTo(inputB); + taskSchedulerB.getOutputWire().solderTo(inputA, SolderType.INJECT); + + validateModel(model, false, false); + } + + @Test + void loopSizeTwoBrokenByMissingBoundTest() { + final WiringModel model = WiringModelBuilder.create( + TestPlatformContextBuilder.create().build()) + .build(); + + /* + + A -> B + ^ | + |----| + + */ + + final TaskScheduler taskSchedulerA = model.schedulerBuilder("A") + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .build() + .cast(); + final InputWire inputA = taskSchedulerA.buildInputWire("inputA"); + + final TaskScheduler taskSchedulerB = + model.schedulerBuilder("B").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputB = taskSchedulerB.buildInputWire("inputB"); + + taskSchedulerA.getOutputWire().solderTo(inputB); + taskSchedulerB.getOutputWire().solderTo(inputA); + + validateModel(model, false, false); + } + + @Test + void loopSizeThreeTest() { + final WiringModel model = WiringModelBuilder.create( + TestPlatformContextBuilder.create().build()) + .build(); + + /* + + A -> B -> C + ^ | + |---------| + + */ + + final TaskScheduler taskSchedulerA = + model.schedulerBuilder("A").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputA = taskSchedulerA.buildInputWire("inputA"); + + final TaskScheduler taskSchedulerB = + model.schedulerBuilder("B").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputB = taskSchedulerB.buildInputWire("inputB"); + + final TaskScheduler taskSchedulerC = + model.schedulerBuilder("C").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputC = taskSchedulerC.buildInputWire("inputC"); + + taskSchedulerA.getOutputWire().solderTo(inputB); + taskSchedulerB.getOutputWire().solderTo(inputC); + taskSchedulerC.getOutputWire().solderTo(inputA); + + validateModel(model, true, false); + } + + @Test + void loopSizeThreeBrokenByInjectionTest() { + final WiringModel model = WiringModelBuilder.create( + TestPlatformContextBuilder.create().build()) + .build(); + + /* + + A -> B -> C + ^ | + |---------| + + */ + + final TaskScheduler taskSchedulerA = + model.schedulerBuilder("A").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputA = taskSchedulerA.buildInputWire("inputA"); + + final TaskScheduler taskSchedulerB = + model.schedulerBuilder("B").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputB = taskSchedulerB.buildInputWire("inputB"); + + final TaskScheduler taskSchedulerC = + model.schedulerBuilder("C").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputC = taskSchedulerC.buildInputWire("inputC"); + + taskSchedulerA.getOutputWire().solderTo(inputB); + taskSchedulerB.getOutputWire().solderTo(inputC); + taskSchedulerC.getOutputWire().solderTo(inputA, SolderType.INJECT); + + validateModel(model, false, false); + } + + @Test + void loopSizeThreeBrokenByMissingBoundTest() { + final WiringModel model = WiringModelBuilder.create( + TestPlatformContextBuilder.create().build()) + .build(); + + /* + + A -> B -> C + ^ | + |---------| + + */ + + final TaskScheduler taskSchedulerA = + model.schedulerBuilder("A").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputA = taskSchedulerA.buildInputWire("inputA"); + + final TaskScheduler taskSchedulerB = + model.schedulerBuilder("B").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputB = taskSchedulerB.buildInputWire("inputB"); + + final TaskScheduler taskSchedulerC = model.schedulerBuilder("C") + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .build() + .cast(); + final InputWire inputC = taskSchedulerC.buildInputWire("inputC"); + + taskSchedulerA.getOutputWire().solderTo(inputB); + taskSchedulerB.getOutputWire().solderTo(inputC); + taskSchedulerC.getOutputWire().solderTo(inputA); + + validateModel(model, false, false); + } + + @Test + void loopSizeFourTest() { + final WiringModel model = WiringModelBuilder.create( + TestPlatformContextBuilder.create().build()) + .build(); + + /* + + A -----> B + ^ | + | v + D <----- C + + */ + + final TaskScheduler taskSchedulerA = + model.schedulerBuilder("A").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputA = taskSchedulerA.buildInputWire("inputA"); + + final TaskScheduler taskSchedulerB = + model.schedulerBuilder("B").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputB = taskSchedulerB.buildInputWire("inputB"); + + final TaskScheduler taskSchedulerC = + model.schedulerBuilder("C").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputC = taskSchedulerC.buildInputWire("inputC"); + + final TaskScheduler taskSchedulerD = + model.schedulerBuilder("D").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputD = taskSchedulerD.buildInputWire("inputD"); + + taskSchedulerA.getOutputWire().solderTo(inputB); + taskSchedulerB.getOutputWire().solderTo(inputC); + taskSchedulerC.getOutputWire().solderTo(inputD); + taskSchedulerD.getOutputWire().solderTo(inputA); + + validateModel(model, true, false); + } + + @Test + void loopSizeFourBrokenByInjectionTest() { + final WiringModel model = WiringModelBuilder.create( + TestPlatformContextBuilder.create().build()) + .build(); + + /* + + A -----> B + ^ | + | v + D <----- C + + */ + + final TaskScheduler taskSchedulerA = + model.schedulerBuilder("A").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputA = taskSchedulerA.buildInputWire("inputA"); + + final TaskScheduler taskSchedulerB = + model.schedulerBuilder("B").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputB = taskSchedulerB.buildInputWire("inputB"); + + final TaskScheduler taskSchedulerC = + model.schedulerBuilder("C").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputC = taskSchedulerC.buildInputWire("inputC"); + + final TaskScheduler taskSchedulerD = model.schedulerBuilder("D") + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .build() + .cast(); + final InputWire inputD = taskSchedulerD.buildInputWire("inputD"); + + taskSchedulerA.getOutputWire().solderTo(inputB); + taskSchedulerB.getOutputWire().solderTo(inputC); + taskSchedulerC.getOutputWire().solderTo(inputD); + taskSchedulerD.getOutputWire().solderTo(inputA, SolderType.INJECT); + + validateModel(model, false, false); + } + + @Test + void loopSizeFourBrokenByMissingBoundTest() { + final WiringModel model = WiringModelBuilder.create( + TestPlatformContextBuilder.create().build()) + .build(); + + /* + + A -----> B + ^ | + | v + D <----- C + + */ + + final TaskScheduler taskSchedulerA = + model.schedulerBuilder("A").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputA = taskSchedulerA.buildInputWire("inputA"); + + final TaskScheduler taskSchedulerB = + model.schedulerBuilder("B").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputB = taskSchedulerB.buildInputWire("inputB"); + + final TaskScheduler taskSchedulerC = + model.schedulerBuilder("C").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputC = taskSchedulerC.buildInputWire("inputC"); + + final TaskScheduler taskSchedulerD = + model.schedulerBuilder("D").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputD = taskSchedulerD.buildInputWire("inputD"); + + taskSchedulerA.getOutputWire().solderTo(inputB); + taskSchedulerB.getOutputWire().solderTo(inputC); + taskSchedulerC.getOutputWire().solderTo(inputD); + taskSchedulerD.getOutputWire().solderTo(inputA); + + validateModel(model, true, false); + } + + @Test + void loopSizeFourWithChainTest() { + final WiringModel model = WiringModelBuilder.create( + TestPlatformContextBuilder.create().build()) + .build(); + + /* + + A + | + v + B + | + v + C + | + v + D -----> E + ^ | + | v + G <----- F -----> H -----> I -----> J + + */ + + final TaskScheduler taskSchedulerA = + model.schedulerBuilder("A").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputA = taskSchedulerA.buildInputWire("inputA"); + + final TaskScheduler taskSchedulerB = + model.schedulerBuilder("B").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputB = taskSchedulerB.buildInputWire("inputB"); + + final TaskScheduler taskSchedulerC = + model.schedulerBuilder("C").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputC = taskSchedulerC.buildInputWire("inputC"); + + final TaskScheduler taskSchedulerD = + model.schedulerBuilder("D").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputD = taskSchedulerD.buildInputWire("inputD"); + + final TaskScheduler taskSchedulerE = + model.schedulerBuilder("E").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputE = taskSchedulerE.buildInputWire("inputE"); + + final TaskScheduler taskSchedulerF = + model.schedulerBuilder("F").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputF = taskSchedulerF.buildInputWire("inputF"); + + final TaskScheduler taskSchedulerG = + model.schedulerBuilder("G").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputG = taskSchedulerG.buildInputWire("inputG"); + + final TaskScheduler taskSchedulerH = + model.schedulerBuilder("H").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputH = taskSchedulerH.buildInputWire("inputH"); + + final TaskScheduler taskSchedulerI = + model.schedulerBuilder("I").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputI = taskSchedulerI.buildInputWire("inputI"); + + final TaskScheduler taskSchedulerJ = + model.schedulerBuilder("J").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputJ = taskSchedulerJ.buildInputWire("inputJ"); + + taskSchedulerA.getOutputWire().solderTo(inputB); + taskSchedulerB.getOutputWire().solderTo(inputC); + taskSchedulerC.getOutputWire().solderTo(inputD); + taskSchedulerD.getOutputWire().solderTo(inputE); + taskSchedulerE.getOutputWire().solderTo(inputF); + taskSchedulerF.getOutputWire().solderTo(inputG); + taskSchedulerG.getOutputWire().solderTo(inputD); + + taskSchedulerF.getOutputWire().solderTo(inputH); + taskSchedulerH.getOutputWire().solderTo(inputI); + taskSchedulerI.getOutputWire().solderTo(inputJ); + + validateModel(model, true, false); + } + + @Test + void loopSizeFourWithChainBrokenByInjectionTest() { + final WiringModel model = WiringModelBuilder.create( + TestPlatformContextBuilder.create().build()) + .build(); + + /* + + A + | + v + B + | + v + C + | + v + D -----> E + ^ | + | v + G <----- F -----> H -----> I -----> J + + */ + + final TaskScheduler taskSchedulerA = + model.schedulerBuilder("A").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputA = taskSchedulerA.buildInputWire("inputA"); + + final TaskScheduler taskSchedulerB = + model.schedulerBuilder("B").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputB = taskSchedulerB.buildInputWire("inputB"); + + final TaskScheduler taskSchedulerC = + model.schedulerBuilder("C").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputC = taskSchedulerC.buildInputWire("inputC"); + + final TaskScheduler taskSchedulerD = + model.schedulerBuilder("D").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputD = taskSchedulerD.buildInputWire("inputD"); + + final TaskScheduler taskSchedulerE = + model.schedulerBuilder("E").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputE = taskSchedulerE.buildInputWire("inputE"); + + final TaskScheduler taskSchedulerF = + model.schedulerBuilder("F").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputF = taskSchedulerF.buildInputWire("inputF"); + + final TaskScheduler taskSchedulerG = + model.schedulerBuilder("G").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputG = taskSchedulerG.buildInputWire("inputG"); + + final TaskScheduler taskSchedulerH = + model.schedulerBuilder("H").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputH = taskSchedulerH.buildInputWire("inputH"); + + final TaskScheduler taskSchedulerI = + model.schedulerBuilder("I").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputI = taskSchedulerI.buildInputWire("inputI"); + + final TaskScheduler taskSchedulerJ = + model.schedulerBuilder("J").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputJ = taskSchedulerJ.buildInputWire(""); + + taskSchedulerA.getOutputWire().solderTo(inputB); + taskSchedulerB.getOutputWire().solderTo(inputC); + taskSchedulerC.getOutputWire().solderTo(inputD); + taskSchedulerD.getOutputWire().solderTo(inputE); + taskSchedulerE.getOutputWire().solderTo(inputF); + taskSchedulerF.getOutputWire().solderTo(inputG); + taskSchedulerG.getOutputWire().solderTo(inputD, SolderType.INJECT); + + taskSchedulerF.getOutputWire().solderTo(inputH); + taskSchedulerH.getOutputWire().solderTo(inputI); + taskSchedulerI.getOutputWire().solderTo(inputJ); + + validateModel(model, false, false); + } + + @Test + void loopSizeFourWithChainBrokenByMissingBoundTest() { + final WiringModel model = WiringModelBuilder.create( + TestPlatformContextBuilder.create().build()) + .build(); + + /* + + A + | + v + B + | + v + C + | + v + D -----> E + ^ | + | v + G <----- F -----> H -----> I -----> J + + */ + + final TaskScheduler taskSchedulerA = + model.schedulerBuilder("A").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputA = taskSchedulerA.buildInputWire("inputA"); + + final TaskScheduler taskSchedulerB = + model.schedulerBuilder("B").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputB = taskSchedulerB.buildInputWire("inputB"); + + final TaskScheduler taskSchedulerC = + model.schedulerBuilder("C").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputC = taskSchedulerC.buildInputWire("inputC"); + + final TaskScheduler taskSchedulerD = model.schedulerBuilder("D") + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .build() + .cast(); + final InputWire inputD = taskSchedulerD.buildInputWire("inputD"); + + final TaskScheduler taskSchedulerE = + model.schedulerBuilder("E").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputE = taskSchedulerE.buildInputWire("inputE"); + + final TaskScheduler taskSchedulerF = + model.schedulerBuilder("F").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputF = taskSchedulerF.buildInputWire("inputF"); + + final TaskScheduler taskSchedulerG = + model.schedulerBuilder("G").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputG = taskSchedulerG.buildInputWire("inputG"); + + final TaskScheduler taskSchedulerH = + model.schedulerBuilder("H").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputH = taskSchedulerH.buildInputWire("inputH"); + + final TaskScheduler taskSchedulerI = + model.schedulerBuilder("I").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputI = taskSchedulerI.buildInputWire("inputI"); + + final TaskScheduler taskSchedulerJ = + model.schedulerBuilder("J").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputJ = taskSchedulerJ.buildInputWire("inputJ"); + + taskSchedulerA.getOutputWire().solderTo(inputB); + taskSchedulerB.getOutputWire().solderTo(inputC); + taskSchedulerC.getOutputWire().solderTo(inputD); + taskSchedulerD.getOutputWire().solderTo(inputE); + taskSchedulerE.getOutputWire().solderTo(inputF); + taskSchedulerF.getOutputWire().solderTo(inputG); + taskSchedulerG.getOutputWire().solderTo(inputD); + + taskSchedulerF.getOutputWire().solderTo(inputH); + taskSchedulerH.getOutputWire().solderTo(inputI); + taskSchedulerI.getOutputWire().solderTo(inputJ); + + validateModel(model, false, false); + } + + @Test + void multiLoopTest() { + final WiringModel model = WiringModelBuilder.create( + TestPlatformContextBuilder.create().build()) + .build(); + + /* + + A <---------------------------------| + | | + v | + B | + | | + v | + C | + | | + v | + D -----> E <---------------| | + ^ | | | + | v | | + G <----- F -----> H -----> I -----> J + + */ + + final TaskScheduler taskSchedulerA = + model.schedulerBuilder("A").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputA = taskSchedulerA.buildInputWire("inputA"); + + final TaskScheduler taskSchedulerB = + model.schedulerBuilder("B").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputB = taskSchedulerB.buildInputWire("inputB"); + + final TaskScheduler taskSchedulerC = + model.schedulerBuilder("C").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputC = taskSchedulerC.buildInputWire("inputC"); + + final TaskScheduler taskSchedulerD = + model.schedulerBuilder("D").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputD = taskSchedulerD.buildInputWire("inputD"); + + final TaskScheduler taskSchedulerE = + model.schedulerBuilder("E").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputE = taskSchedulerE.buildInputWire("inputE"); + + final TaskScheduler taskSchedulerF = + model.schedulerBuilder("F").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputF = taskSchedulerF.buildInputWire("inputF"); + + final TaskScheduler taskSchedulerG = + model.schedulerBuilder("G").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputG = taskSchedulerG.buildInputWire("inputG"); + + final TaskScheduler taskSchedulerH = + model.schedulerBuilder("H").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputH = taskSchedulerH.buildInputWire("inputH"); + + final TaskScheduler taskSchedulerI = + model.schedulerBuilder("I").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputI = taskSchedulerI.buildInputWire("inputI"); + + final TaskScheduler taskSchedulerJ = + model.schedulerBuilder("J").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputJ = taskSchedulerJ.buildInputWire("inputJ"); + + taskSchedulerA.getOutputWire().solderTo(inputB); + taskSchedulerB.getOutputWire().solderTo(inputC); + taskSchedulerC.getOutputWire().solderTo(inputD); + taskSchedulerD.getOutputWire().solderTo(inputE); + taskSchedulerE.getOutputWire().solderTo(inputF); + taskSchedulerF.getOutputWire().solderTo(inputG); + taskSchedulerG.getOutputWire().solderTo(inputD); + + taskSchedulerF.getOutputWire().solderTo(inputH); + taskSchedulerH.getOutputWire().solderTo(inputI); + taskSchedulerI.getOutputWire().solderTo(inputJ); + + taskSchedulerJ.getOutputWire().solderTo(inputA); + + taskSchedulerI.getOutputWire().solderTo(inputE); + + validateModel(model, true, false); + } + + @Test + void multiLoopBrokenByInjectionTest() { + final WiringModel model = WiringModelBuilder.create( + TestPlatformContextBuilder.create().build()) + .build(); + + /* + + A <---------------------------------| + | | + v | + B | + | | + v | + C | + | | + v | + D -----> E <---------------| | + ^ | | | + | v | | + G <----- F -----> H -----> I -----> J + + */ + + final TaskScheduler taskSchedulerA = + model.schedulerBuilder("A").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputA = taskSchedulerA.buildInputWire("inputA"); + + final TaskScheduler taskSchedulerB = + model.schedulerBuilder("B").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputB = taskSchedulerB.buildInputWire("inputB"); + + final TaskScheduler taskSchedulerC = + model.schedulerBuilder("C").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputC = taskSchedulerC.buildInputWire("inputC"); + + final TaskScheduler taskSchedulerD = + model.schedulerBuilder("D").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputD = taskSchedulerD.buildInputWire("inputD"); + + final TaskScheduler taskSchedulerE = + model.schedulerBuilder("E").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputE = taskSchedulerE.buildInputWire("inputE"); + + final TaskScheduler taskSchedulerF = + model.schedulerBuilder("F").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputF = taskSchedulerF.buildInputWire("inputF"); + + final TaskScheduler taskSchedulerG = + model.schedulerBuilder("G").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputG = taskSchedulerG.buildInputWire("inputG"); + + final TaskScheduler taskSchedulerH = + model.schedulerBuilder("H").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputH = taskSchedulerH.buildInputWire("inputH"); + + final TaskScheduler taskSchedulerI = + model.schedulerBuilder("I").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputI = taskSchedulerI.buildInputWire("inputI"); + + final TaskScheduler taskSchedulerJ = + model.schedulerBuilder("J").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputJ = taskSchedulerJ.buildInputWire("inputJ"); + + taskSchedulerA.getOutputWire().solderTo(inputB); + taskSchedulerB.getOutputWire().solderTo(inputC); + taskSchedulerC.getOutputWire().solderTo(inputD); + taskSchedulerD.getOutputWire().solderTo(inputE); + taskSchedulerE.getOutputWire().solderTo(inputF); + taskSchedulerF.getOutputWire().solderTo(inputG); + taskSchedulerG.getOutputWire().solderTo(inputD, SolderType.INJECT); + + taskSchedulerF.getOutputWire().solderTo(inputH); + taskSchedulerH.getOutputWire().solderTo(inputI); + taskSchedulerI.getOutputWire().solderTo(inputJ); + + taskSchedulerJ.getOutputWire().solderTo(inputA, SolderType.INJECT); + + taskSchedulerI.getOutputWire().solderTo(inputE, SolderType.INJECT); + + validateModel(model, false, false); + } + + @Test + void multiLoopBrokenByMissingBoundTest() { + final WiringModel model = WiringModelBuilder.create( + TestPlatformContextBuilder.create().build()) + .build(); + + /* + + A <---------------------------------| + | | + v | + B | + | | + v | + C | + | | + v | + D -----> E <---------------| | + ^ | | | + | v | | + G <----- F -----> H -----> I -----> J + + */ + + final TaskScheduler taskSchedulerA = + model.schedulerBuilder("A").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputA = taskSchedulerA.buildInputWire("inputA"); + + final TaskScheduler taskSchedulerB = + model.schedulerBuilder("B").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputB = taskSchedulerB.buildInputWire("inputB"); + + final TaskScheduler taskSchedulerC = + model.schedulerBuilder("C").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputC = taskSchedulerC.buildInputWire("inputC"); + + final TaskScheduler taskSchedulerD = + model.schedulerBuilder("D").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputD = taskSchedulerD.buildInputWire("inputD"); + + final TaskScheduler taskSchedulerE = model.schedulerBuilder("E") + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .build() + .cast(); + final InputWire inputE = taskSchedulerE.buildInputWire("inputE"); + + final TaskScheduler taskSchedulerF = + model.schedulerBuilder("F").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputF = taskSchedulerF.buildInputWire("inputF"); + + final TaskScheduler taskSchedulerG = + model.schedulerBuilder("G").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputG = taskSchedulerG.buildInputWire("inputG"); + + final TaskScheduler taskSchedulerH = + model.schedulerBuilder("H").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputH = taskSchedulerH.buildInputWire("inputH"); + + final TaskScheduler taskSchedulerI = + model.schedulerBuilder("I").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputI = taskSchedulerI.buildInputWire("inputI"); + + final TaskScheduler taskSchedulerJ = model.schedulerBuilder("J") + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .build() + .cast(); + final InputWire inputJ = taskSchedulerJ.buildInputWire("inputJ"); + + taskSchedulerA.getOutputWire().solderTo(inputB); + taskSchedulerB.getOutputWire().solderTo(inputC); + taskSchedulerC.getOutputWire().solderTo(inputD); + taskSchedulerD.getOutputWire().solderTo(inputE); + taskSchedulerE.getOutputWire().solderTo(inputF); + taskSchedulerF.getOutputWire().solderTo(inputG); + taskSchedulerG.getOutputWire().solderTo(inputD); + + taskSchedulerF.getOutputWire().solderTo(inputH); + taskSchedulerH.getOutputWire().solderTo(inputI); + taskSchedulerI.getOutputWire().solderTo(inputJ); + + taskSchedulerJ.getOutputWire().solderTo(inputA); + + taskSchedulerI.getOutputWire().solderTo(inputE); + + validateModel(model, false, false); + } + + @Test + void filterInCycleTest() { + final WiringModel model = WiringModelBuilder.create( + TestPlatformContextBuilder.create().build()) + .build(); + + /* + + A + | + v + B + | + v + C + | + v + D -----> E + ^ | + | v + G <----- F -----> H -----> I -----> J + + Connection D -> E uses a filter + + */ + + final TaskScheduler taskSchedulerA = + model.schedulerBuilder("A").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputA = taskSchedulerA.buildInputWire("inputA"); + + final TaskScheduler taskSchedulerB = + model.schedulerBuilder("B").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputB = taskSchedulerB.buildInputWire("inputB"); + + final TaskScheduler taskSchedulerC = + model.schedulerBuilder("C").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputC = taskSchedulerC.buildInputWire("inputC"); + + final TaskScheduler taskSchedulerD = + model.schedulerBuilder("D").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputD = taskSchedulerD.buildInputWire("inputD"); + + final TaskScheduler taskSchedulerE = + model.schedulerBuilder("E").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputE = taskSchedulerE.buildInputWire("inputE"); + + final TaskScheduler taskSchedulerF = + model.schedulerBuilder("F").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputF = taskSchedulerF.buildInputWire("inputF"); + + final TaskScheduler taskSchedulerG = + model.schedulerBuilder("G").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputG = taskSchedulerG.buildInputWire("inputG"); + + final TaskScheduler taskSchedulerH = + model.schedulerBuilder("H").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputH = taskSchedulerH.buildInputWire("inputH"); + + final TaskScheduler taskSchedulerI = + model.schedulerBuilder("I").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputI = taskSchedulerI.buildInputWire("inputI"); + + final TaskScheduler taskSchedulerJ = + model.schedulerBuilder("J").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputJ = taskSchedulerJ.buildInputWire(""); + + taskSchedulerA.getOutputWire().solderTo(inputB); + taskSchedulerB.getOutputWire().solderTo(inputC); + taskSchedulerC.getOutputWire().solderTo(inputD); + taskSchedulerD + .getOutputWire() + .buildFilter("onlyEven", "onlyEvenInput", x -> x % 2 == 0) + .solderTo(inputE); + taskSchedulerE.getOutputWire().solderTo(inputF); + taskSchedulerF.getOutputWire().solderTo(inputG); + taskSchedulerG.getOutputWire().solderTo(inputD); + + taskSchedulerF.getOutputWire().solderTo(inputH); + taskSchedulerH.getOutputWire().solderTo(inputI); + taskSchedulerI.getOutputWire().solderTo(inputJ); + + validateModel(model, true, false); + } + + @Test + void transformerInCycleTest() { + final WiringModel model = WiringModelBuilder.create( + TestPlatformContextBuilder.create().build()) + .build(); + + /* + + A + | + v + B + | + v + C + | + v + D -----> E + ^ | + | v + G <----- F -----> H -----> I -----> J + + Connection D -> E uses a transformer + + */ + + final TaskScheduler taskSchedulerA = + model.schedulerBuilder("A").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputA = taskSchedulerA.buildInputWire("inputA"); + + final TaskScheduler taskSchedulerB = + model.schedulerBuilder("B").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputB = taskSchedulerB.buildInputWire("inputB"); + + final TaskScheduler taskSchedulerC = + model.schedulerBuilder("C").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputC = taskSchedulerC.buildInputWire("inputC"); + + final TaskScheduler taskSchedulerD = + model.schedulerBuilder("D").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputD = taskSchedulerD.buildInputWire("inputD"); + + final TaskScheduler taskSchedulerE = + model.schedulerBuilder("E").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputE = taskSchedulerE.buildInputWire("inputE"); + + final TaskScheduler taskSchedulerF = + model.schedulerBuilder("F").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputF = taskSchedulerF.buildInputWire("inputF"); + + final TaskScheduler taskSchedulerG = + model.schedulerBuilder("G").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputG = taskSchedulerG.buildInputWire("inputG"); + + final TaskScheduler taskSchedulerH = + model.schedulerBuilder("H").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputH = taskSchedulerH.buildInputWire("inputH"); + + final TaskScheduler taskSchedulerI = + model.schedulerBuilder("I").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputI = taskSchedulerI.buildInputWire("inputI"); + + final TaskScheduler taskSchedulerJ = + model.schedulerBuilder("J").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputJ = taskSchedulerJ.buildInputWire(""); + + taskSchedulerA.getOutputWire().solderTo(inputB); + taskSchedulerB.getOutputWire().solderTo(inputC); + taskSchedulerC.getOutputWire().solderTo(inputD); + taskSchedulerD + .getOutputWire() + .buildTransformer("inverter", "inverterInput", x -> -x) + .solderTo(inputE); + taskSchedulerE.getOutputWire().solderTo(inputF); + taskSchedulerF.getOutputWire().solderTo(inputG); + taskSchedulerG.getOutputWire().solderTo(inputD); + + taskSchedulerF.getOutputWire().solderTo(inputH); + taskSchedulerH.getOutputWire().solderTo(inputI); + taskSchedulerI.getOutputWire().solderTo(inputJ); + + validateModel(model, true, false); + } + + @Test + void splitterInCycleTest() { + final WiringModel model = WiringModelBuilder.create( + TestPlatformContextBuilder.create().build()) + .build(); + + /* + + A + | + v + B + | + v + C + | + v + D -----> E + ^ | + | v + G <----- F -----> H -----> I -----> J + + Connection D -> E uses a splitter + + */ + + final TaskScheduler taskSchedulerA = + model.schedulerBuilder("A").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputA = taskSchedulerA.buildInputWire("inputA"); + + final TaskScheduler taskSchedulerB = + model.schedulerBuilder("B").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputB = taskSchedulerB.buildInputWire("inputB"); + + final TaskScheduler taskSchedulerC = + model.schedulerBuilder("C").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputC = taskSchedulerC.buildInputWire("inputC"); + + final TaskScheduler> taskSchedulerD = + model.schedulerBuilder("D").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputD = taskSchedulerD.buildInputWire("inputD"); + + final TaskScheduler taskSchedulerE = + model.schedulerBuilder("E").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputE = taskSchedulerE.buildInputWire("inputE"); + + final TaskScheduler taskSchedulerF = + model.schedulerBuilder("F").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputF = taskSchedulerF.buildInputWire("inputF"); + + final TaskScheduler taskSchedulerG = + model.schedulerBuilder("G").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputG = taskSchedulerG.buildInputWire("inputG"); + + final TaskScheduler taskSchedulerH = + model.schedulerBuilder("H").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputH = taskSchedulerH.buildInputWire("inputH"); + + final TaskScheduler taskSchedulerI = + model.schedulerBuilder("I").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputI = taskSchedulerI.buildInputWire("inputI"); + + final TaskScheduler taskSchedulerJ = + model.schedulerBuilder("J").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputJ = taskSchedulerJ.buildInputWire(""); + + taskSchedulerA.getOutputWire().solderTo(inputB); + taskSchedulerB.getOutputWire().solderTo(inputC); + taskSchedulerC.getOutputWire().solderTo(inputD); + final OutputWire splitter = taskSchedulerD.getOutputWire().buildSplitter("splitter", "splitterInput"); + splitter.solderTo(inputE); + taskSchedulerE.getOutputWire().solderTo(inputF); + taskSchedulerF.getOutputWire().solderTo(inputG); + taskSchedulerG.getOutputWire().solderTo(inputD); + + taskSchedulerF.getOutputWire().solderTo(inputH); + taskSchedulerH.getOutputWire().solderTo(inputI); + taskSchedulerI.getOutputWire().solderTo(inputJ); + + validateModel(model, true, false); + } + + @Test + void multipleOutputCycleTest() { + final WiringModel model = WiringModelBuilder.create( + TestPlatformContextBuilder.create().build()) + .build(); + + /* + + A <---------------------------------| + | | + v | + B | + | | + v | + C | + | | + v | + D -----> E <---------------| | + ^ | | | + | v | | + G <----- F -----> H -----> I -----> J + | ^ + | | + |--------| + + I has secondary output channels + + */ + + final TaskScheduler taskSchedulerA = + model.schedulerBuilder("A").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputA = taskSchedulerA.buildInputWire("inputA"); + + final TaskScheduler taskSchedulerB = + model.schedulerBuilder("B").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputB = taskSchedulerB.buildInputWire("inputB"); + + final TaskScheduler taskSchedulerC = + model.schedulerBuilder("C").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputC = taskSchedulerC.buildInputWire("inputC"); + + final TaskScheduler taskSchedulerD = + model.schedulerBuilder("D").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputD = taskSchedulerD.buildInputWire("inputD"); + + final TaskScheduler taskSchedulerE = + model.schedulerBuilder("E").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputE = taskSchedulerE.buildInputWire("inputE"); + + final TaskScheduler taskSchedulerF = + model.schedulerBuilder("F").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputF = taskSchedulerF.buildInputWire("inputF"); + + final TaskScheduler taskSchedulerG = + model.schedulerBuilder("G").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputG = taskSchedulerG.buildInputWire("inputG"); + + final TaskScheduler taskSchedulerH = + model.schedulerBuilder("H").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputH = taskSchedulerH.buildInputWire("inputH"); + + final TaskScheduler taskSchedulerI = + model.schedulerBuilder("I").withUnhandledTaskCapacity(1).build().cast(); + final OutputWire secondaryOutputI = taskSchedulerI.buildSecondaryOutputWire(); + final OutputWire tertiaryOutputI = taskSchedulerI.buildSecondaryOutputWire(); + final InputWire inputI = taskSchedulerI.buildInputWire("inputI"); + + final TaskScheduler taskSchedulerJ = + model.schedulerBuilder("J").withUnhandledTaskCapacity(1).build().cast(); + final InputWire inputJ = taskSchedulerJ.buildInputWire("inputJ"); + final InputWire inputJ2 = taskSchedulerJ.buildInputWire("inputJ2"); + + taskSchedulerA.getOutputWire().solderTo(inputB); + taskSchedulerB.getOutputWire().solderTo(inputC); + taskSchedulerC.getOutputWire().solderTo(inputD); + taskSchedulerD.getOutputWire().solderTo(inputE); + taskSchedulerE.getOutputWire().solderTo(inputF); + taskSchedulerF.getOutputWire().solderTo(inputG); + taskSchedulerG.getOutputWire().solderTo(inputD); + + taskSchedulerF.getOutputWire().solderTo(inputH); + taskSchedulerH.getOutputWire().solderTo(inputI); + taskSchedulerI.getOutputWire().solderTo(inputJ); + + taskSchedulerJ.getOutputWire().solderTo(inputA); + + secondaryOutputI.solderTo(inputE); + tertiaryOutputI.solderTo(inputJ2); + + validateModel(model, true, false); + } + + /** + * We should detect when a concurrent scheduler access a direct scheduler. + */ + @Test + void concurrentAccessingDirectTest() { + final WiringModel model = WiringModelBuilder.create( + TestPlatformContextBuilder.create().build()) + .build(); + + /* + + A + | + v + B + | + v + C + | + v + D -----> E + ^ | + | v + G <----- F -----> H -----> I -----> J + + D = CONCURRENT + E = DIRECT + + */ + + final TaskScheduler taskSchedulerA = model.schedulerBuilder("A") + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .build() + .cast(); + final InputWire inputA = taskSchedulerA.buildInputWire("inputA"); + + final TaskScheduler taskSchedulerB = model.schedulerBuilder("B") + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .build() + .cast(); + final InputWire inputB = taskSchedulerB.buildInputWire("inputB"); + + final TaskScheduler taskSchedulerC = model.schedulerBuilder("C") + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .build() + .cast(); + final InputWire inputC = taskSchedulerC.buildInputWire("inputC"); + + final TaskScheduler taskSchedulerD = model.schedulerBuilder("D") + .withType(TaskSchedulerType.CONCURRENT) + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .build() + .cast(); + final InputWire inputD = taskSchedulerD.buildInputWire("inputD"); + + final TaskScheduler taskSchedulerE = model.schedulerBuilder("E") + .withType(TaskSchedulerType.DIRECT) + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .build() + .cast(); + final InputWire inputE = taskSchedulerE.buildInputWire("inputE"); + + final TaskScheduler taskSchedulerF = model.schedulerBuilder("F") + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .build() + .cast(); + final InputWire inputF = taskSchedulerF.buildInputWire("inputF"); + + final TaskScheduler taskSchedulerG = model.schedulerBuilder("G") + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .build() + .cast(); + final InputWire inputG = taskSchedulerG.buildInputWire("inputG"); + + final TaskScheduler taskSchedulerH = model.schedulerBuilder("H") + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .build() + .cast(); + final InputWire inputH = taskSchedulerH.buildInputWire("inputH"); + + final TaskScheduler taskSchedulerI = model.schedulerBuilder("I") + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .build() + .cast(); + final InputWire inputI = taskSchedulerI.buildInputWire("inputI"); + + final TaskScheduler taskSchedulerJ = model.schedulerBuilder("J") + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .build() + .cast(); + final InputWire inputJ = taskSchedulerJ.buildInputWire("inputJ"); + + taskSchedulerA.getOutputWire().solderTo(inputB); + taskSchedulerB.getOutputWire().solderTo(inputC); + taskSchedulerC.getOutputWire().solderTo(inputD); + taskSchedulerD.getOutputWire().solderTo(inputE); + taskSchedulerE.getOutputWire().solderTo(inputF); + taskSchedulerF.getOutputWire().solderTo(inputG); + taskSchedulerG.getOutputWire().solderTo(inputD); + + taskSchedulerF.getOutputWire().solderTo(inputH); + taskSchedulerH.getOutputWire().solderTo(inputI); + taskSchedulerI.getOutputWire().solderTo(inputJ); + + validateModel(model, false, true); + } + + /** + * We should detect when a concurrent scheduler access a direct scheduler. + */ + @Test + void concurrentAccessingMultipleDirectTest() { + final WiringModel model = WiringModelBuilder.create( + TestPlatformContextBuilder.create().build()) + .build(); + + /* + + A + | + v + B + | + v + C + | + v + D -----> E + ^ | + | v + G <----- F -----> H -----> I -----> J + + D = CONCURRENT + E = DIRECT + F = DIRECT + + */ + + final TaskScheduler taskSchedulerA = model.schedulerBuilder("A") + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .build() + .cast(); + final InputWire inputA = taskSchedulerA.buildInputWire("inputA"); + + final TaskScheduler taskSchedulerB = model.schedulerBuilder("B") + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .build() + .cast(); + final InputWire inputB = taskSchedulerB.buildInputWire("inputB"); + + final TaskScheduler taskSchedulerC = model.schedulerBuilder("C") + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .build() + .cast(); + final InputWire inputC = taskSchedulerC.buildInputWire("inputC"); + + final TaskScheduler taskSchedulerD = model.schedulerBuilder("D") + .withType(TaskSchedulerType.CONCURRENT) + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .build() + .cast(); + final InputWire inputD = taskSchedulerD.buildInputWire("inputD"); + + final TaskScheduler taskSchedulerE = model.schedulerBuilder("E") + .withType(TaskSchedulerType.DIRECT) + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .build() + .cast(); + final InputWire inputE = taskSchedulerE.buildInputWire("inputE"); + + final TaskScheduler taskSchedulerF = model.schedulerBuilder("F") + .withType(TaskSchedulerType.DIRECT) + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .build() + .cast(); + final InputWire inputF = taskSchedulerF.buildInputWire("inputF"); + + final TaskScheduler taskSchedulerG = model.schedulerBuilder("G") + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .build() + .cast(); + final InputWire inputG = taskSchedulerG.buildInputWire("inputG"); + + final TaskScheduler taskSchedulerH = model.schedulerBuilder("H") + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .build() + .cast(); + final InputWire inputH = taskSchedulerH.buildInputWire("inputH"); + + final TaskScheduler taskSchedulerI = model.schedulerBuilder("I") + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .build() + .cast(); + final InputWire inputI = taskSchedulerI.buildInputWire("inputI"); + + final TaskScheduler taskSchedulerJ = model.schedulerBuilder("J") + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .build() + .cast(); + final InputWire inputJ = taskSchedulerJ.buildInputWire("inputJ"); + + taskSchedulerA.getOutputWire().solderTo(inputB); + taskSchedulerB.getOutputWire().solderTo(inputC); + taskSchedulerC.getOutputWire().solderTo(inputD); + taskSchedulerD.getOutputWire().solderTo(inputE); + taskSchedulerE.getOutputWire().solderTo(inputF); + taskSchedulerF.getOutputWire().solderTo(inputG); + taskSchedulerG.getOutputWire().solderTo(inputD); + + taskSchedulerF.getOutputWire().solderTo(inputH); + taskSchedulerH.getOutputWire().solderTo(inputI); + taskSchedulerI.getOutputWire().solderTo(inputJ); + + validateModel(model, false, true); + } + + /** + * We should detect when a concurrent scheduler access a direct scheduler through proxies (i.e. the concurrent + * scheduler calls into a DIRECT_THREADSAFE scheduler which calls into a DIRECT scheduler). + */ + @Test + void concurrentAccessingDirectThroughProxyTest() { + final WiringModel model = WiringModelBuilder.create( + TestPlatformContextBuilder.create().build()) + .build(); + + /* + + A + | + v + B + | + v + C + | + v + D -----> E + ^ | + | v + G <----- F -----> H -----> I -----> J + + D = CONCURRENT + E = DIRECT_THREADSAFE + F = DIRECT_THREADSAFE + G = DIRECT + + */ + + final TaskScheduler taskSchedulerA = model.schedulerBuilder("A") + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .build() + .cast(); + final InputWire inputA = taskSchedulerA.buildInputWire("inputA"); + + final TaskScheduler taskSchedulerB = model.schedulerBuilder("B") + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .build() + .cast(); + final InputWire inputB = taskSchedulerB.buildInputWire("inputB"); + + final TaskScheduler taskSchedulerC = + model.schedulerBuilder("C").build().cast(); + final InputWire inputC = taskSchedulerC.buildInputWire("inputC"); + + final TaskScheduler taskSchedulerD = model.schedulerBuilder("D") + .withType(TaskSchedulerType.CONCURRENT) + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .build() + .cast(); + final InputWire inputD = taskSchedulerD.buildInputWire("inputD"); + + final TaskScheduler taskSchedulerE = model.schedulerBuilder("E") + .withType(TaskSchedulerType.DIRECT_THREADSAFE) + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .build() + .cast(); + final InputWire inputE = taskSchedulerE.buildInputWire("inputE"); + + final TaskScheduler taskSchedulerF = model.schedulerBuilder("F") + .withType(TaskSchedulerType.DIRECT_THREADSAFE) + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .build() + .cast(); + final InputWire inputF = taskSchedulerF.buildInputWire("inputF"); + + final TaskScheduler taskSchedulerG = model.schedulerBuilder("G") + .withType(TaskSchedulerType.DIRECT) + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .build() + .cast(); + final InputWire inputG = taskSchedulerG.buildInputWire("inputG"); + + final TaskScheduler taskSchedulerH = model.schedulerBuilder("H") + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .build() + .cast(); + final InputWire inputH = taskSchedulerH.buildInputWire("inputH"); + + final TaskScheduler taskSchedulerI = model.schedulerBuilder("I") + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .build() + .cast(); + final InputWire inputI = taskSchedulerI.buildInputWire("inputI"); + + final TaskScheduler taskSchedulerJ = model.schedulerBuilder("J") + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .build() + .cast(); + final InputWire inputJ = taskSchedulerJ.buildInputWire("inputJ"); + + taskSchedulerA.getOutputWire().solderTo(inputB); + taskSchedulerB.getOutputWire().solderTo(inputC); + taskSchedulerC.getOutputWire().solderTo(inputD); + taskSchedulerD.getOutputWire().solderTo(inputE); + taskSchedulerE.getOutputWire().solderTo(inputF); + taskSchedulerF.getOutputWire().solderTo(inputG); + taskSchedulerG.getOutputWire().solderTo(inputD); + + taskSchedulerF.getOutputWire().solderTo(inputH); + taskSchedulerH.getOutputWire().solderTo(inputI); + taskSchedulerI.getOutputWire().solderTo(inputJ); + + validateModel(model, false, true); + } + + /** + * We should detect when multiple sequential schedulers call into a scheduler. + */ + @Test + void multipleSequentialSchedulerTest() { + final WiringModel model = WiringModelBuilder.create( + TestPlatformContextBuilder.create().build()) + .build(); + + /* + + A + | + v + B + | + v + C + | + v + D -----> E + ^ | + | v + G <----- F -----> H -----> I -----> J + + B = SEQUENTIAL_THREAD + C = DIRECT_THREADSAFE + D = DIRECT + + */ + + final TaskScheduler taskSchedulerA = + model.schedulerBuilder("A").build().cast(); + final InputWire inputA = taskSchedulerA.buildInputWire("inputA"); + + final TaskScheduler taskSchedulerB = model.schedulerBuilder("B") + .withType(TaskSchedulerType.SEQUENTIAL_THREAD) + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .build() + .cast(); + final InputWire inputB = taskSchedulerB.buildInputWire("inputB"); + + final TaskScheduler taskSchedulerC = model.schedulerBuilder("C") + .withType(TaskSchedulerType.DIRECT_THREADSAFE) + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .build() + .cast(); + final InputWire inputC = taskSchedulerC.buildInputWire("inputC"); + + final TaskScheduler taskSchedulerD = model.schedulerBuilder("D") + .withType(TaskSchedulerType.DIRECT) + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .build() + .cast(); + final InputWire inputD = taskSchedulerD.buildInputWire("inputD"); + + final TaskScheduler taskSchedulerE = model.schedulerBuilder("E") + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .build() + .cast(); + final InputWire inputE = taskSchedulerE.buildInputWire("inputE"); + + final TaskScheduler taskSchedulerF = model.schedulerBuilder("F") + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .build() + .cast(); + final InputWire inputF = taskSchedulerF.buildInputWire("inputF"); + + final TaskScheduler taskSchedulerG = model.schedulerBuilder("G") + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .build() + .cast(); + final InputWire inputG = taskSchedulerG.buildInputWire("inputG"); + + final TaskScheduler taskSchedulerH = model.schedulerBuilder("H") + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .build() + .cast(); + final InputWire inputH = taskSchedulerH.buildInputWire("inputH"); + + final TaskScheduler taskSchedulerI = model.schedulerBuilder("I") + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .build() + .cast(); + final InputWire inputI = taskSchedulerI.buildInputWire("inputI"); + + final TaskScheduler taskSchedulerJ = model.schedulerBuilder("J") + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .build() + .cast(); + final InputWire inputJ = taskSchedulerJ.buildInputWire("inputJ"); + + taskSchedulerA.getOutputWire().solderTo(inputB); + taskSchedulerB.getOutputWire().solderTo(inputC); + taskSchedulerC.getOutputWire().solderTo(inputD); + taskSchedulerD.getOutputWire().solderTo(inputE); + taskSchedulerE.getOutputWire().solderTo(inputF); + taskSchedulerF.getOutputWire().solderTo(inputG); + taskSchedulerG.getOutputWire().solderTo(inputD); + + taskSchedulerF.getOutputWire().solderTo(inputH); + taskSchedulerH.getOutputWire().solderTo(inputI); + taskSchedulerI.getOutputWire().solderTo(inputJ); + + validateModel(model, false, true); + } + + @Test + void unboundInputWireTest() { + final WiringModel model = WiringModelBuilder.create( + TestPlatformContextBuilder.create().build()) + .build(); + + final TaskScheduler taskSchedulerA = model.schedulerBuilder("A") + .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) + .build() + .cast(); + final BindableInputWire inputA = taskSchedulerA.buildInputWire("inputA"); + + assertTrue(model.checkForUnboundInputWires()); + + inputA.bindConsumer(x -> {}); + + model.start(); + assertFalse(model.checkForUnboundInputWires()); + model.stop(); + } +} diff --git a/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/model/internal/monitor/HealthMonitorTests.java b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/model/internal/monitor/HealthMonitorTests.java new file mode 100644 index 00000000000..365e9922de3 --- /dev/null +++ b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/model/internal/monitor/HealthMonitorTests.java @@ -0,0 +1,236 @@ +/* + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC + * + * 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 org.hiero.wiring.framework.model.internal.monitor; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import com.swirlds.base.test.fixtures.time.FakeTime; +import com.swirlds.common.context.PlatformContext; +import com.swirlds.common.test.fixtures.Randotron; +import com.swirlds.common.test.fixtures.platform.TestPlatformContextBuilder; +import com.swirlds.common.utility.CompareTo; +import edu.umd.cs.findbugs.annotations.NonNull; +import java.time.Duration; +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.junit.jupiter.api.Test; + +class HealthMonitorTests { + + /** + * Build a mock task scheduler. + * + * @param healthy when the value of this atomic boolean is true, the task scheduler is healthy; otherwise, it is + * unhealthy. + * @return a mock task scheduler + */ + @NonNull + private static TaskScheduler buildMockScheduler(final AtomicBoolean healthy) { + final TaskScheduler taskScheduler = mock(TaskScheduler.class); + when(taskScheduler.getCapacity()).thenReturn(10L); + when(taskScheduler.getUnprocessedTaskCount()).thenAnswer(invocation -> healthy.get() ? 5L : 15L); + return taskScheduler; + } + + @Test + void healthyBehaviorTest() { + final Randotron randotron = Randotron.create(); + + final int schedulerCount = randotron.nextInt(10, 20); + + final List> schedulers = new ArrayList<>(); + + for (int i = 0; i < schedulerCount; i++) { + final AtomicBoolean healthy = new AtomicBoolean(true); + final TaskScheduler scheduler = buildMockScheduler(healthy); + schedulers.add(scheduler); + } + + final Instant startTime = randotron.nextInstant(); + final FakeTime time = new FakeTime(startTime, Duration.ZERO); + final PlatformContext platformContext = + TestPlatformContextBuilder.create().withTime(time).build(); + + final HealthMonitor healthMonitor = + new HealthMonitor(platformContext, schedulers, Duration.ofSeconds(5), Duration.ofDays(10000)); + + final Instant endTime = startTime.plus(Duration.ofSeconds(10)); + while (time.now().isBefore(endTime)) { + assertNull(healthMonitor.checkSystemHealth(time.now())); + time.tick(Duration.ofMinutes(randotron.nextInt(1, 1000))); + assertEquals(Duration.ZERO, healthMonitor.getUnhealthyDuration()); + } + } + + @Test + void oneUnhealthySchedulerTest() { + final Randotron randotron = Randotron.create(); + + final int schedulerCount = randotron.nextInt(10, 20); + + final List> schedulers = new ArrayList<>(); + final List schedulerHealths = new ArrayList<>(); + + for (int i = 0; i < schedulerCount; i++) { + final AtomicBoolean healthy = new AtomicBoolean(true); + final TaskScheduler scheduler = buildMockScheduler(healthy); + schedulers.add(scheduler); + schedulerHealths.add(healthy); + } + + final Instant startTime = randotron.nextInstant(); + final FakeTime time = new FakeTime(startTime, Duration.ZERO); + final PlatformContext platformContext = + TestPlatformContextBuilder.create().withTime(time).build(); + + final HealthMonitor healthMonitor = + new HealthMonitor(platformContext, schedulers, Duration.ofSeconds(5), Duration.ofDays(10000)); + + final Instant phase1EndTime = startTime.plus(Duration.ofSeconds(10)); + while (time.now().isBefore(phase1EndTime)) { + assertNull(healthMonitor.checkSystemHealth(time.now())); + time.tick(Duration.ofMillis(randotron.nextInt(1, 1000))); + assertEquals(Duration.ZERO, healthMonitor.getUnhealthyDuration()); + } + + final Instant unhealthyStartTime = time.now(); + final int unhealthyIndex = randotron.nextInt(0, schedulerCount); + schedulerHealths.get(unhealthyIndex).set(false); + + final Instant phase2EndTime = time.now().plus(Duration.ofSeconds(10)); + while (time.now().isBefore(phase2EndTime)) { + final Duration unhealthyTime = Duration.between(unhealthyStartTime, time.now()); + + final Duration healthReport = healthMonitor.checkSystemHealth(time.now()); + if (CompareTo.isGreaterThan(unhealthyTime, Duration.ZERO)) { + assertEquals(unhealthyTime, healthReport); + } else { + assertNull(healthReport); + } + time.tick(Duration.ofMillis(randotron.nextInt(1, 1000))); + assertEquals(unhealthyTime, healthMonitor.getUnhealthyDuration()); + } + + // Make the scheduler healthy again. We should see a single report of 0s, followed by nulls. + schedulerHealths.get(unhealthyIndex).set(true); + assertEquals(Duration.ZERO, healthMonitor.checkSystemHealth(time.now())); + + final Instant phase3EndTime = time.now().plus(Duration.ofSeconds(10)); + while (time.now().isBefore(phase3EndTime)) { + assertNull(healthMonitor.checkSystemHealth(time.now())); + time.tick(Duration.ofMillis(randotron.nextInt(1, 1000))); + assertEquals(Duration.ZERO, healthMonitor.getUnhealthyDuration()); + } + } + + @Test + void multipleUnhealthySchedulersTest() { + final Randotron randotron = Randotron.create(); + + final int schedulerCount = randotron.nextInt(10, 20); + + final List> schedulers = new ArrayList<>(); + final List schedulerHealths = new ArrayList<>(); + + for (int i = 0; i < schedulerCount; i++) { + final AtomicBoolean healthy = new AtomicBoolean(true); + final TaskScheduler scheduler = buildMockScheduler(healthy); + schedulers.add(scheduler); + schedulerHealths.add(healthy); + } + + final Instant startTime = randotron.nextInstant(); + final FakeTime time = new FakeTime(startTime, Duration.ZERO); + final PlatformContext platformContext = + TestPlatformContextBuilder.create().withTime(time).build(); + + final HealthMonitor healthMonitor = + new HealthMonitor(platformContext, schedulers, Duration.ofSeconds(5), Duration.ofDays(10000)); + + final Instant phase1EndTime = startTime.plus(Duration.ofSeconds(10)); + while (time.now().isBefore(phase1EndTime)) { + assertNull(healthMonitor.checkSystemHealth(time.now())); + time.tick(Duration.ofMillis(randotron.nextInt(1, 1000))); + assertEquals(Duration.ZERO, healthMonitor.getUnhealthyDuration()); + } + + final Instant unhealthyStartTimeA = time.now(); + final int unhealthyIndexA = randotron.nextInt(0, schedulerCount); + schedulerHealths.get(unhealthyIndexA).set(false); + + final Instant phase2EndTime = time.now().plus(Duration.ofSeconds(10)); + while (time.now().isBefore(phase2EndTime)) { + final Duration unhealthyTime = Duration.between(unhealthyStartTimeA, time.now()); + + final Duration healthReport = healthMonitor.checkSystemHealth(time.now()); + if (CompareTo.isGreaterThan(unhealthyTime, Duration.ZERO)) { + assertEquals(unhealthyTime, healthReport); + } else { + assertNull(healthReport); + } + time.tick(Duration.ofMillis(randotron.nextInt(1, 1000))); + assertEquals(unhealthyTime, healthMonitor.getUnhealthyDuration()); + } + + // Make another scheduler unhealthy. It should be overshadowed by the first unhealthy scheduler. + final Instant unhealthyStartTimeB = time.now(); + final int unhealthyIndexB = (unhealthyIndexA + 1) % schedulerCount; + schedulerHealths.get(unhealthyIndexB).set(false); + + final Instant phase3EndTime = time.now().plus(Duration.ofSeconds(10)); + while (time.now().isBefore(phase3EndTime)) { + final Duration unhealthyTime = Duration.between(unhealthyStartTimeA, time.now()); + + final Duration healthReport = healthMonitor.checkSystemHealth(time.now()); + assertEquals(unhealthyTime, healthReport); + + time.tick(Duration.ofMillis(randotron.nextInt(1, 1000))); + assertEquals(unhealthyTime, healthMonitor.getUnhealthyDuration()); + } + + // Make the first scheduler healthy again. This will allow us to see the unhealthy time of the second scheduler. + schedulerHealths.get(unhealthyIndexA).set(true); + + final Instant phase4EndTime = time.now().plus(Duration.ofSeconds(10)); + while (time.now().isBefore(phase4EndTime)) { + final Duration unhealthyTime = Duration.between(unhealthyStartTimeB, time.now()); + + final Duration healthReport = healthMonitor.checkSystemHealth(time.now()); + assertEquals(unhealthyTime, healthReport); + + time.tick(Duration.ofMillis(randotron.nextInt(1, 1000))); + assertEquals(unhealthyTime, healthMonitor.getUnhealthyDuration()); + } + + // Make the second scheduler healthy again. System should return to normal. + schedulerHealths.get(unhealthyIndexB).set(true); + assertEquals(Duration.ZERO, healthMonitor.checkSystemHealth(time.now())); + + final Instant phase5EndTime = time.now().plus(Duration.ofSeconds(10)); + while (time.now().isBefore(phase5EndTime)) { + assertNull(healthMonitor.checkSystemHealth(time.now())); + time.tick(Duration.ofMillis(randotron.nextInt(1, 1000))); + assertEquals(Duration.ZERO, healthMonitor.getUnhealthyDuration()); + } + } +} diff --git a/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/schedulers/NoOpTaskSchedulerTests.java b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/schedulers/NoOpTaskSchedulerTests.java new file mode 100644 index 00000000000..c73f14bff3a --- /dev/null +++ b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/schedulers/NoOpTaskSchedulerTests.java @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC + * + * 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 org.hiero.wiring.framework.schedulers; + +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.NO_OP; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import com.swirlds.common.context.PlatformContext; +import com.swirlds.common.test.fixtures.platform.TestPlatformContextBuilder; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.model.WiringModelBuilder; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.wires.SolderType; +import org.hiero.wiring.framework.wires.input.BindableInputWire; +import org.hiero.wiring.framework.wires.output.OutputWire; +import org.junit.jupiter.api.Test; + +class NoOpTaskSchedulerTests { + + @Test + void nothingHappensTest() { + final PlatformContext platformContext = + TestPlatformContextBuilder.create().build(); + final WiringModel model = WiringModelBuilder.create(platformContext).build(); + + final TaskScheduler> realFakeScheduler = + model.schedulerBuilder("A").withType(NO_OP).build().cast(); + + final AtomicBoolean shouldAlwaysBeFalse = new AtomicBoolean(false); + + final BindableInputWire> inA = realFakeScheduler.buildInputWire("inA"); + inA.bindConsumer((value) -> shouldAlwaysBeFalse.set(true)); + + final BindableInputWire> inB = realFakeScheduler.buildInputWire("inB"); + inB.bind((value) -> { + shouldAlwaysBeFalse.set(true); + return List.of(1, 2, 3); + }); + + final OutputWire> transformer = realFakeScheduler + .getOutputWire() + .buildTransformer("transformer", "transformer input", (value) -> { + shouldAlwaysBeFalse.set(true); + return List.of(1, 2, 3); + }); + + final OutputWire> filter = realFakeScheduler + .getOutputWire() + .buildFilter("filter", "filter input", (value) -> { + shouldAlwaysBeFalse.set(true); + return true; + }); + + final OutputWire splitter = + realFakeScheduler.getOutputWire().buildSplitter("splitter", "splitter input"); + splitter.solderTo("handler", "handler input", value -> shouldAlwaysBeFalse.set(true)); + + // Solder the fake scheduler to a real one. No data should be passed. + final TaskScheduler realScheduler = model.schedulerBuilder("B") + .withType(TaskSchedulerType.DIRECT) + .build() + .cast(); + + final BindableInputWire, Void> realInA = realScheduler.buildInputWire("realInA"); + realInA.bindConsumer((value) -> shouldAlwaysBeFalse.set(true)); + realFakeScheduler.getOutputWire().solderTo(realInA, SolderType.PUT); + realFakeScheduler.getOutputWire().solderTo(realInA, SolderType.OFFER); + realFakeScheduler.getOutputWire().solderTo(realInA, SolderType.INJECT); + transformer.solderTo(realInA, SolderType.PUT); + transformer.solderTo(realInA, SolderType.OFFER); + transformer.solderTo(realInA, SolderType.INJECT); + filter.solderTo(realInA, SolderType.PUT); + filter.solderTo(realInA, SolderType.OFFER); + filter.solderTo(realInA, SolderType.INJECT); + + final BindableInputWire realInB = realScheduler.buildInputWire("realInB"); + realInB.bindConsumer((value) -> shouldAlwaysBeFalse.set(true)); + splitter.solderTo(realInB, SolderType.PUT); + splitter.solderTo(realInB, SolderType.OFFER); + splitter.solderTo(realInB, SolderType.INJECT); + + inA.put(1); + assertTrue(inA.offer(1)); + inA.inject(1); + + inB.put(1); + assertTrue(inB.offer(1)); + inB.inject(1); + + assertFalse(shouldAlwaysBeFalse.get()); + assertEquals(0, realFakeScheduler.getUnprocessedTaskCount()); + } +} diff --git a/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/transformers/WireRouterTests.java b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/transformers/WireRouterTests.java new file mode 100644 index 00000000000..49aa5a24eaf --- /dev/null +++ b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/transformers/WireRouterTests.java @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC + * + * 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 org.hiero.wiring.framework.transformers; + +import static com.swirlds.common.test.fixtures.RandomUtils.getRandomPrintSeed; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.swirlds.common.context.PlatformContext; +import com.swirlds.common.test.fixtures.platform.TestPlatformContextBuilder; +import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Random; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicLong; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.model.WiringModelBuilder; +import org.hiero.wiring.framework.wires.output.OutputWire; +import org.junit.jupiter.api.Test; + +class WireRouterTests { + + private enum TestDataType { + FOO, // Long values + BAR, // Long values + BAZ; // Boolean values + + /** + * Create a new {@link RoutableData} object with the given data. + * + * @param data the data + * @return the new {@link RoutableData} object + */ + @NonNull + public RoutableData of(@NonNull final Object data) { + return new RoutableData<>(this, data); + } + } + + @Test + void basicBehaviorTest() { + final Random random = getRandomPrintSeed(); + + final PlatformContext platformContext = + TestPlatformContextBuilder.create().build(); + final WiringModel model = WiringModelBuilder.create(platformContext).build(); + + final WireRouter router = new WireRouter<>(model, "router", "router input", TestDataType.class); + + final AtomicLong latestFoo = new AtomicLong(); + final AtomicLong latestBar = new AtomicLong(); + final AtomicBoolean latestBaz = new AtomicBoolean(); + + final OutputWire fooOutput = router.getOutput(TestDataType.FOO); + final OutputWire barOutput = router.getOutput(TestDataType.BAR); + final OutputWire bazOutput = router.getOutput(TestDataType.BAZ); + + fooOutput.solderTo("fooHandler", "fooInput", latestFoo::set); + barOutput.solderTo("barHandler", "barInput", latestBar::set); + bazOutput.solderTo("bazHandler", "bazInput", latestBaz::set); + + long expectedFoo = 0; + long expectedBar = 0; + boolean expectedBaz = false; + + for (int i = 0; i < 1000; i++) { + final double choice = random.nextDouble(); + if (choice < 1.0 / 3.0) { + expectedFoo = random.nextLong(); + router.getInput().put(TestDataType.FOO.of(expectedFoo)); + } else if (choice < 2.0 / 3.0) { + expectedBar = random.nextLong(); + router.getInput().put(TestDataType.BAR.of(expectedBar)); + } else { + expectedBaz = random.nextBoolean(); + router.getInput().put(TestDataType.BAZ.of(expectedBaz)); + } + assertEquals(expectedFoo, latestFoo.get()); + assertEquals(expectedBar, latestBar.get()); + assertEquals(expectedBaz, latestBaz.get()); + } + } +} From 7ff2fc3ec62083c3926c45a0cc4068bc8f13264d Mon Sep 17 00:00:00 2001 From: mxtartaglia Date: Tue, 14 Jan 2025 18:45:44 -0300 Subject: [PATCH 3/6] chore: new module for wiring framework Signed-off-by: mxtartaglia --- .../blocks/impl/BlockStreamManagerImpl.java | 2 +- .../src/main/java/module-info.java | 23 +++++----- .../hiero/wiring/framework}/WiringConfig.java | 2 +- .../framework}/component/ComponentWiring.java | 44 +++++++++---------- .../framework}/component/InputWireLabel.java | 2 +- .../framework}/component/SchedulerLabel.java | 2 +- .../component/internal/FilterToBind.java | 4 +- .../component/internal/InputWireToBind.java | 4 +- .../component/internal/TransformerToBind.java | 4 +- .../internal/WiringComponentProxy.java | 5 ++- .../counters/BackpressureObjectCounter.java | 2 +- .../framework}/counters/EmptyBlocker.java | 2 +- .../counters/MultiObjectCounter.java | 2 +- .../counters/NoOpObjectCounter.java | 2 +- .../framework}/counters/ObjectCounter.java | 2 +- .../counters/StandardObjectCounter.java | 2 +- .../model/DeterministicWiringModel.java | 12 ++--- .../framework}/model/StandardWiringModel.java | 28 ++++++------ .../model/TraceableWiringModel.java | 40 ++++++++--------- .../wiring/framework}/model/WiringModel.java | 14 +++--- .../framework}/model/WiringModelBuilder.java | 2 +- .../model/diagram/HyperlinkBuilder.java | 2 +- .../model/diagram/ModelEdgeSubstitution.java | 2 +- .../framework}/model/diagram/ModelGroup.java | 2 +- .../model/diagram/ModelManualLink.java | 2 +- .../model/internal/analysis/CycleFinder.java | 2 +- .../analysis/DirectSchedulerChecks.java | 4 +- .../model/internal/analysis/GroupVertex.java | 8 ++-- .../internal/analysis/InputWireChecks.java | 2 +- .../analysis/InputWireDescriptor.java | 2 +- .../analysis/MermaidNameShortener.java | 2 +- .../analysis/MermaidStyleManager.java | 2 +- .../model/internal/analysis/ModelEdge.java | 2 +- .../model/internal/analysis/ModelVertex.java | 4 +- .../analysis/ModelVertexMetaType.java | 2 +- .../internal/analysis/StandardVertex.java | 14 +++--- .../internal/analysis/WiringFlowchart.java | 28 ++++++------ .../DeterministicHeartbeatScheduler.java | 8 ++-- .../DeterministicTaskScheduler.java | 10 ++--- .../DeterministicTaskSchedulerBuilder.java | 18 ++++---- .../model/internal/monitor/HealthMonitor.java | 6 +-- .../internal/monitor/HealthMonitorLogger.java | 4 +- .../monitor/HealthMonitorMetrics.java | 2 +- .../standard/AbstractHeartbeatScheduler.java | 10 ++--- .../internal/standard/HeartbeatScheduler.java | 4 +- .../internal/standard/HeartbeatTask.java | 8 ++-- .../model/internal/standard/JvmAnchor.java | 2 +- .../framework}/schedulers/TaskScheduler.java | 26 +++++------ .../builders/TaskSchedulerBuilder.java | 6 +-- .../builders/TaskSchedulerConfigOption.java | 2 +- .../builders/TaskSchedulerConfiguration.java | 10 ++--- .../builders/TaskSchedulerType.java | 2 +- .../AbstractTaskSchedulerBuilder.java | 28 ++++++------ .../StandardTaskSchedulerBuilder.java | 22 +++++----- .../schedulers/internal/ConcurrentTask.java | 6 +-- .../internal/ConcurrentTaskScheduler.java | 10 ++--- .../schedulers/internal/DefaultSquelcher.java | 2 +- .../internal/DirectTaskScheduler.java | 12 ++--- .../internal/NoOpTaskScheduler.java | 18 ++++---- .../schedulers/internal/SequentialTask.java | 6 +-- .../internal/SequentialTaskScheduler.java | 10 ++--- .../internal/SequentialThreadTask.java | 2 +- .../SequentialThreadTaskScheduler.java | 10 ++--- .../schedulers/internal/Squelcher.java | 2 +- .../internal/ThrowingSquelcher.java | 2 +- .../wiring/framework}/tasks/AbstractTask.java | 2 +- .../transformers/AdvancedTransformation.java | 5 ++- .../framework}/transformers/RoutableData.java | 2 +- .../framework}/transformers/WireFilter.java | 14 +++--- .../transformers/WireListSplitter.java | 16 +++---- .../framework}/transformers/WireRouter.java | 16 +++---- .../transformers/WireTransformer.java | 14 +++--- .../wiring/framework}/wires/SolderType.java | 4 +- .../framework}/wires/input/Bindable.java | 2 +- .../wires/input/BindableInputWire.java | 8 ++-- .../framework}/wires/input/InputWire.java | 6 +-- .../framework}/wires/input/NoOpInputWire.java | 6 +-- .../wires/input/TaskSchedulerInput.java | 4 +- .../wires/output/NoOpOutputWire.java | 10 ++--- .../framework}/wires/output/OutputWire.java | 26 +++++------ .../wires/output/StandardOutputWire.java | 6 +-- .../output/internal/ForwardingOutputWire.java | 6 +-- .../internal/TransformingOutputWire.java | 10 ++--- .../wiring/benchmark/WiringBenchmark.java | 14 +++--- .../TaskSchedulerConfigurationTests.java | 4 +- .../component/ComponentWiringRouterTests.java | 11 ++--- .../component/ComponentWiringTests.java | 13 +++--- .../WiringComponentPerformanceTests.java | 13 +++--- .../BackpressureObjectCounterTests.java | 2 + .../counters/MultiObjectCounterTests.java | 4 ++ .../counters/NoOpObjectCounterTests.java | 1 + .../counters/StandardObjectCounterTests.java | 2 + .../DeterministicHeartbeatSchedulerTests.java | 8 ++-- .../wiring/model/DeterministicModelTests.java | 25 ++++++----- .../common/wiring/model/ModelTests.java | 14 +++--- .../internal/monitor/HealthMonitorTests.java | 3 +- .../schedulers/NoOpTaskSchedulerTests.java | 15 ++++--- .../wiring/transformers/WireRouterTests.java | 8 ++-- .../common/TestWiringModelBuilder.java | 4 +- .../ConcurrentTaskSchedulerTests.java | 9 ++-- .../schedulers/DefaultSquelcherTests.java | 4 +- .../schedulers/DirectTaskSchedulerTests.java | 13 +++--- .../schedulers/HeartbeatSchedulerTests.java | 7 +-- .../SequentialTaskSchedulerTests.java | 19 ++++---- .../schedulers/ThrowingSquelcherTests.java | 4 +- .../TaskSchedulerTransformersTests.java | 11 ++--- .../common/wiring/wires/OutputWireTests.java | 12 ++--- .../files/hashmap/HalfDiskHashMap.java | 2 +- .../platform/builder/PlatformBuilder.java | 6 +-- .../builder/PlatformBuildingBlocks.java | 2 +- .../builder/PlatformComponentBuilder.java | 3 +- .../swirlds/platform/cli/DiagramCommand.java | 10 ++--- .../platform/cli/DiagramLegendCommand.java | 16 +++---- .../platform/components/AppNotifier.java | 2 +- .../components/EventWindowManager.java | 2 +- .../components/SavedStateController.java | 2 +- .../appcomm/LatestCompleteStateNotifier.java | 2 +- .../components/consensus/ConsensusEngine.java | 2 +- .../PlatformConfigurationExtension.java | 4 +- .../platform/event/FutureEventBuffer.java | 2 +- .../event/branching/BranchDetector.java | 2 +- .../event/branching/BranchReporter.java | 2 +- .../event/creation/EventCreationManager.java | 2 +- .../deduplication/EventDeduplicator.java | 2 +- .../platform/event/hashing/EventHasher.java | 2 +- .../platform/event/linking/InOrderLinker.java | 2 +- .../platform/event/orphan/OrphanBuffer.java | 2 +- .../event/preconsensus/InlinePcesWriter.java | 2 +- .../event/preconsensus/PcesReplayer.java | 2 +- .../event/preconsensus/PcesSequencer.java | 2 +- .../event/preconsensus/PcesWriter.java | 2 +- .../durability/RoundDurabilityBuffer.java | 2 +- .../resubmitter/TransactionResubmitter.java | 2 +- .../event/signing/SelfEventSigner.java | 2 +- .../stale/DefaultStaleEventDetector.java | 2 +- .../event/stale/StaleEventDetector.java | 4 +- .../event/stream/ConsensusEventStream.java | 2 +- .../validation/EventSignatureValidator.java | 2 +- .../validation/InternalEventValidator.java | 2 +- .../DefaultTransactionHandler.java | 2 +- .../eventhandling/TransactionHandler.java | 2 +- .../eventhandling/TransactionPrehandler.java | 2 +- .../swirlds/platform/gossip/SyncGossip.java | 6 +-- .../platform/pool/TransactionPool.java | 2 +- .../platform/publisher/PlatformPublisher.java | 2 +- .../platform/state/hasher/StateHasher.java | 2 +- .../platform/state/hashlogger/HashLogger.java | 2 +- .../state/nexus/LatestCompleteStateNexus.java | 2 +- .../state/nexus/SignedStateNexus.java | 2 +- .../state/signed/StateSignatureCollector.java | 2 +- .../events/BirthRoundMigrationShim.java | 2 +- .../system/status/StatusStateMachine.java | 2 +- .../platform/wiring/PlatformCoordinator.java | 4 +- .../wiring/PlatformSchedulersConfig.java | 2 +- .../platform/wiring/PlatformWiring.java | 26 +++++------ .../platform/wiring/SignedStateReserver.java | 2 +- .../wiring/StateAndRoundReserver.java | 2 +- .../wiring/StateAndRoundToStateReserver.java | 2 +- .../platform/wiring/components/Gossip.java | 6 +-- .../wiring/components/GossipWiring.java | 12 ++--- .../wiring/components/PassThroughWiring.java | 12 ++--- .../wiring/components/PcesReplayerWiring.java | 16 +++---- .../RunningEventHashOverrideWiring.java | 14 +++--- .../components/EventWindowManagerTests.java | 8 ++-- .../event/stale/StaleEventDetectorTests.java | 2 +- .../stream/ConsensusEventStreamTest.java | 8 ++-- .../turtle/gossip/SimulatedGossipTests.java | 14 +++--- .../platform/turtle/runner/TurtleNode.java | 4 +- .../platform/wiring/PlatformWiringTests.java | 4 +- .../wiring/SignedStateReserverTest.java | 12 ++--- .../turtle/gossip/SimulatedGossip.java | 6 +-- .../platform/test/consensus/TestIntake.java | 14 +++--- .../event/preconsensus/PcesReplayerTests.java | 2 +- .../internal/hash/VirtualHasher.java | 2 +- 174 files changed, 619 insertions(+), 585 deletions(-) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/WiringConfig.java (98%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/component/ComponentWiring.java (95%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/component/InputWireLabel.java (96%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/component/SchedulerLabel.java (96%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/component/internal/FilterToBind.java (90%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/component/internal/InputWireToBind.java (95%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/component/internal/TransformerToBind.java (91%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/component/internal/WiringComponentProxy.java (91%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/counters/BackpressureObjectCounter.java (99%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/counters/EmptyBlocker.java (97%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/counters/MultiObjectCounter.java (98%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/counters/NoOpObjectCounter.java (97%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/counters/ObjectCounter.java (98%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/counters/StandardObjectCounter.java (98%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/model/DeterministicWiringModel.java (89%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/model/StandardWiringModel.java (87%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/model/TraceableWiringModel.java (89%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/model/WiringModel.java (93%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/model/WiringModelBuilder.java (99%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/model/diagram/HyperlinkBuilder.java (98%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/model/diagram/ModelEdgeSubstitution.java (96%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/model/diagram/ModelGroup.java (96%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/model/diagram/ModelManualLink.java (95%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/model/internal/analysis/CycleFinder.java (98%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/model/internal/analysis/DirectSchedulerChecks.java (98%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/model/internal/analysis/GroupVertex.java (93%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/model/internal/analysis/InputWireChecks.java (97%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/model/internal/analysis/InputWireDescriptor.java (94%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/model/internal/analysis/MermaidNameShortener.java (96%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/model/internal/analysis/MermaidStyleManager.java (98%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/model/internal/analysis/ModelEdge.java (98%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/model/internal/analysis/ModelVertex.java (95%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/model/internal/analysis/ModelVertexMetaType.java (95%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/model/internal/analysis/StandardVertex.java (91%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/model/internal/analysis/WiringFlowchart.java (93%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/model/internal/deterministic/DeterministicHeartbeatScheduler.java (92%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/model/internal/deterministic/DeterministicTaskScheduler.java (93%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/model/internal/deterministic/DeterministicTaskSchedulerBuilder.java (84%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/model/internal/monitor/HealthMonitor.java (96%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/model/internal/monitor/HealthMonitorLogger.java (96%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/model/internal/monitor/HealthMonitorMetrics.java (97%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/model/internal/standard/AbstractHeartbeatScheduler.java (92%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/model/internal/standard/HeartbeatScheduler.java (94%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/model/internal/standard/HeartbeatTask.java (90%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/model/internal/standard/JvmAnchor.java (96%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/schedulers/TaskScheduler.java (92%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/schedulers/builders/TaskSchedulerBuilder.java (97%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/schedulers/builders/TaskSchedulerConfigOption.java (96%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/schedulers/builders/TaskSchedulerConfiguration.java (95%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/schedulers/builders/TaskSchedulerType.java (98%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/schedulers/builders/internal/AbstractTaskSchedulerBuilder.java (92%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/schedulers/builders/internal/StandardTaskSchedulerBuilder.java (89%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/schedulers/internal/ConcurrentTask.java (93%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/schedulers/internal/ConcurrentTaskScheduler.java (93%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/schedulers/internal/DefaultSquelcher.java (96%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/schedulers/internal/DirectTaskScheduler.java (92%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/schedulers/internal/NoOpTaskScheduler.java (86%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/schedulers/internal/SequentialTask.java (96%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/schedulers/internal/SequentialTaskScheduler.java (95%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/schedulers/internal/SequentialThreadTask.java (95%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/schedulers/internal/SequentialThreadTaskScheduler.java (95%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/schedulers/internal/Squelcher.java (97%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/schedulers/internal/ThrowingSquelcher.java (96%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/tasks/AbstractTask.java (98%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/transformers/AdvancedTransformation.java (92%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/transformers/RoutableData.java (95%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/transformers/WireFilter.java (90%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/transformers/WireListSplitter.java (83%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/transformers/WireRouter.java (89%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/transformers/WireTransformer.java (90%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/wires/SolderType.java (92%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/wires/input/Bindable.java (97%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/wires/input/BindableInputWire.java (93%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/wires/input/InputWire.java (95%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/wires/input/NoOpInputWire.java (93%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/wires/input/TaskSchedulerInput.java (95%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/wires/output/NoOpOutputWire.java (92%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/wires/output/OutputWire.java (93%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/wires/output/StandardOutputWire.java (92%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/wires/output/internal/ForwardingOutputWire.java (90%) rename platform-sdk/swirlds-common/src/main/java/{com/swirlds/common/wiring => org/hiero/wiring/framework}/wires/output/internal/TransformingOutputWire.java (94%) diff --git a/hedera-node/hedera-app/src/main/java/com/hedera/node/app/blocks/impl/BlockStreamManagerImpl.java b/hedera-node/hedera-app/src/main/java/com/hedera/node/app/blocks/impl/BlockStreamManagerImpl.java index 6c5493563c8..de298f679a9 100644 --- a/hedera-node/hedera-app/src/main/java/com/hedera/node/app/blocks/impl/BlockStreamManagerImpl.java +++ b/hedera-node/hedera-app/src/main/java/com/hedera/node/app/blocks/impl/BlockStreamManagerImpl.java @@ -58,7 +58,7 @@ import com.hedera.node.config.types.BlockStreamWriterMode; import com.hedera.node.config.types.DiskNetworkExport; import com.hedera.pbj.runtime.io.buffer.Bytes; -import com.swirlds.common.wiring.tasks.AbstractTask; +import org.hiero.wiring.framework.tasks.AbstractTask; import com.swirlds.config.api.Configuration; import com.swirlds.platform.state.service.PlatformStateService; import com.swirlds.platform.state.service.schemas.V0540PlatformStateSchema; diff --git a/platform-sdk/swirlds-common/src/main/java/module-info.java b/platform-sdk/swirlds-common/src/main/java/module-info.java index 83ab83db9ad..7402d2a18a0 100644 --- a/platform-sdk/swirlds-common/src/main/java/module-info.java +++ b/platform-sdk/swirlds-common/src/main/java/module-info.java @@ -62,16 +62,16 @@ exports com.swirlds.common.jackson; exports com.swirlds.common.units; exports com.swirlds.common.wiring; - exports com.swirlds.common.wiring.component; - exports com.swirlds.common.wiring.counters; - exports com.swirlds.common.wiring.model; - exports com.swirlds.common.wiring.schedulers; - exports com.swirlds.common.wiring.schedulers.builders; - exports com.swirlds.common.wiring.tasks; - exports com.swirlds.common.wiring.transformers; - exports com.swirlds.common.wiring.wires; - exports com.swirlds.common.wiring.wires.input; - exports com.swirlds.common.wiring.wires.output; + exports org.hiero.wiring.framework.component; + exports org.hiero.wiring.framework.counters; + exports org.hiero.wiring.framework.model; + exports org.hiero.wiring.framework.schedulers; + exports org.hiero.wiring.framework.schedulers.builders; + exports org.hiero.wiring.framework.tasks; + exports org.hiero.wiring.framework.transformers; + exports org.hiero.wiring.framework.wires; + exports org.hiero.wiring.framework.wires.input; + exports org.hiero.wiring.framework.wires.output; /* Targeted exports */ exports com.swirlds.common.crypto.internal to @@ -140,9 +140,10 @@ com.swirlds.platform.gui; exports com.swirlds.common.startup; exports com.swirlds.common.threading.atomic; - exports com.swirlds.common.wiring.model.diagram; + exports org.hiero.wiring.framework.model.diagram; exports com.swirlds.common.concurrent; exports com.swirlds.common.merkle.synchronization.stats; + exports org.hiero.wiring.framework; requires transitive com.swirlds.base; requires transitive com.swirlds.config.api; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/WiringConfig.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/WiringConfig.java similarity index 98% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/WiringConfig.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/WiringConfig.java index 8c48b350181..dcef5e4ee04 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/WiringConfig.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/WiringConfig.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.common.wiring; +package org.hiero.wiring.framework; import com.swirlds.config.api.ConfigData; import com.swirlds.config.api.ConfigProperty; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/component/ComponentWiring.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/component/ComponentWiring.java similarity index 95% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/component/ComponentWiring.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/component/ComponentWiring.java index 926168ead21..49bee085300 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/component/ComponentWiring.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/component/ComponentWiring.java @@ -14,25 +14,25 @@ * limitations under the License. */ -package com.swirlds.common.wiring.component; - -import static com.swirlds.common.wiring.model.diagram.HyperlinkBuilder.platformCoreHyperlink; - -import com.swirlds.common.wiring.component.internal.FilterToBind; -import com.swirlds.common.wiring.component.internal.InputWireToBind; -import com.swirlds.common.wiring.component.internal.TransformerToBind; -import com.swirlds.common.wiring.component.internal.WiringComponentProxy; -import com.swirlds.common.wiring.model.WiringModel; -import com.swirlds.common.wiring.schedulers.TaskScheduler; -import com.swirlds.common.wiring.schedulers.builders.TaskSchedulerConfiguration; -import com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType; -import com.swirlds.common.wiring.transformers.RoutableData; -import com.swirlds.common.wiring.transformers.WireFilter; -import com.swirlds.common.wiring.transformers.WireRouter; -import com.swirlds.common.wiring.transformers.WireTransformer; -import com.swirlds.common.wiring.wires.input.BindableInputWire; -import com.swirlds.common.wiring.wires.input.InputWire; -import com.swirlds.common.wiring.wires.output.OutputWire; +package org.hiero.wiring.framework.component; + +import static org.hiero.wiring.framework.model.diagram.HyperlinkBuilder.platformCoreHyperlink; + +import org.hiero.wiring.framework.component.internal.FilterToBind; +import org.hiero.wiring.framework.component.internal.InputWireToBind; +import org.hiero.wiring.framework.component.internal.TransformerToBind; +import org.hiero.wiring.framework.component.internal.WiringComponentProxy; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerConfiguration; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.transformers.RoutableData; +import org.hiero.wiring.framework.transformers.WireFilter; +import org.hiero.wiring.framework.transformers.WireRouter; +import org.hiero.wiring.framework.transformers.WireTransformer; +import org.hiero.wiring.framework.wires.input.BindableInputWire; +import org.hiero.wiring.framework.wires.input.InputWire; +import org.hiero.wiring.framework.wires.output.OutputWire; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; import java.lang.reflect.Method; @@ -376,7 +376,7 @@ public OutputWire getSplitOutput() { * address, which are implemented by enum values. *

* This method should only be used for components which have an output type of - * {@link com.swirlds.common.wiring.transformers.RoutableData RoutableData}. Calling this method more than once with + * {@link RoutableData RoutableData}. Calling this method more than once with * different enum classes will throw. * * @param address an enum value that describes one of the different types of data that can be routed @@ -398,7 +398,7 @@ public , DATA_TYPE> OutputWire * described by a routing address, which are implemented by enum values. *

* This method should only be used for components which have an output type of - * {@link com.swirlds.common.wiring.transformers.RoutableData List<RoutableData>}. Calling this method more + * {@link RoutableData List<RoutableData>}. Calling this method more * than once with different enum classes will throw. * * @param address an enum value that describes one of the different types of data that can be routed @@ -757,7 +757,7 @@ public void bind(@NonNull final COMPONENT_TYPE component) { /** * Bind to a component. This method is similar to {@link #bind(Object)}, but it allows the component to be created * if and only if we need to bind to it. This method will invoke the supplier if the task scheduler type is anything - * other than a {@link com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType#NO_OP NO_OP} scheduler. + * other than a {@link TaskSchedulerType#NO_OP NO_OP} scheduler. * * @param componentBuilder builds or supplies the component */ diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/component/InputWireLabel.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/component/InputWireLabel.java similarity index 96% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/component/InputWireLabel.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/component/InputWireLabel.java index 6fd770311f3..12b15ef7db2 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/component/InputWireLabel.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/component/InputWireLabel.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.common.wiring.component; +package org.hiero.wiring.framework.component; import edu.umd.cs.findbugs.annotations.NonNull; import java.lang.annotation.ElementType; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/component/SchedulerLabel.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/component/SchedulerLabel.java similarity index 96% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/component/SchedulerLabel.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/component/SchedulerLabel.java index 045a648339b..b8ddbf959fa 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/component/SchedulerLabel.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/component/SchedulerLabel.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.common.wiring.component; +package org.hiero.wiring.framework.component; import edu.umd.cs.findbugs.annotations.NonNull; import java.lang.annotation.ElementType; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/component/internal/FilterToBind.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/component/internal/FilterToBind.java similarity index 90% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/component/internal/FilterToBind.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/component/internal/FilterToBind.java index 9f972f8fcea..81f10eb1c43 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/component/internal/FilterToBind.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/component/internal/FilterToBind.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package com.swirlds.common.wiring.component.internal; +package org.hiero.wiring.framework.component.internal; -import com.swirlds.common.wiring.transformers.WireFilter; +import org.hiero.wiring.framework.transformers.WireFilter; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.function.BiFunction; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/component/internal/InputWireToBind.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/component/internal/InputWireToBind.java similarity index 95% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/component/internal/InputWireToBind.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/component/internal/InputWireToBind.java index 12384859522..c7adb681e5a 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/component/internal/InputWireToBind.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/component/internal/InputWireToBind.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package com.swirlds.common.wiring.component.internal; +package org.hiero.wiring.framework.component.internal; -import com.swirlds.common.wiring.wires.input.BindableInputWire; +import org.hiero.wiring.framework.wires.input.BindableInputWire; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; import java.util.function.BiConsumer; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/component/internal/TransformerToBind.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/component/internal/TransformerToBind.java similarity index 91% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/component/internal/TransformerToBind.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/component/internal/TransformerToBind.java index 982099c8c47..90637b6a63e 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/component/internal/TransformerToBind.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/component/internal/TransformerToBind.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package com.swirlds.common.wiring.component.internal; +package org.hiero.wiring.framework.component.internal; -import com.swirlds.common.wiring.transformers.WireTransformer; +import org.hiero.wiring.framework.transformers.WireTransformer; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.function.BiFunction; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/component/internal/WiringComponentProxy.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/component/internal/WiringComponentProxy.java similarity index 91% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/component/internal/WiringComponentProxy.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/component/internal/WiringComponentProxy.java index b751b34dd19..0724818e4e4 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/component/internal/WiringComponentProxy.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/component/internal/WiringComponentProxy.java @@ -14,15 +14,16 @@ * limitations under the License. */ -package com.swirlds.common.wiring.component.internal; +package org.hiero.wiring.framework.component.internal; import edu.umd.cs.findbugs.annotations.NonNull; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.util.Objects; +import org.hiero.wiring.framework.component.ComponentWiring; /** - * This dynamic proxy is used by the {@link com.swirlds.common.wiring.component.ComponentWiring} to capture the most + * This dynamic proxy is used by the {@link ComponentWiring} to capture the most * recently invoked method. */ public class WiringComponentProxy implements InvocationHandler { diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/counters/BackpressureObjectCounter.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/counters/BackpressureObjectCounter.java similarity index 99% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/counters/BackpressureObjectCounter.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/counters/BackpressureObjectCounter.java index 9f14e3971aa..59b61f64f95 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/counters/BackpressureObjectCounter.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/counters/BackpressureObjectCounter.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.common.wiring.counters; +package org.hiero.wiring.framework.counters; import static java.util.concurrent.TimeUnit.NANOSECONDS; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/counters/EmptyBlocker.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/counters/EmptyBlocker.java similarity index 97% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/counters/EmptyBlocker.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/counters/EmptyBlocker.java index 7360668cd9d..e159f3e7591 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/counters/EmptyBlocker.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/counters/EmptyBlocker.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.common.wiring.counters; +package org.hiero.wiring.framework.counters; import static java.util.concurrent.TimeUnit.NANOSECONDS; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/counters/MultiObjectCounter.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/counters/MultiObjectCounter.java similarity index 98% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/counters/MultiObjectCounter.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/counters/MultiObjectCounter.java index 7e50d9500dc..a1690a527d3 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/counters/MultiObjectCounter.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/counters/MultiObjectCounter.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.common.wiring.counters; +package org.hiero.wiring.framework.counters; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.Objects; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/counters/NoOpObjectCounter.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/counters/NoOpObjectCounter.java similarity index 97% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/counters/NoOpObjectCounter.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/counters/NoOpObjectCounter.java index fa03845f6a1..a55b93c7c52 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/counters/NoOpObjectCounter.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/counters/NoOpObjectCounter.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.common.wiring.counters; +package org.hiero.wiring.framework.counters; /** * A counter that doesn't actually count. Saves us from having to do a (counter == null) check in the standard case. diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/counters/ObjectCounter.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/counters/ObjectCounter.java similarity index 98% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/counters/ObjectCounter.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/counters/ObjectCounter.java index 78c3e83caaa..5ee15e66dd9 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/counters/ObjectCounter.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/counters/ObjectCounter.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.common.wiring.counters; +package org.hiero.wiring.framework.counters; /** * A class that counts the number of objects in various parts of the pipeline. diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/counters/StandardObjectCounter.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/counters/StandardObjectCounter.java similarity index 98% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/counters/StandardObjectCounter.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/counters/StandardObjectCounter.java index 3cd5915f163..8fae4360909 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/counters/StandardObjectCounter.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/counters/StandardObjectCounter.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.common.wiring.counters; +package org.hiero.wiring.framework.counters; import edu.umd.cs.findbugs.annotations.NonNull; import java.time.Duration; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/DeterministicWiringModel.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/DeterministicWiringModel.java similarity index 89% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/DeterministicWiringModel.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/DeterministicWiringModel.java index ba3c2115195..d3a63e0df28 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/DeterministicWiringModel.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/DeterministicWiringModel.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package com.swirlds.common.wiring.model; +package org.hiero.wiring.framework.model; import com.swirlds.common.context.PlatformContext; -import com.swirlds.common.wiring.model.internal.deterministic.DeterministicHeartbeatScheduler; -import com.swirlds.common.wiring.model.internal.deterministic.DeterministicTaskSchedulerBuilder; -import com.swirlds.common.wiring.schedulers.builders.TaskSchedulerBuilder; -import com.swirlds.common.wiring.wires.output.NoOpOutputWire; -import com.swirlds.common.wiring.wires.output.OutputWire; +import org.hiero.wiring.framework.model.internal.deterministic.DeterministicHeartbeatScheduler; +import org.hiero.wiring.framework.model.internal.deterministic.DeterministicTaskSchedulerBuilder; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerBuilder; +import org.hiero.wiring.framework.wires.output.NoOpOutputWire; +import org.hiero.wiring.framework.wires.output.OutputWire; import edu.umd.cs.findbugs.annotations.NonNull; import java.time.Duration; import java.time.Instant; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/StandardWiringModel.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/StandardWiringModel.java similarity index 87% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/StandardWiringModel.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/StandardWiringModel.java index 75087693dff..5a0100de8e5 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/StandardWiringModel.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/StandardWiringModel.java @@ -14,23 +14,23 @@ * limitations under the License. */ -package com.swirlds.common.wiring.model; +package org.hiero.wiring.framework.model; -import static com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType.NO_OP; -import static com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType.SEQUENTIAL; -import static com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType.SEQUENTIAL_THREAD; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.NO_OP; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.SEQUENTIAL; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.SEQUENTIAL_THREAD; import com.swirlds.common.context.PlatformContext; -import com.swirlds.common.wiring.model.diagram.HyperlinkBuilder; -import com.swirlds.common.wiring.model.internal.monitor.HealthMonitor; -import com.swirlds.common.wiring.model.internal.standard.HeartbeatScheduler; -import com.swirlds.common.wiring.model.internal.standard.JvmAnchor; -import com.swirlds.common.wiring.schedulers.TaskScheduler; -import com.swirlds.common.wiring.schedulers.builders.TaskSchedulerBuilder; -import com.swirlds.common.wiring.schedulers.builders.internal.StandardTaskSchedulerBuilder; -import com.swirlds.common.wiring.schedulers.internal.SequentialThreadTaskScheduler; -import com.swirlds.common.wiring.wires.input.BindableInputWire; -import com.swirlds.common.wiring.wires.output.OutputWire; +import org.hiero.wiring.framework.model.diagram.HyperlinkBuilder; +import org.hiero.wiring.framework.model.internal.monitor.HealthMonitor; +import org.hiero.wiring.framework.model.internal.standard.HeartbeatScheduler; +import org.hiero.wiring.framework.model.internal.standard.JvmAnchor; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerBuilder; +import org.hiero.wiring.framework.schedulers.builders.internal.StandardTaskSchedulerBuilder; +import org.hiero.wiring.framework.schedulers.internal.SequentialThreadTaskScheduler; +import org.hiero.wiring.framework.wires.input.BindableInputWire; +import org.hiero.wiring.framework.wires.output.OutputWire; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; import java.time.Duration; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/TraceableWiringModel.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/TraceableWiringModel.java similarity index 89% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/TraceableWiringModel.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/TraceableWiringModel.java index 9820f3b7eca..7395a9ddd6d 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/TraceableWiringModel.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/TraceableWiringModel.java @@ -14,26 +14,26 @@ * limitations under the License. */ -package com.swirlds.common.wiring.model; - -import static com.swirlds.common.wiring.model.internal.analysis.ModelVertexMetaType.SCHEDULER; -import static com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType.DIRECT; -import static com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType.DIRECT_THREADSAFE; - -import com.swirlds.common.wiring.model.diagram.ModelEdgeSubstitution; -import com.swirlds.common.wiring.model.diagram.ModelGroup; -import com.swirlds.common.wiring.model.diagram.ModelManualLink; -import com.swirlds.common.wiring.model.internal.analysis.CycleFinder; -import com.swirlds.common.wiring.model.internal.analysis.DirectSchedulerChecks; -import com.swirlds.common.wiring.model.internal.analysis.InputWireChecks; -import com.swirlds.common.wiring.model.internal.analysis.InputWireDescriptor; -import com.swirlds.common.wiring.model.internal.analysis.ModelEdge; -import com.swirlds.common.wiring.model.internal.analysis.ModelVertex; -import com.swirlds.common.wiring.model.internal.analysis.StandardVertex; -import com.swirlds.common.wiring.model.internal.analysis.WiringFlowchart; -import com.swirlds.common.wiring.schedulers.TaskScheduler; -import com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType; -import com.swirlds.common.wiring.wires.SolderType; +package org.hiero.wiring.framework.model; + +import static org.hiero.wiring.framework.model.internal.analysis.ModelVertexMetaType.SCHEDULER; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.DIRECT; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.DIRECT_THREADSAFE; + +import org.hiero.wiring.framework.model.diagram.ModelEdgeSubstitution; +import org.hiero.wiring.framework.model.diagram.ModelGroup; +import org.hiero.wiring.framework.model.diagram.ModelManualLink; +import org.hiero.wiring.framework.model.internal.analysis.CycleFinder; +import org.hiero.wiring.framework.model.internal.analysis.DirectSchedulerChecks; +import org.hiero.wiring.framework.model.internal.analysis.InputWireChecks; +import org.hiero.wiring.framework.model.internal.analysis.InputWireDescriptor; +import org.hiero.wiring.framework.model.internal.analysis.ModelEdge; +import org.hiero.wiring.framework.model.internal.analysis.ModelVertex; +import org.hiero.wiring.framework.model.internal.analysis.StandardVertex; +import org.hiero.wiring.framework.model.internal.analysis.WiringFlowchart; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.wires.SolderType; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; import java.util.ArrayList; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/WiringModel.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/WiringModel.java similarity index 93% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/WiringModel.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/WiringModel.java index e848c506faa..7c586cd1137 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/WiringModel.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/WiringModel.java @@ -14,16 +14,16 @@ * limitations under the License. */ -package com.swirlds.common.wiring.model; +package org.hiero.wiring.framework.model; import com.swirlds.base.state.Startable; import com.swirlds.base.state.Stoppable; -import com.swirlds.common.wiring.model.diagram.ModelEdgeSubstitution; -import com.swirlds.common.wiring.model.diagram.ModelGroup; -import com.swirlds.common.wiring.model.diagram.ModelManualLink; -import com.swirlds.common.wiring.schedulers.builders.TaskSchedulerBuilder; -import com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType; -import com.swirlds.common.wiring.wires.output.OutputWire; +import org.hiero.wiring.framework.model.diagram.ModelEdgeSubstitution; +import org.hiero.wiring.framework.model.diagram.ModelGroup; +import org.hiero.wiring.framework.model.diagram.ModelManualLink; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerBuilder; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.wires.output.OutputWire; import edu.umd.cs.findbugs.annotations.NonNull; import java.time.Duration; import java.time.Instant; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/WiringModelBuilder.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/WiringModelBuilder.java similarity index 99% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/WiringModelBuilder.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/WiringModelBuilder.java index d47dc00955a..8dea26704b8 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/WiringModelBuilder.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/WiringModelBuilder.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.common.wiring.model; +package org.hiero.wiring.framework.model; import com.swirlds.common.context.PlatformContext; import edu.umd.cs.findbugs.annotations.NonNull; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/diagram/HyperlinkBuilder.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/diagram/HyperlinkBuilder.java similarity index 98% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/diagram/HyperlinkBuilder.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/diagram/HyperlinkBuilder.java index 20b74254b1d..8cda7a5ac18 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/diagram/HyperlinkBuilder.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/diagram/HyperlinkBuilder.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.common.wiring.model.diagram; +package org.hiero.wiring.framework.model.diagram; import edu.umd.cs.findbugs.annotations.NonNull; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/diagram/ModelEdgeSubstitution.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/diagram/ModelEdgeSubstitution.java similarity index 96% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/diagram/ModelEdgeSubstitution.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/diagram/ModelEdgeSubstitution.java index c6d8c923921..a5226d60121 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/diagram/ModelEdgeSubstitution.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/diagram/ModelEdgeSubstitution.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.common.wiring.model.diagram; +package org.hiero.wiring.framework.model.diagram; import edu.umd.cs.findbugs.annotations.NonNull; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/diagram/ModelGroup.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/diagram/ModelGroup.java similarity index 96% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/diagram/ModelGroup.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/diagram/ModelGroup.java index b51835b17fe..c8ed076c050 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/diagram/ModelGroup.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/diagram/ModelGroup.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.common.wiring.model.diagram; +package org.hiero.wiring.framework.model.diagram; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.Set; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/diagram/ModelManualLink.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/diagram/ModelManualLink.java similarity index 95% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/diagram/ModelManualLink.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/diagram/ModelManualLink.java index 0fa08179168..f55a9832d3a 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/diagram/ModelManualLink.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/diagram/ModelManualLink.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.common.wiring.model.diagram; +package org.hiero.wiring.framework.model.diagram; import edu.umd.cs.findbugs.annotations.NonNull; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/analysis/CycleFinder.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/CycleFinder.java similarity index 98% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/analysis/CycleFinder.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/CycleFinder.java index 1c0bcdebf28..2774d98eb3c 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/analysis/CycleFinder.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/CycleFinder.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.common.wiring.model.internal.analysis; +package org.hiero.wiring.framework.model.internal.analysis; import static com.swirlds.logging.legacy.LogMarker.EXCEPTION; import static com.swirlds.logging.legacy.LogMarker.STARTUP; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/analysis/DirectSchedulerChecks.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/DirectSchedulerChecks.java similarity index 98% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/analysis/DirectSchedulerChecks.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/DirectSchedulerChecks.java index 781cd84abc4..e75052f3bc6 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/analysis/DirectSchedulerChecks.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/DirectSchedulerChecks.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.swirlds.common.wiring.model.internal.analysis; +package org.hiero.wiring.framework.model.internal.analysis; import static com.swirlds.logging.legacy.LogMarker.EXCEPTION; import static com.swirlds.logging.legacy.LogMarker.STARTUP; -import com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.Collection; import java.util.Deque; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/analysis/GroupVertex.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/GroupVertex.java similarity index 93% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/analysis/GroupVertex.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/GroupVertex.java index 173fcdab33a..d88a27f8806 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/analysis/GroupVertex.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/GroupVertex.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.swirlds.common.wiring.model.internal.analysis; +package org.hiero.wiring.framework.model.internal.analysis; -import static com.swirlds.common.wiring.model.internal.analysis.WiringFlowchart.GROUP_COLOR; -import static com.swirlds.common.wiring.model.internal.analysis.WiringFlowchart.TEXT_COLOR; +import static org.hiero.wiring.framework.model.internal.analysis.WiringFlowchart.GROUP_COLOR; +import static org.hiero.wiring.framework.model.internal.analysis.WiringFlowchart.TEXT_COLOR; -import com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; import java.util.HashSet; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/analysis/InputWireChecks.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/InputWireChecks.java similarity index 97% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/analysis/InputWireChecks.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/InputWireChecks.java index 940247559a1..261812d5e56 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/analysis/InputWireChecks.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/InputWireChecks.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.common.wiring.model.internal.analysis; +package org.hiero.wiring.framework.model.internal.analysis; import static com.swirlds.logging.legacy.LogMarker.EXCEPTION; import static com.swirlds.logging.legacy.LogMarker.STARTUP; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/analysis/InputWireDescriptor.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/InputWireDescriptor.java similarity index 94% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/analysis/InputWireDescriptor.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/InputWireDescriptor.java index 4a64fbfd566..f90d31f7289 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/analysis/InputWireDescriptor.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/InputWireDescriptor.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.common.wiring.model.internal.analysis; +package org.hiero.wiring.framework.model.internal.analysis; import edu.umd.cs.findbugs.annotations.NonNull; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/analysis/MermaidNameShortener.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/MermaidNameShortener.java similarity index 96% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/analysis/MermaidNameShortener.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/MermaidNameShortener.java index f8ed5122471..e8dcd0bcd92 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/analysis/MermaidNameShortener.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/MermaidNameShortener.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.common.wiring.model.internal.analysis; +package org.hiero.wiring.framework.model.internal.analysis; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.HashMap; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/analysis/MermaidStyleManager.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/MermaidStyleManager.java similarity index 98% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/analysis/MermaidStyleManager.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/MermaidStyleManager.java index 38d17cdbbd3..710000fb927 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/analysis/MermaidStyleManager.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/MermaidStyleManager.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.common.wiring.model.internal.analysis; +package org.hiero.wiring.framework.model.internal.analysis; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.ArrayList; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/analysis/ModelEdge.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/ModelEdge.java similarity index 98% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/analysis/ModelEdge.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/ModelEdge.java index 98b0b56794d..3e9882c24e3 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/analysis/ModelEdge.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/ModelEdge.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.common.wiring.model.internal.analysis; +package org.hiero.wiring.framework.model.internal.analysis; import static com.swirlds.common.utility.NonCryptographicHashing.hash32; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/analysis/ModelVertex.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/ModelVertex.java similarity index 95% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/analysis/ModelVertex.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/ModelVertex.java index d062b75365c..d22d55ce2bb 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/analysis/ModelVertex.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/ModelVertex.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package com.swirlds.common.wiring.model.internal.analysis; +package org.hiero.wiring.framework.model.internal.analysis; -import com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; import java.util.Set; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/analysis/ModelVertexMetaType.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/ModelVertexMetaType.java similarity index 95% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/analysis/ModelVertexMetaType.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/ModelVertexMetaType.java index 5953daff3cb..914291fb82e 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/analysis/ModelVertexMetaType.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/ModelVertexMetaType.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.common.wiring.model.internal.analysis; +package org.hiero.wiring.framework.model.internal.analysis; /** * The type of a vertex in a wiring flowchart. Although the original graph will be constructed of SCHEDULER vertices diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/analysis/StandardVertex.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/StandardVertex.java similarity index 91% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/analysis/StandardVertex.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/StandardVertex.java index 3c022895d93..c8c58940ee3 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/analysis/StandardVertex.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/StandardVertex.java @@ -14,15 +14,15 @@ * limitations under the License. */ -package com.swirlds.common.wiring.model.internal.analysis; +package org.hiero.wiring.framework.model.internal.analysis; -import static com.swirlds.common.wiring.model.internal.analysis.WiringFlowchart.DIRECT_SCHEDULER_COLOR; -import static com.swirlds.common.wiring.model.internal.analysis.WiringFlowchart.GROUP_COLOR; -import static com.swirlds.common.wiring.model.internal.analysis.WiringFlowchart.SCHEDULER_COLOR; -import static com.swirlds.common.wiring.model.internal.analysis.WiringFlowchart.SUBSTITUTION_COLOR; -import static com.swirlds.common.wiring.model.internal.analysis.WiringFlowchart.TEXT_COLOR; +import static org.hiero.wiring.framework.model.internal.analysis.WiringFlowchart.DIRECT_SCHEDULER_COLOR; +import static org.hiero.wiring.framework.model.internal.analysis.WiringFlowchart.GROUP_COLOR; +import static org.hiero.wiring.framework.model.internal.analysis.WiringFlowchart.SCHEDULER_COLOR; +import static org.hiero.wiring.framework.model.internal.analysis.WiringFlowchart.SUBSTITUTION_COLOR; +import static org.hiero.wiring.framework.model.internal.analysis.WiringFlowchart.TEXT_COLOR; -import com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; import java.util.HashSet; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/analysis/WiringFlowchart.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/WiringFlowchart.java similarity index 93% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/analysis/WiringFlowchart.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/WiringFlowchart.java index ab622f11c6a..a666b8ed475 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/analysis/WiringFlowchart.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/WiringFlowchart.java @@ -14,20 +14,20 @@ * limitations under the License. */ -package com.swirlds.common.wiring.model.internal.analysis; - -import static com.swirlds.common.wiring.model.internal.analysis.ModelVertexMetaType.SCHEDULER; -import static com.swirlds.common.wiring.model.internal.analysis.ModelVertexMetaType.SUBSTITUTION; -import static com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType.CONCURRENT; -import static com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType.DIRECT; -import static com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType.DIRECT_THREADSAFE; -import static com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType.SEQUENTIAL; -import static com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType.SEQUENTIAL_THREAD; - -import com.swirlds.common.wiring.model.diagram.ModelEdgeSubstitution; -import com.swirlds.common.wiring.model.diagram.ModelGroup; -import com.swirlds.common.wiring.model.diagram.ModelManualLink; -import com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType; +package org.hiero.wiring.framework.model.internal.analysis; + +import static org.hiero.wiring.framework.model.internal.analysis.ModelVertexMetaType.SCHEDULER; +import static org.hiero.wiring.framework.model.internal.analysis.ModelVertexMetaType.SUBSTITUTION; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.CONCURRENT; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.DIRECT; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.DIRECT_THREADSAFE; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.SEQUENTIAL; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.SEQUENTIAL_THREAD; + +import org.hiero.wiring.framework.model.diagram.ModelEdgeSubstitution; +import org.hiero.wiring.framework.model.diagram.ModelGroup; +import org.hiero.wiring.framework.model.diagram.ModelManualLink; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.ArrayList; import java.util.Collections; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/deterministic/DeterministicHeartbeatScheduler.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/deterministic/DeterministicHeartbeatScheduler.java similarity index 92% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/deterministic/DeterministicHeartbeatScheduler.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/deterministic/DeterministicHeartbeatScheduler.java index 94b80dab0ee..ea71712d431 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/deterministic/DeterministicHeartbeatScheduler.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/deterministic/DeterministicHeartbeatScheduler.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package com.swirlds.common.wiring.model.internal.deterministic; +package org.hiero.wiring.framework.model.internal.deterministic; import static com.swirlds.common.utility.CompareTo.isGreaterThanOrEqualTo; import com.swirlds.base.time.Time; -import com.swirlds.common.wiring.model.TraceableWiringModel; -import com.swirlds.common.wiring.model.internal.standard.AbstractHeartbeatScheduler; -import com.swirlds.common.wiring.model.internal.standard.HeartbeatTask; +import org.hiero.wiring.framework.model.TraceableWiringModel; +import org.hiero.wiring.framework.model.internal.standard.AbstractHeartbeatScheduler; +import org.hiero.wiring.framework.model.internal.standard.HeartbeatTask; import edu.umd.cs.findbugs.annotations.NonNull; import java.time.Duration; import java.time.Instant; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/deterministic/DeterministicTaskScheduler.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/deterministic/DeterministicTaskScheduler.java similarity index 93% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/deterministic/DeterministicTaskScheduler.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/deterministic/DeterministicTaskScheduler.java index a4ed064ff77..87894c04bd0 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/deterministic/DeterministicTaskScheduler.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/deterministic/DeterministicTaskScheduler.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.swirlds.common.wiring.model.internal.deterministic; +package org.hiero.wiring.framework.model.internal.deterministic; -import com.swirlds.common.wiring.counters.ObjectCounter; -import com.swirlds.common.wiring.model.TraceableWiringModel; -import com.swirlds.common.wiring.schedulers.TaskScheduler; -import com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.counters.ObjectCounter; +import org.hiero.wiring.framework.model.TraceableWiringModel; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.Objects; import java.util.function.Consumer; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/deterministic/DeterministicTaskSchedulerBuilder.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/deterministic/DeterministicTaskSchedulerBuilder.java similarity index 84% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/deterministic/DeterministicTaskSchedulerBuilder.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/deterministic/DeterministicTaskSchedulerBuilder.java index 47335b820f5..58d151c56e4 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/deterministic/DeterministicTaskSchedulerBuilder.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/deterministic/DeterministicTaskSchedulerBuilder.java @@ -14,20 +14,20 @@ * limitations under the License. */ -package com.swirlds.common.wiring.model.internal.deterministic; +package org.hiero.wiring.framework.model.internal.deterministic; -import static com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType.DIRECT_THREADSAFE; -import static com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType.NO_OP; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.DIRECT_THREADSAFE; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.NO_OP; import com.swirlds.common.context.PlatformContext; import com.swirlds.common.metrics.extensions.FractionalTimer; import com.swirlds.common.metrics.extensions.NoOpFractionalTimer; -import com.swirlds.common.wiring.model.DeterministicWiringModel; -import com.swirlds.common.wiring.model.TraceableWiringModel; -import com.swirlds.common.wiring.schedulers.TaskScheduler; -import com.swirlds.common.wiring.schedulers.builders.internal.AbstractTaskSchedulerBuilder; -import com.swirlds.common.wiring.schedulers.internal.DirectTaskScheduler; -import com.swirlds.common.wiring.schedulers.internal.NoOpTaskScheduler; +import org.hiero.wiring.framework.model.DeterministicWiringModel; +import org.hiero.wiring.framework.model.TraceableWiringModel; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.schedulers.builders.internal.AbstractTaskSchedulerBuilder; +import org.hiero.wiring.framework.schedulers.internal.DirectTaskScheduler; +import org.hiero.wiring.framework.schedulers.internal.NoOpTaskScheduler; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.Objects; import java.util.concurrent.ForkJoinPool; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/monitor/HealthMonitor.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/monitor/HealthMonitor.java similarity index 96% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/monitor/HealthMonitor.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/monitor/HealthMonitor.java index 26dcd3cd17e..a91921b317d 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/monitor/HealthMonitor.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/monitor/HealthMonitor.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package com.swirlds.common.wiring.model.internal.monitor; +package org.hiero.wiring.framework.model.internal.monitor; import static com.swirlds.common.utility.CompareTo.isGreaterThan; import com.swirlds.common.context.PlatformContext; -import com.swirlds.common.wiring.schedulers.TaskScheduler; -import com.swirlds.common.wiring.schedulers.builders.TaskSchedulerBuilder; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerBuilder; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; import java.time.Duration; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/monitor/HealthMonitorLogger.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/monitor/HealthMonitorLogger.java similarity index 96% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/monitor/HealthMonitorLogger.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/monitor/HealthMonitorLogger.java index 342f9d285ca..bec6ad95aec 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/monitor/HealthMonitorLogger.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/monitor/HealthMonitorLogger.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.common.wiring.model.internal.monitor; +package org.hiero.wiring.framework.model.internal.monitor; import static com.swirlds.common.units.TimeUnit.UNIT_NANOSECONDS; import static com.swirlds.logging.legacy.LogMarker.STARTUP; @@ -22,7 +22,7 @@ import com.swirlds.common.context.PlatformContext; import com.swirlds.common.utility.CompareTo; import com.swirlds.common.utility.throttle.RateLimitedLogger; -import com.swirlds.common.wiring.schedulers.TaskScheduler; +import org.hiero.wiring.framework.schedulers.TaskScheduler; import edu.umd.cs.findbugs.annotations.NonNull; import java.time.Duration; import java.util.HashMap; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/monitor/HealthMonitorMetrics.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/monitor/HealthMonitorMetrics.java similarity index 97% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/monitor/HealthMonitorMetrics.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/monitor/HealthMonitorMetrics.java index 5bc6e54a415..430417d70e2 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/monitor/HealthMonitorMetrics.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/monitor/HealthMonitorMetrics.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.common.wiring.model.internal.monitor; +package org.hiero.wiring.framework.model.internal.monitor; import static com.swirlds.common.utility.CompareTo.isLessThan; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/standard/AbstractHeartbeatScheduler.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/standard/AbstractHeartbeatScheduler.java similarity index 92% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/standard/AbstractHeartbeatScheduler.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/standard/AbstractHeartbeatScheduler.java index 31e6fdfa40c..cf702ba3fd9 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/standard/AbstractHeartbeatScheduler.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/standard/AbstractHeartbeatScheduler.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package com.swirlds.common.wiring.model.internal.standard; +package org.hiero.wiring.framework.model.internal.standard; -import static com.swirlds.common.wiring.model.diagram.HyperlinkBuilder.platformCommonHyperlink; +import static org.hiero.wiring.framework.model.diagram.HyperlinkBuilder.platformCommonHyperlink; import com.swirlds.base.time.Time; -import com.swirlds.common.wiring.model.TraceableWiringModel; -import com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType; -import com.swirlds.common.wiring.wires.output.OutputWire; +import org.hiero.wiring.framework.model.TraceableWiringModel; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.wires.output.OutputWire; import edu.umd.cs.findbugs.annotations.NonNull; import java.time.Duration; import java.time.Instant; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/standard/HeartbeatScheduler.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/standard/HeartbeatScheduler.java similarity index 94% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/standard/HeartbeatScheduler.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/standard/HeartbeatScheduler.java index 89ec0df32a6..53b27a55ec1 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/standard/HeartbeatScheduler.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/standard/HeartbeatScheduler.java @@ -14,10 +14,10 @@ * limitations under the License. */ -package com.swirlds.common.wiring.model.internal.standard; +package org.hiero.wiring.framework.model.internal.standard; import com.swirlds.base.time.Time; -import com.swirlds.common.wiring.model.StandardWiringModel; +import org.hiero.wiring.framework.model.StandardWiringModel; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.Timer; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/standard/HeartbeatTask.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/standard/HeartbeatTask.java similarity index 90% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/standard/HeartbeatTask.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/standard/HeartbeatTask.java index 7a6be4f6f69..52d92c52d0d 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/standard/HeartbeatTask.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/standard/HeartbeatTask.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.swirlds.common.wiring.model.internal.standard; +package org.hiero.wiring.framework.model.internal.standard; import com.swirlds.base.time.Time; -import com.swirlds.common.wiring.model.TraceableWiringModel; -import com.swirlds.common.wiring.wires.output.OutputWire; -import com.swirlds.common.wiring.wires.output.StandardOutputWire; +import org.hiero.wiring.framework.model.TraceableWiringModel; +import org.hiero.wiring.framework.wires.output.OutputWire; +import org.hiero.wiring.framework.wires.output.StandardOutputWire; import edu.umd.cs.findbugs.annotations.NonNull; import java.time.Duration; import java.time.Instant; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/standard/JvmAnchor.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/standard/JvmAnchor.java similarity index 96% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/standard/JvmAnchor.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/standard/JvmAnchor.java index c4f17a70464..b484905bc75 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/model/internal/standard/JvmAnchor.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/standard/JvmAnchor.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.common.wiring.model.internal.standard; +package org.hiero.wiring.framework.model.internal.standard; import static java.util.concurrent.TimeUnit.SECONDS; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/schedulers/TaskScheduler.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/TaskScheduler.java similarity index 92% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/schedulers/TaskScheduler.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/TaskScheduler.java index 470968c7838..c3f5d265d24 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/schedulers/TaskScheduler.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/TaskScheduler.java @@ -14,20 +14,20 @@ * limitations under the License. */ -package com.swirlds.common.wiring.schedulers; +package org.hiero.wiring.framework.schedulers; -import com.swirlds.common.wiring.counters.ObjectCounter; -import com.swirlds.common.wiring.model.TraceableWiringModel; -import com.swirlds.common.wiring.schedulers.builders.TaskSchedulerBuilder; -import com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType; -import com.swirlds.common.wiring.schedulers.internal.DefaultSquelcher; -import com.swirlds.common.wiring.schedulers.internal.Squelcher; -import com.swirlds.common.wiring.schedulers.internal.ThrowingSquelcher; -import com.swirlds.common.wiring.wires.input.BindableInputWire; -import com.swirlds.common.wiring.wires.input.InputWire; -import com.swirlds.common.wiring.wires.input.TaskSchedulerInput; -import com.swirlds.common.wiring.wires.output.OutputWire; -import com.swirlds.common.wiring.wires.output.StandardOutputWire; +import org.hiero.wiring.framework.counters.ObjectCounter; +import org.hiero.wiring.framework.model.TraceableWiringModel; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerBuilder; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.schedulers.internal.DefaultSquelcher; +import org.hiero.wiring.framework.schedulers.internal.Squelcher; +import org.hiero.wiring.framework.schedulers.internal.ThrowingSquelcher; +import org.hiero.wiring.framework.wires.input.BindableInputWire; +import org.hiero.wiring.framework.wires.input.InputWire; +import org.hiero.wiring.framework.wires.input.TaskSchedulerInput; +import org.hiero.wiring.framework.wires.output.OutputWire; +import org.hiero.wiring.framework.wires.output.StandardOutputWire; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.Objects; import java.util.function.Consumer; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/schedulers/builders/TaskSchedulerBuilder.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/builders/TaskSchedulerBuilder.java similarity index 97% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/schedulers/builders/TaskSchedulerBuilder.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/builders/TaskSchedulerBuilder.java index 4ef2f99dc7d..e5aed604550 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/schedulers/builders/TaskSchedulerBuilder.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/builders/TaskSchedulerBuilder.java @@ -14,10 +14,10 @@ * limitations under the License. */ -package com.swirlds.common.wiring.schedulers.builders; +package org.hiero.wiring.framework.schedulers.builders; -import com.swirlds.common.wiring.counters.ObjectCounter; -import com.swirlds.common.wiring.schedulers.TaskScheduler; +import org.hiero.wiring.framework.counters.ObjectCounter; +import org.hiero.wiring.framework.schedulers.TaskScheduler; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; import java.lang.Thread.UncaughtExceptionHandler; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/schedulers/builders/TaskSchedulerConfigOption.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/builders/TaskSchedulerConfigOption.java similarity index 96% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/schedulers/builders/TaskSchedulerConfigOption.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/builders/TaskSchedulerConfigOption.java index 722d79fdd5b..45145d5e0e4 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/schedulers/builders/TaskSchedulerConfigOption.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/builders/TaskSchedulerConfigOption.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.common.wiring.schedulers.builders; +package org.hiero.wiring.framework.schedulers.builders; /** * Various configuration options for a task scheduler. Note that the task scheduler type uses values from diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/schedulers/builders/TaskSchedulerConfiguration.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/builders/TaskSchedulerConfiguration.java similarity index 95% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/schedulers/builders/TaskSchedulerConfiguration.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/builders/TaskSchedulerConfiguration.java index b92d92069b0..8966f3a6226 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/schedulers/builders/TaskSchedulerConfiguration.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/builders/TaskSchedulerConfiguration.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.swirlds.common.wiring.schedulers.builders; +package org.hiero.wiring.framework.schedulers.builders; -import static com.swirlds.common.wiring.schedulers.builders.TaskSchedulerConfigOption.BUSY_FRACTION_METRIC; -import static com.swirlds.common.wiring.schedulers.builders.TaskSchedulerConfigOption.FLUSHABLE; -import static com.swirlds.common.wiring.schedulers.builders.TaskSchedulerConfigOption.SQUELCHABLE; -import static com.swirlds.common.wiring.schedulers.builders.TaskSchedulerConfigOption.UNHANDLED_TASK_METRIC; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerConfigOption.BUSY_FRACTION_METRIC; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerConfigOption.FLUSHABLE; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerConfigOption.SQUELCHABLE; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerConfigOption.UNHANDLED_TASK_METRIC; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/schedulers/builders/TaskSchedulerType.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/builders/TaskSchedulerType.java similarity index 98% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/schedulers/builders/TaskSchedulerType.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/builders/TaskSchedulerType.java index 34e20ca69dd..3e4e42cea75 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/schedulers/builders/TaskSchedulerType.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/builders/TaskSchedulerType.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.common.wiring.schedulers.builders; +package org.hiero.wiring.framework.schedulers.builders; /** * Various types of task schedulers. Pass one of these types to {@link TaskSchedulerBuilder#withType(TaskSchedulerType)} diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/schedulers/builders/internal/AbstractTaskSchedulerBuilder.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/builders/internal/AbstractTaskSchedulerBuilder.java similarity index 92% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/schedulers/builders/internal/AbstractTaskSchedulerBuilder.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/builders/internal/AbstractTaskSchedulerBuilder.java index 9e6ff8c217d..73a82bffcb1 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/schedulers/builders/internal/AbstractTaskSchedulerBuilder.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/builders/internal/AbstractTaskSchedulerBuilder.java @@ -14,24 +14,24 @@ * limitations under the License. */ -package com.swirlds.common.wiring.schedulers.builders.internal; +package org.hiero.wiring.framework.schedulers.builders.internal; -import static com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType.DIRECT; -import static com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType.DIRECT_THREADSAFE; -import static com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType.NO_OP; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.DIRECT; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.DIRECT_THREADSAFE; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.NO_OP; import static com.swirlds.logging.legacy.LogMarker.EXCEPTION; import com.swirlds.common.context.PlatformContext; -import com.swirlds.common.wiring.counters.BackpressureObjectCounter; -import com.swirlds.common.wiring.counters.MultiObjectCounter; -import com.swirlds.common.wiring.counters.NoOpObjectCounter; -import com.swirlds.common.wiring.counters.ObjectCounter; -import com.swirlds.common.wiring.counters.StandardObjectCounter; -import com.swirlds.common.wiring.model.TraceableWiringModel; -import com.swirlds.common.wiring.schedulers.TaskScheduler; -import com.swirlds.common.wiring.schedulers.builders.TaskSchedulerBuilder; -import com.swirlds.common.wiring.schedulers.builders.TaskSchedulerConfiguration; -import com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.counters.BackpressureObjectCounter; +import org.hiero.wiring.framework.counters.MultiObjectCounter; +import org.hiero.wiring.framework.counters.NoOpObjectCounter; +import org.hiero.wiring.framework.counters.ObjectCounter; +import org.hiero.wiring.framework.counters.StandardObjectCounter; +import org.hiero.wiring.framework.model.TraceableWiringModel; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerBuilder; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerConfiguration; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; import java.lang.Thread.UncaughtExceptionHandler; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/schedulers/builders/internal/StandardTaskSchedulerBuilder.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/builders/internal/StandardTaskSchedulerBuilder.java similarity index 89% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/schedulers/builders/internal/StandardTaskSchedulerBuilder.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/builders/internal/StandardTaskSchedulerBuilder.java index 563964cceb5..7c160b15301 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/schedulers/builders/internal/StandardTaskSchedulerBuilder.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/builders/internal/StandardTaskSchedulerBuilder.java @@ -14,24 +14,24 @@ * limitations under the License. */ -package com.swirlds.common.wiring.schedulers.builders.internal; +package org.hiero.wiring.framework.schedulers.builders.internal; -import static com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType.DIRECT_THREADSAFE; -import static com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType.NO_OP; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.DIRECT_THREADSAFE; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.NO_OP; import com.swirlds.common.context.PlatformContext; import com.swirlds.common.metrics.FunctionGauge; import com.swirlds.common.metrics.extensions.FractionalTimer; import com.swirlds.common.metrics.extensions.NoOpFractionalTimer; import com.swirlds.common.metrics.extensions.StandardFractionalTimer; -import com.swirlds.common.wiring.model.StandardWiringModel; -import com.swirlds.common.wiring.schedulers.TaskScheduler; -import com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType; -import com.swirlds.common.wiring.schedulers.internal.ConcurrentTaskScheduler; -import com.swirlds.common.wiring.schedulers.internal.DirectTaskScheduler; -import com.swirlds.common.wiring.schedulers.internal.NoOpTaskScheduler; -import com.swirlds.common.wiring.schedulers.internal.SequentialTaskScheduler; -import com.swirlds.common.wiring.schedulers.internal.SequentialThreadTaskScheduler; +import org.hiero.wiring.framework.model.StandardWiringModel; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.schedulers.internal.ConcurrentTaskScheduler; +import org.hiero.wiring.framework.schedulers.internal.DirectTaskScheduler; +import org.hiero.wiring.framework.schedulers.internal.NoOpTaskScheduler; +import org.hiero.wiring.framework.schedulers.internal.SequentialTaskScheduler; +import org.hiero.wiring.framework.schedulers.internal.SequentialThreadTaskScheduler; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; import java.util.Objects; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/schedulers/internal/ConcurrentTask.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/ConcurrentTask.java similarity index 93% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/schedulers/internal/ConcurrentTask.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/ConcurrentTask.java index fea8b381e6d..90e8025d8b5 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/schedulers/internal/ConcurrentTask.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/ConcurrentTask.java @@ -14,10 +14,10 @@ * limitations under the License. */ -package com.swirlds.common.wiring.schedulers.internal; +package org.hiero.wiring.framework.schedulers.internal; -import com.swirlds.common.wiring.counters.ObjectCounter; -import com.swirlds.common.wiring.tasks.AbstractTask; +import org.hiero.wiring.framework.counters.ObjectCounter; +import org.hiero.wiring.framework.tasks.AbstractTask; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; import java.lang.Thread.UncaughtExceptionHandler; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/schedulers/internal/ConcurrentTaskScheduler.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/ConcurrentTaskScheduler.java similarity index 93% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/schedulers/internal/ConcurrentTaskScheduler.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/ConcurrentTaskScheduler.java index c1d268ab6f4..a5e2e670f33 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/schedulers/internal/ConcurrentTaskScheduler.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/ConcurrentTaskScheduler.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.swirlds.common.wiring.schedulers.internal; +package org.hiero.wiring.framework.schedulers.internal; -import com.swirlds.common.wiring.counters.ObjectCounter; -import com.swirlds.common.wiring.model.TraceableWiringModel; -import com.swirlds.common.wiring.schedulers.TaskScheduler; -import com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.counters.ObjectCounter; +import org.hiero.wiring.framework.model.TraceableWiringModel; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; import edu.umd.cs.findbugs.annotations.NonNull; import java.lang.Thread.UncaughtExceptionHandler; import java.util.Objects; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/schedulers/internal/DefaultSquelcher.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/DefaultSquelcher.java similarity index 96% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/schedulers/internal/DefaultSquelcher.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/DefaultSquelcher.java index 66ac98bbd9d..811daf27711 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/schedulers/internal/DefaultSquelcher.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/DefaultSquelcher.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.common.wiring.schedulers.internal; +package org.hiero.wiring.framework.schedulers.internal; import java.util.concurrent.atomic.AtomicBoolean; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/schedulers/internal/DirectTaskScheduler.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/DirectTaskScheduler.java similarity index 92% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/schedulers/internal/DirectTaskScheduler.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/DirectTaskScheduler.java index dee47c7650c..9d377228e0c 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/schedulers/internal/DirectTaskScheduler.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/DirectTaskScheduler.java @@ -14,15 +14,15 @@ * limitations under the License. */ -package com.swirlds.common.wiring.schedulers.internal; +package org.hiero.wiring.framework.schedulers.internal; -import static com.swirlds.common.wiring.schedulers.builders.TaskSchedulerBuilder.UNLIMITED_CAPACITY; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerBuilder.UNLIMITED_CAPACITY; import com.swirlds.common.metrics.extensions.FractionalTimer; -import com.swirlds.common.wiring.counters.ObjectCounter; -import com.swirlds.common.wiring.model.TraceableWiringModel; -import com.swirlds.common.wiring.schedulers.TaskScheduler; -import com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.counters.ObjectCounter; +import org.hiero.wiring.framework.model.TraceableWiringModel; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; import edu.umd.cs.findbugs.annotations.NonNull; import java.lang.Thread.UncaughtExceptionHandler; import java.util.Objects; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/schedulers/internal/NoOpTaskScheduler.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/NoOpTaskScheduler.java similarity index 86% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/schedulers/internal/NoOpTaskScheduler.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/NoOpTaskScheduler.java index c15530abb65..7cf28994342 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/schedulers/internal/NoOpTaskScheduler.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/NoOpTaskScheduler.java @@ -14,17 +14,17 @@ * limitations under the License. */ -package com.swirlds.common.wiring.schedulers.internal; +package org.hiero.wiring.framework.schedulers.internal; -import static com.swirlds.common.wiring.schedulers.builders.TaskSchedulerBuilder.UNLIMITED_CAPACITY; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerBuilder.UNLIMITED_CAPACITY; -import com.swirlds.common.wiring.model.TraceableWiringModel; -import com.swirlds.common.wiring.schedulers.TaskScheduler; -import com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType; -import com.swirlds.common.wiring.wires.input.BindableInputWire; -import com.swirlds.common.wiring.wires.input.NoOpInputWire; -import com.swirlds.common.wiring.wires.output.NoOpOutputWire; -import com.swirlds.common.wiring.wires.output.StandardOutputWire; +import org.hiero.wiring.framework.model.TraceableWiringModel; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.wires.input.BindableInputWire; +import org.hiero.wiring.framework.wires.input.NoOpInputWire; +import org.hiero.wiring.framework.wires.output.NoOpOutputWire; +import org.hiero.wiring.framework.wires.output.StandardOutputWire; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.Objects; import java.util.function.Consumer; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/schedulers/internal/SequentialTask.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/SequentialTask.java similarity index 96% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/schedulers/internal/SequentialTask.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/SequentialTask.java index 760e28b337d..156b5a9299f 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/schedulers/internal/SequentialTask.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/SequentialTask.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package com.swirlds.common.wiring.schedulers.internal; +package org.hiero.wiring.framework.schedulers.internal; import com.swirlds.common.metrics.extensions.FractionalTimer; -import com.swirlds.common.wiring.counters.ObjectCounter; -import com.swirlds.common.wiring.tasks.AbstractTask; +import org.hiero.wiring.framework.counters.ObjectCounter; +import org.hiero.wiring.framework.tasks.AbstractTask; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; import java.lang.Thread.UncaughtExceptionHandler; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/schedulers/internal/SequentialTaskScheduler.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/SequentialTaskScheduler.java similarity index 95% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/schedulers/internal/SequentialTaskScheduler.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/SequentialTaskScheduler.java index fe83f236635..5ef032d25d3 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/schedulers/internal/SequentialTaskScheduler.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/SequentialTaskScheduler.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package com.swirlds.common.wiring.schedulers.internal; +package org.hiero.wiring.framework.schedulers.internal; import com.swirlds.common.metrics.extensions.FractionalTimer; -import com.swirlds.common.wiring.counters.ObjectCounter; -import com.swirlds.common.wiring.model.TraceableWiringModel; -import com.swirlds.common.wiring.schedulers.TaskScheduler; -import com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.counters.ObjectCounter; +import org.hiero.wiring.framework.model.TraceableWiringModel; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; import edu.umd.cs.findbugs.annotations.NonNull; import java.lang.Thread.UncaughtExceptionHandler; import java.util.Objects; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/schedulers/internal/SequentialThreadTask.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/SequentialThreadTask.java similarity index 95% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/schedulers/internal/SequentialThreadTask.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/SequentialThreadTask.java index 8a9b2f16089..04f14bce995 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/schedulers/internal/SequentialThreadTask.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/SequentialThreadTask.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.common.wiring.schedulers.internal; +package org.hiero.wiring.framework.schedulers.internal; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.function.Consumer; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/schedulers/internal/SequentialThreadTaskScheduler.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/SequentialThreadTaskScheduler.java similarity index 95% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/schedulers/internal/SequentialThreadTaskScheduler.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/SequentialThreadTaskScheduler.java index f658c1204c4..9435efc242f 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/schedulers/internal/SequentialThreadTaskScheduler.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/SequentialThreadTaskScheduler.java @@ -14,15 +14,15 @@ * limitations under the License. */ -package com.swirlds.common.wiring.schedulers.internal; +package org.hiero.wiring.framework.schedulers.internal; import com.swirlds.base.state.Startable; import com.swirlds.base.state.Stoppable; import com.swirlds.common.metrics.extensions.FractionalTimer; -import com.swirlds.common.wiring.counters.ObjectCounter; -import com.swirlds.common.wiring.model.TraceableWiringModel; -import com.swirlds.common.wiring.schedulers.TaskScheduler; -import com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.counters.ObjectCounter; +import org.hiero.wiring.framework.model.TraceableWiringModel; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; import edu.umd.cs.findbugs.annotations.NonNull; import java.lang.Thread.UncaughtExceptionHandler; import java.util.ArrayList; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/schedulers/internal/Squelcher.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/Squelcher.java similarity index 97% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/schedulers/internal/Squelcher.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/Squelcher.java index 6ee0affb07b..b46595d56e9 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/schedulers/internal/Squelcher.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/Squelcher.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.common.wiring.schedulers.internal; +package org.hiero.wiring.framework.schedulers.internal; /** * Manages whether or not tasks scheduled by a given task scheduler should be squelched. diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/schedulers/internal/ThrowingSquelcher.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/ThrowingSquelcher.java similarity index 96% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/schedulers/internal/ThrowingSquelcher.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/ThrowingSquelcher.java index ada8d41b475..11deec5ddb9 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/schedulers/internal/ThrowingSquelcher.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/ThrowingSquelcher.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.common.wiring.schedulers.internal; +package org.hiero.wiring.framework.schedulers.internal; /** * A squelcher object that does not support squelching. diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/tasks/AbstractTask.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/tasks/AbstractTask.java similarity index 98% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/tasks/AbstractTask.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/tasks/AbstractTask.java index cba3654d27d..2c66f81e3db 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/tasks/AbstractTask.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/tasks/AbstractTask.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.common.wiring.tasks; +package org.hiero.wiring.framework.tasks; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.concurrent.ForkJoinPool; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/transformers/AdvancedTransformation.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/transformers/AdvancedTransformation.java similarity index 92% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/transformers/AdvancedTransformation.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/transformers/AdvancedTransformation.java index 1c8d5c21a31..adeda559d8f 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/transformers/AdvancedTransformation.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/transformers/AdvancedTransformation.java @@ -14,14 +14,15 @@ * limitations under the License. */ -package com.swirlds.common.wiring.transformers; +package org.hiero.wiring.framework.transformers; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; +import org.hiero.wiring.framework.wires.output.OutputWire; /** * Executes a transformation for an advanced transformer as created by - * {@link com.swirlds.common.wiring.wires.output.OutputWire#buildAdvancedTransformer(AdvancedTransformation)}. + * {@link OutputWire#buildAdvancedTransformer(AdvancedTransformation)}. * * @param the original wire output type * @param the output type of the transformer diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/transformers/RoutableData.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/transformers/RoutableData.java similarity index 95% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/transformers/RoutableData.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/transformers/RoutableData.java index deb9205ab3e..76c792164fe 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/transformers/RoutableData.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/transformers/RoutableData.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.common.wiring.transformers; +package org.hiero.wiring.framework.transformers; import edu.umd.cs.findbugs.annotations.NonNull; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/transformers/WireFilter.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/transformers/WireFilter.java similarity index 90% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/transformers/WireFilter.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/transformers/WireFilter.java index d1c1f8d0c2e..dcb7e65a91b 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/transformers/WireFilter.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/transformers/WireFilter.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package com.swirlds.common.wiring.transformers; +package org.hiero.wiring.framework.transformers; -import com.swirlds.common.wiring.model.WiringModel; -import com.swirlds.common.wiring.schedulers.TaskScheduler; -import com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType; -import com.swirlds.common.wiring.wires.input.BindableInputWire; -import com.swirlds.common.wiring.wires.input.InputWire; -import com.swirlds.common.wiring.wires.output.OutputWire; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.wires.input.BindableInputWire; +import org.hiero.wiring.framework.wires.input.InputWire; +import org.hiero.wiring.framework.wires.output.OutputWire; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.Objects; import java.util.function.Predicate; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/transformers/WireListSplitter.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/transformers/WireListSplitter.java similarity index 83% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/transformers/WireListSplitter.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/transformers/WireListSplitter.java index ef87407a8a9..17b38f243f2 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/transformers/WireListSplitter.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/transformers/WireListSplitter.java @@ -14,15 +14,15 @@ * limitations under the License. */ -package com.swirlds.common.wiring.transformers; +package org.hiero.wiring.framework.transformers; -import com.swirlds.common.wiring.model.WiringModel; -import com.swirlds.common.wiring.schedulers.TaskScheduler; -import com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType; -import com.swirlds.common.wiring.wires.input.BindableInputWire; -import com.swirlds.common.wiring.wires.input.InputWire; -import com.swirlds.common.wiring.wires.output.OutputWire; -import com.swirlds.common.wiring.wires.output.StandardOutputWire; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.wires.input.BindableInputWire; +import org.hiero.wiring.framework.wires.input.InputWire; +import org.hiero.wiring.framework.wires.output.OutputWire; +import org.hiero.wiring.framework.wires.output.StandardOutputWire; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.List; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/transformers/WireRouter.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/transformers/WireRouter.java similarity index 89% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/transformers/WireRouter.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/transformers/WireRouter.java index 9b186386687..fcf1e81185b 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/transformers/WireRouter.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/transformers/WireRouter.java @@ -14,16 +14,16 @@ * limitations under the License. */ -package com.swirlds.common.wiring.transformers; +package org.hiero.wiring.framework.transformers; -import static com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType.DIRECT_THREADSAFE; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.DIRECT_THREADSAFE; -import com.swirlds.common.wiring.model.WiringModel; -import com.swirlds.common.wiring.schedulers.TaskScheduler; -import com.swirlds.common.wiring.wires.input.BindableInputWire; -import com.swirlds.common.wiring.wires.input.InputWire; -import com.swirlds.common.wiring.wires.output.OutputWire; -import com.swirlds.common.wiring.wires.output.StandardOutputWire; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.wires.input.BindableInputWire; +import org.hiero.wiring.framework.wires.input.InputWire; +import org.hiero.wiring.framework.wires.output.OutputWire; +import org.hiero.wiring.framework.wires.output.StandardOutputWire; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.ArrayList; import java.util.List; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/transformers/WireTransformer.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/transformers/WireTransformer.java similarity index 90% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/transformers/WireTransformer.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/transformers/WireTransformer.java index 4bd174a722d..b6b83a0ea15 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/transformers/WireTransformer.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/transformers/WireTransformer.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package com.swirlds.common.wiring.transformers; +package org.hiero.wiring.framework.transformers; -import com.swirlds.common.wiring.model.WiringModel; -import com.swirlds.common.wiring.schedulers.TaskScheduler; -import com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType; -import com.swirlds.common.wiring.wires.input.BindableInputWire; -import com.swirlds.common.wiring.wires.input.InputWire; -import com.swirlds.common.wiring.wires.output.OutputWire; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.wires.input.BindableInputWire; +import org.hiero.wiring.framework.wires.input.InputWire; +import org.hiero.wiring.framework.wires.output.OutputWire; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.Objects; import java.util.function.Function; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/wires/SolderType.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/SolderType.java similarity index 92% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/wires/SolderType.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/SolderType.java index e8de84ba814..9a3e2a2ab34 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/wires/SolderType.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/SolderType.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package com.swirlds.common.wiring.wires; +package org.hiero.wiring.framework.wires; -import com.swirlds.common.wiring.wires.input.InputWire; +import org.hiero.wiring.framework.wires.input.InputWire; /** * The type of solder connection between an output wire and an input wire. diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/wires/input/Bindable.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/input/Bindable.java similarity index 97% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/wires/input/Bindable.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/input/Bindable.java index ff4acb48cd7..d16be99c50c 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/wires/input/Bindable.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/input/Bindable.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.common.wiring.wires.input; +package org.hiero.wiring.framework.wires.input; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.function.Consumer; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/wires/input/BindableInputWire.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/input/BindableInputWire.java similarity index 93% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/wires/input/BindableInputWire.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/input/BindableInputWire.java index 8cbf47f9f76..c7c9f5152de 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/wires/input/BindableInputWire.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/input/BindableInputWire.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.swirlds.common.wiring.wires.input; +package org.hiero.wiring.framework.wires.input; -import static com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType.NO_OP; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.NO_OP; -import com.swirlds.common.wiring.model.TraceableWiringModel; -import com.swirlds.common.wiring.schedulers.TaskScheduler; +import org.hiero.wiring.framework.model.TraceableWiringModel; +import org.hiero.wiring.framework.schedulers.TaskScheduler; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.Objects; import java.util.function.Consumer; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/wires/input/InputWire.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/input/InputWire.java similarity index 95% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/wires/input/InputWire.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/input/InputWire.java index 5a0701b38f6..a2a36c6be09 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/wires/input/InputWire.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/input/InputWire.java @@ -14,10 +14,10 @@ * limitations under the License. */ -package com.swirlds.common.wiring.wires.input; +package org.hiero.wiring.framework.wires.input; -import com.swirlds.common.wiring.schedulers.TaskScheduler; -import com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.Objects; import java.util.function.Consumer; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/wires/input/NoOpInputWire.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/input/NoOpInputWire.java similarity index 93% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/wires/input/NoOpInputWire.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/input/NoOpInputWire.java index 3f841ba2623..849f014e418 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/wires/input/NoOpInputWire.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/input/NoOpInputWire.java @@ -14,10 +14,10 @@ * limitations under the License. */ -package com.swirlds.common.wiring.wires.input; +package org.hiero.wiring.framework.wires.input; -import com.swirlds.common.wiring.model.TraceableWiringModel; -import com.swirlds.common.wiring.schedulers.TaskScheduler; +import org.hiero.wiring.framework.model.TraceableWiringModel; +import org.hiero.wiring.framework.schedulers.TaskScheduler; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.function.Consumer; import java.util.function.Function; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/wires/input/TaskSchedulerInput.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/input/TaskSchedulerInput.java similarity index 95% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/wires/input/TaskSchedulerInput.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/input/TaskSchedulerInput.java index f45af508d8c..6655ac16572 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/wires/input/TaskSchedulerInput.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/input/TaskSchedulerInput.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package com.swirlds.common.wiring.wires.input; +package org.hiero.wiring.framework.wires.input; -import com.swirlds.common.wiring.schedulers.TaskScheduler; +import org.hiero.wiring.framework.schedulers.TaskScheduler; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.function.Consumer; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/wires/output/NoOpOutputWire.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/output/NoOpOutputWire.java similarity index 92% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/wires/output/NoOpOutputWire.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/output/NoOpOutputWire.java index 193c54c2dae..40541d70f74 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/wires/output/NoOpOutputWire.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/output/NoOpOutputWire.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.swirlds.common.wiring.wires.output; +package org.hiero.wiring.framework.wires.output; -import com.swirlds.common.wiring.model.TraceableWiringModel; -import com.swirlds.common.wiring.transformers.AdvancedTransformation; -import com.swirlds.common.wiring.wires.SolderType; -import com.swirlds.common.wiring.wires.input.InputWire; +import org.hiero.wiring.framework.model.TraceableWiringModel; +import org.hiero.wiring.framework.transformers.AdvancedTransformation; +import org.hiero.wiring.framework.wires.SolderType; +import org.hiero.wiring.framework.wires.input.InputWire; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.function.Consumer; import java.util.function.Function; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/wires/output/OutputWire.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/output/OutputWire.java similarity index 93% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/wires/output/OutputWire.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/output/OutputWire.java index 00b540dbaf2..183a025316c 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/wires/output/OutputWire.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/output/OutputWire.java @@ -14,21 +14,21 @@ * limitations under the License. */ -package com.swirlds.common.wiring.wires.output; +package org.hiero.wiring.framework.wires.output; -import static com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType.NO_OP; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.NO_OP; -import com.swirlds.common.wiring.model.TraceableWiringModel; -import com.swirlds.common.wiring.schedulers.TaskScheduler; -import com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType; -import com.swirlds.common.wiring.transformers.AdvancedTransformation; -import com.swirlds.common.wiring.transformers.WireFilter; -import com.swirlds.common.wiring.transformers.WireListSplitter; -import com.swirlds.common.wiring.transformers.WireTransformer; -import com.swirlds.common.wiring.wires.SolderType; -import com.swirlds.common.wiring.wires.input.BindableInputWire; -import com.swirlds.common.wiring.wires.input.InputWire; -import com.swirlds.common.wiring.wires.output.internal.TransformingOutputWire; +import org.hiero.wiring.framework.model.TraceableWiringModel; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.transformers.AdvancedTransformation; +import org.hiero.wiring.framework.transformers.WireFilter; +import org.hiero.wiring.framework.transformers.WireListSplitter; +import org.hiero.wiring.framework.transformers.WireTransformer; +import org.hiero.wiring.framework.wires.SolderType; +import org.hiero.wiring.framework.wires.input.BindableInputWire; +import org.hiero.wiring.framework.wires.input.InputWire; +import org.hiero.wiring.framework.wires.output.internal.TransformingOutputWire; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.List; import java.util.Objects; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/wires/output/StandardOutputWire.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/output/StandardOutputWire.java similarity index 92% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/wires/output/StandardOutputWire.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/output/StandardOutputWire.java index f90d74c3ec5..347ec7a9c1c 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/wires/output/StandardOutputWire.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/output/StandardOutputWire.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.swirlds.common.wiring.wires.output; +package org.hiero.wiring.framework.wires.output; import static com.swirlds.logging.legacy.LogMarker.EXCEPTION; -import com.swirlds.common.wiring.model.TraceableWiringModel; -import com.swirlds.common.wiring.wires.output.internal.ForwardingOutputWire; +import org.hiero.wiring.framework.model.TraceableWiringModel; +import org.hiero.wiring.framework.wires.output.internal.ForwardingOutputWire; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.ArrayList; import java.util.List; diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/wires/output/internal/ForwardingOutputWire.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/output/internal/ForwardingOutputWire.java similarity index 90% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/wires/output/internal/ForwardingOutputWire.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/output/internal/ForwardingOutputWire.java index 87373447a78..f8eebe9db22 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/wires/output/internal/ForwardingOutputWire.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/output/internal/ForwardingOutputWire.java @@ -14,10 +14,10 @@ * limitations under the License. */ -package com.swirlds.common.wiring.wires.output.internal; +package org.hiero.wiring.framework.wires.output.internal; -import com.swirlds.common.wiring.model.TraceableWiringModel; -import com.swirlds.common.wiring.wires.output.OutputWire; +import org.hiero.wiring.framework.model.TraceableWiringModel; +import org.hiero.wiring.framework.wires.output.OutputWire; import edu.umd.cs.findbugs.annotations.NonNull; /** diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/wires/output/internal/TransformingOutputWire.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/output/internal/TransformingOutputWire.java similarity index 94% rename from platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/wires/output/internal/TransformingOutputWire.java rename to platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/output/internal/TransformingOutputWire.java index 4006facc99a..ab8cf59fe7f 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/wiring/wires/output/internal/TransformingOutputWire.java +++ b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/output/internal/TransformingOutputWire.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package com.swirlds.common.wiring.wires.output.internal; +package org.hiero.wiring.framework.wires.output.internal; import static com.swirlds.logging.legacy.LogMarker.EXCEPTION; -import com.swirlds.common.wiring.model.TraceableWiringModel; -import com.swirlds.common.wiring.wires.SolderType; -import com.swirlds.common.wiring.wires.input.InputWire; -import com.swirlds.common.wiring.wires.output.OutputWire; +import org.hiero.wiring.framework.model.TraceableWiringModel; +import org.hiero.wiring.framework.wires.SolderType; +import org.hiero.wiring.framework.wires.input.InputWire; +import org.hiero.wiring.framework.wires.output.OutputWire; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; import java.util.ArrayList; diff --git a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/benchmark/WiringBenchmark.java b/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/benchmark/WiringBenchmark.java index 1c44c6d7586..293d85b44d6 100644 --- a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/benchmark/WiringBenchmark.java +++ b/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/benchmark/WiringBenchmark.java @@ -22,13 +22,13 @@ import com.swirlds.common.context.PlatformContext; import com.swirlds.common.test.fixtures.platform.TestPlatformContextBuilder; -import com.swirlds.common.wiring.counters.BackpressureObjectCounter; -import com.swirlds.common.wiring.counters.ObjectCounter; -import com.swirlds.common.wiring.model.WiringModel; -import com.swirlds.common.wiring.model.WiringModelBuilder; -import com.swirlds.common.wiring.schedulers.TaskScheduler; -import com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType; -import com.swirlds.common.wiring.wires.input.BindableInputWire; +import org.hiero.wiring.framework.counters.BackpressureObjectCounter; +import org.hiero.wiring.framework.counters.ObjectCounter; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.model.WiringModelBuilder; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.wires.input.BindableInputWire; import java.time.Duration; import java.util.concurrent.ForkJoinPool; diff --git a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/builders/TaskSchedulerConfigurationTests.java b/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/builders/TaskSchedulerConfigurationTests.java index 5ed5da35fca..2e836529fc6 100644 --- a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/builders/TaskSchedulerConfigurationTests.java +++ b/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/builders/TaskSchedulerConfigurationTests.java @@ -21,8 +21,8 @@ import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; -import com.swirlds.common.wiring.schedulers.builders.TaskSchedulerConfiguration; -import com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerConfiguration; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; import java.util.Random; import org.junit.jupiter.api.Test; diff --git a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/component/ComponentWiringRouterTests.java b/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/component/ComponentWiringRouterTests.java index 921f6aacc6d..83c2453010d 100644 --- a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/component/ComponentWiringRouterTests.java +++ b/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/component/ComponentWiringRouterTests.java @@ -17,16 +17,17 @@ package com.swirlds.common.wiring.component; import static com.swirlds.common.test.fixtures.RandomUtils.getRandomPrintSeed; -import static com.swirlds.common.wiring.schedulers.builders.TaskSchedulerConfiguration.DIRECT_CONFIGURATION; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerConfiguration.DIRECT_CONFIGURATION; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import com.swirlds.common.context.PlatformContext; import com.swirlds.common.test.fixtures.platform.TestPlatformContextBuilder; -import com.swirlds.common.wiring.model.WiringModel; -import com.swirlds.common.wiring.model.WiringModelBuilder; -import com.swirlds.common.wiring.transformers.RoutableData; -import com.swirlds.common.wiring.wires.output.OutputWire; +import org.hiero.wiring.framework.component.ComponentWiring; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.model.WiringModelBuilder; +import org.hiero.wiring.framework.transformers.RoutableData; +import org.hiero.wiring.framework.wires.output.OutputWire; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.ArrayList; import java.util.List; diff --git a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/component/ComponentWiringTests.java b/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/component/ComponentWiringTests.java index 08cf47fc904..f695c4745ed 100644 --- a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/component/ComponentWiringTests.java +++ b/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/component/ComponentWiringTests.java @@ -22,11 +22,14 @@ import com.swirlds.common.context.PlatformContext; import com.swirlds.common.test.fixtures.platform.TestPlatformContextBuilder; -import com.swirlds.common.wiring.model.WiringModel; -import com.swirlds.common.wiring.model.WiringModelBuilder; -import com.swirlds.common.wiring.schedulers.builders.TaskSchedulerConfiguration; -import com.swirlds.common.wiring.wires.input.InputWire; -import com.swirlds.common.wiring.wires.output.OutputWire; +import org.hiero.wiring.framework.component.ComponentWiring; +import org.hiero.wiring.framework.component.InputWireLabel; +import org.hiero.wiring.framework.component.SchedulerLabel; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.model.WiringModelBuilder; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerConfiguration; +import org.hiero.wiring.framework.wires.input.InputWire; +import org.hiero.wiring.framework.wires.output.OutputWire; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.ArrayList; import java.util.List; diff --git a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/component/WiringComponentPerformanceTests.java b/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/component/WiringComponentPerformanceTests.java index d0a40badda9..2a2f73711cb 100644 --- a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/component/WiringComponentPerformanceTests.java +++ b/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/component/WiringComponentPerformanceTests.java @@ -17,12 +17,13 @@ package com.swirlds.common.wiring.component; import com.swirlds.common.test.fixtures.platform.TestPlatformContextBuilder; -import com.swirlds.common.wiring.model.WiringModel; -import com.swirlds.common.wiring.model.WiringModelBuilder; -import com.swirlds.common.wiring.schedulers.TaskScheduler; -import com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType; -import com.swirlds.common.wiring.wires.input.BindableInputWire; -import com.swirlds.common.wiring.wires.input.InputWire; +import org.hiero.wiring.framework.component.ComponentWiring; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.model.WiringModelBuilder; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.wires.input.BindableInputWire; +import org.hiero.wiring.framework.wires.input.InputWire; import edu.umd.cs.findbugs.annotations.NonNull; import java.time.Duration; import java.time.Instant; diff --git a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/counters/BackpressureObjectCounterTests.java b/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/counters/BackpressureObjectCounterTests.java index e1bbee44c45..701fb201582 100644 --- a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/counters/BackpressureObjectCounterTests.java +++ b/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/counters/BackpressureObjectCounterTests.java @@ -34,6 +34,8 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; +import org.hiero.wiring.framework.counters.BackpressureObjectCounter; +import org.hiero.wiring.framework.counters.ObjectCounter; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; diff --git a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/counters/MultiObjectCounterTests.java b/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/counters/MultiObjectCounterTests.java index 94cfa656351..e35221e5f9f 100644 --- a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/counters/MultiObjectCounterTests.java +++ b/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/counters/MultiObjectCounterTests.java @@ -27,6 +27,10 @@ import java.time.Duration; import java.util.Random; import java.util.concurrent.atomic.AtomicBoolean; +import org.hiero.wiring.framework.counters.BackpressureObjectCounter; +import org.hiero.wiring.framework.counters.MultiObjectCounter; +import org.hiero.wiring.framework.counters.ObjectCounter; +import org.hiero.wiring.framework.counters.StandardObjectCounter; import org.junit.jupiter.api.Test; class MultiObjectCounterTests { diff --git a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/counters/NoOpObjectCounterTests.java b/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/counters/NoOpObjectCounterTests.java index 1a6107768f1..0ac12065dd1 100644 --- a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/counters/NoOpObjectCounterTests.java +++ b/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/counters/NoOpObjectCounterTests.java @@ -18,6 +18,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; +import org.hiero.wiring.framework.counters.NoOpObjectCounter; import org.junit.jupiter.api.Test; class NoOpObjectCounterTests { diff --git a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/counters/StandardObjectCounterTests.java b/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/counters/StandardObjectCounterTests.java index e2d51b294ad..a73a9b76a11 100644 --- a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/counters/StandardObjectCounterTests.java +++ b/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/counters/StandardObjectCounterTests.java @@ -27,6 +27,8 @@ import java.time.Duration; import java.util.Random; import java.util.concurrent.atomic.AtomicBoolean; +import org.hiero.wiring.framework.counters.ObjectCounter; +import org.hiero.wiring.framework.counters.StandardObjectCounter; import org.junit.jupiter.api.Test; class StandardObjectCounterTests { diff --git a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/model/DeterministicHeartbeatSchedulerTests.java b/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/model/DeterministicHeartbeatSchedulerTests.java index 952ba5af077..ed18c8bd179 100644 --- a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/model/DeterministicHeartbeatSchedulerTests.java +++ b/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/model/DeterministicHeartbeatSchedulerTests.java @@ -16,14 +16,16 @@ package com.swirlds.common.wiring.model; -import static com.swirlds.common.wiring.schedulers.builders.TaskSchedulerBuilder.UNLIMITED_CAPACITY; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerBuilder.UNLIMITED_CAPACITY; import static org.junit.jupiter.api.Assertions.assertEquals; import com.swirlds.base.test.fixtures.time.FakeTime; import com.swirlds.common.context.PlatformContext; import com.swirlds.common.test.fixtures.platform.TestPlatformContextBuilder; -import com.swirlds.common.wiring.schedulers.TaskScheduler; -import com.swirlds.common.wiring.wires.input.BindableInputWire; +import org.hiero.wiring.framework.model.DeterministicWiringModel; +import org.hiero.wiring.framework.model.WiringModelBuilder; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.wires.input.BindableInputWire; import java.time.Duration; import java.time.Instant; import java.util.concurrent.atomic.AtomicLong; diff --git a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/model/DeterministicModelTests.java b/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/model/DeterministicModelTests.java index 1d41eafdcbd..2309094d71e 100644 --- a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/model/DeterministicModelTests.java +++ b/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/model/DeterministicModelTests.java @@ -19,13 +19,13 @@ import static com.swirlds.common.test.fixtures.RandomUtils.getRandomPrintSeed; import static com.swirlds.common.test.fixtures.RandomUtils.randomInstant; import static com.swirlds.common.utility.NonCryptographicHashing.hash32; -import static com.swirlds.common.wiring.schedulers.builders.TaskSchedulerBuilder.UNLIMITED_CAPACITY; -import static com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType.CONCURRENT; -import static com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType.DIRECT; -import static com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType.DIRECT_THREADSAFE; -import static com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType.NO_OP; -import static com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType.SEQUENTIAL; -import static com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType.SEQUENTIAL_THREAD; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerBuilder.UNLIMITED_CAPACITY; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.CONCURRENT; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.DIRECT; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.DIRECT_THREADSAFE; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.NO_OP; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.SEQUENTIAL; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.SEQUENTIAL_THREAD; import static java.util.concurrent.TimeUnit.MICROSECONDS; import static java.util.concurrent.TimeUnit.MILLISECONDS; import static org.assertj.core.api.Fail.fail; @@ -37,10 +37,13 @@ import com.swirlds.common.context.PlatformContext; import com.swirlds.common.test.fixtures.platform.TestPlatformContextBuilder; import com.swirlds.common.utility.NonCryptographicHashing; -import com.swirlds.common.wiring.schedulers.TaskScheduler; -import com.swirlds.common.wiring.wires.input.BindableInputWire; -import com.swirlds.common.wiring.wires.input.InputWire; -import com.swirlds.common.wiring.wires.output.OutputWire; +import org.hiero.wiring.framework.model.DeterministicWiringModel; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.model.WiringModelBuilder; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.wires.input.BindableInputWire; +import org.hiero.wiring.framework.wires.input.InputWire; +import org.hiero.wiring.framework.wires.output.OutputWire; import edu.umd.cs.findbugs.annotations.NonNull; import java.time.Duration; import java.time.Instant; diff --git a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/model/ModelTests.java b/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/model/ModelTests.java index fca40ced635..745c2d24508 100644 --- a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/model/ModelTests.java +++ b/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/model/ModelTests.java @@ -22,12 +22,14 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import com.swirlds.common.test.fixtures.platform.TestPlatformContextBuilder; -import com.swirlds.common.wiring.schedulers.TaskScheduler; -import com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType; -import com.swirlds.common.wiring.wires.SolderType; -import com.swirlds.common.wiring.wires.input.BindableInputWire; -import com.swirlds.common.wiring.wires.input.InputWire; -import com.swirlds.common.wiring.wires.output.OutputWire; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.model.WiringModelBuilder; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.wires.SolderType; +import org.hiero.wiring.framework.wires.input.BindableInputWire; +import org.hiero.wiring.framework.wires.input.InputWire; +import org.hiero.wiring.framework.wires.output.OutputWire; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.List; import org.junit.jupiter.api.Test; diff --git a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/model/internal/monitor/HealthMonitorTests.java b/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/model/internal/monitor/HealthMonitorTests.java index 111380dfc6d..ed32ac498cb 100644 --- a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/model/internal/monitor/HealthMonitorTests.java +++ b/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/model/internal/monitor/HealthMonitorTests.java @@ -26,7 +26,8 @@ import com.swirlds.common.test.fixtures.Randotron; import com.swirlds.common.test.fixtures.platform.TestPlatformContextBuilder; import com.swirlds.common.utility.CompareTo; -import com.swirlds.common.wiring.schedulers.TaskScheduler; +import org.hiero.wiring.framework.model.internal.monitor.HealthMonitor; +import org.hiero.wiring.framework.schedulers.TaskScheduler; import edu.umd.cs.findbugs.annotations.NonNull; import java.time.Duration; import java.time.Instant; diff --git a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/schedulers/NoOpTaskSchedulerTests.java b/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/schedulers/NoOpTaskSchedulerTests.java index bb65e1144b4..f7ba74a6697 100644 --- a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/schedulers/NoOpTaskSchedulerTests.java +++ b/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/schedulers/NoOpTaskSchedulerTests.java @@ -16,19 +16,20 @@ package com.swirlds.common.wiring.schedulers; -import static com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType.NO_OP; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.NO_OP; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; import com.swirlds.common.context.PlatformContext; import com.swirlds.common.test.fixtures.platform.TestPlatformContextBuilder; -import com.swirlds.common.wiring.model.WiringModel; -import com.swirlds.common.wiring.model.WiringModelBuilder; -import com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType; -import com.swirlds.common.wiring.wires.SolderType; -import com.swirlds.common.wiring.wires.input.BindableInputWire; -import com.swirlds.common.wiring.wires.output.OutputWire; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.model.WiringModelBuilder; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.wires.SolderType; +import org.hiero.wiring.framework.wires.input.BindableInputWire; +import org.hiero.wiring.framework.wires.output.OutputWire; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; import org.junit.jupiter.api.Test; diff --git a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/transformers/WireRouterTests.java b/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/transformers/WireRouterTests.java index 2d12683a62b..7851cae95cf 100644 --- a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/transformers/WireRouterTests.java +++ b/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/transformers/WireRouterTests.java @@ -21,9 +21,11 @@ import com.swirlds.common.context.PlatformContext; import com.swirlds.common.test.fixtures.platform.TestPlatformContextBuilder; -import com.swirlds.common.wiring.model.WiringModel; -import com.swirlds.common.wiring.model.WiringModelBuilder; -import com.swirlds.common.wiring.wires.output.OutputWire; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.model.WiringModelBuilder; +import org.hiero.wiring.framework.transformers.RoutableData; +import org.hiero.wiring.framework.transformers.WireRouter; +import org.hiero.wiring.framework.wires.output.OutputWire; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.Random; import java.util.concurrent.atomic.AtomicBoolean; diff --git a/platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/TestWiringModelBuilder.java b/platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/TestWiringModelBuilder.java index 0887c36e477..c6f5800a525 100644 --- a/platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/TestWiringModelBuilder.java +++ b/platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/TestWiringModelBuilder.java @@ -18,8 +18,8 @@ import com.swirlds.common.context.PlatformContext; import com.swirlds.common.test.fixtures.platform.TestPlatformContextBuilder; -import com.swirlds.common.wiring.model.WiringModel; -import com.swirlds.common.wiring.model.WiringModelBuilder; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.model.WiringModelBuilder; import edu.umd.cs.findbugs.annotations.NonNull; /** diff --git a/platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring/schedulers/ConcurrentTaskSchedulerTests.java b/platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring/schedulers/ConcurrentTaskSchedulerTests.java index 81a01a72134..6683927f017 100644 --- a/platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring/schedulers/ConcurrentTaskSchedulerTests.java +++ b/platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring/schedulers/ConcurrentTaskSchedulerTests.java @@ -19,14 +19,15 @@ import static com.swirlds.common.test.fixtures.AssertionUtils.assertEventuallyEquals; import static com.swirlds.common.test.fixtures.AssertionUtils.assertEventuallyTrue; import static com.swirlds.common.test.fixtures.RandomUtils.getRandomPrintSeed; -import static com.swirlds.common.wiring.schedulers.builders.TaskSchedulerBuilder.UNLIMITED_CAPACITY; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerBuilder.UNLIMITED_CAPACITY; import static java.util.concurrent.TimeUnit.MICROSECONDS; import static org.junit.jupiter.api.Assertions.assertEquals; import com.swirlds.common.TestWiringModelBuilder; -import com.swirlds.common.wiring.model.WiringModel; -import com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType; -import com.swirlds.common.wiring.wires.input.BindableInputWire; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.wires.input.BindableInputWire; import edu.umd.cs.findbugs.annotations.Nullable; import java.time.Duration; import java.util.Random; diff --git a/platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring/schedulers/DefaultSquelcherTests.java b/platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring/schedulers/DefaultSquelcherTests.java index b51c7723601..88f99d0a7e8 100644 --- a/platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring/schedulers/DefaultSquelcherTests.java +++ b/platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring/schedulers/DefaultSquelcherTests.java @@ -20,8 +20,8 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; -import com.swirlds.common.wiring.schedulers.internal.DefaultSquelcher; -import com.swirlds.common.wiring.schedulers.internal.Squelcher; +import org.hiero.wiring.framework.schedulers.internal.DefaultSquelcher; +import org.hiero.wiring.framework.schedulers.internal.Squelcher; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring/schedulers/DirectTaskSchedulerTests.java b/platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring/schedulers/DirectTaskSchedulerTests.java index 40ce0694258..0ecbc815ece 100644 --- a/platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring/schedulers/DirectTaskSchedulerTests.java +++ b/platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring/schedulers/DirectTaskSchedulerTests.java @@ -21,12 +21,13 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import com.swirlds.common.TestWiringModelBuilder; -import com.swirlds.common.wiring.counters.StandardObjectCounter; -import com.swirlds.common.wiring.model.WiringModel; -import com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType; -import com.swirlds.common.wiring.wires.SolderType; -import com.swirlds.common.wiring.wires.input.BindableInputWire; -import com.swirlds.common.wiring.wires.output.OutputWire; +import org.hiero.wiring.framework.counters.StandardObjectCounter; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.wires.SolderType; +import org.hiero.wiring.framework.wires.input.BindableInputWire; +import org.hiero.wiring.framework.wires.output.OutputWire; import java.lang.Thread.UncaughtExceptionHandler; import java.time.Duration; import java.util.Random; diff --git a/platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring/schedulers/HeartbeatSchedulerTests.java b/platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring/schedulers/HeartbeatSchedulerTests.java index 29ce20f57a6..a95d400b71c 100644 --- a/platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring/schedulers/HeartbeatSchedulerTests.java +++ b/platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring/schedulers/HeartbeatSchedulerTests.java @@ -23,9 +23,10 @@ import com.swirlds.base.test.fixtures.time.FakeTime; import com.swirlds.common.context.PlatformContext; import com.swirlds.common.test.fixtures.platform.TestPlatformContextBuilder; -import com.swirlds.common.wiring.model.WiringModel; -import com.swirlds.common.wiring.model.WiringModelBuilder; -import com.swirlds.common.wiring.wires.input.BindableInputWire; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.model.WiringModelBuilder; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.wires.input.BindableInputWire; import java.time.Duration; import java.time.Instant; import java.util.concurrent.atomic.AtomicLong; diff --git a/platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring/schedulers/SequentialTaskSchedulerTests.java b/platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring/schedulers/SequentialTaskSchedulerTests.java index 2cbc30150b1..2f85c373262 100644 --- a/platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring/schedulers/SequentialTaskSchedulerTests.java +++ b/platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring/schedulers/SequentialTaskSchedulerTests.java @@ -22,7 +22,7 @@ import static com.swirlds.common.test.fixtures.RandomUtils.getRandomPrintSeed; import static com.swirlds.common.threading.manager.AdHocThreadManager.getStaticThreadManager; import static com.swirlds.common.utility.NonCryptographicHashing.hash32; -import static com.swirlds.common.wiring.schedulers.builders.TaskSchedulerBuilder.UNLIMITED_CAPACITY; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerBuilder.UNLIMITED_CAPACITY; import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.concurrent.TimeUnit.NANOSECONDS; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -35,14 +35,15 @@ import com.swirlds.common.test.fixtures.RandomUtils; import com.swirlds.common.test.fixtures.platform.TestPlatformContextBuilder; import com.swirlds.common.threading.framework.config.ThreadConfiguration; -import com.swirlds.common.wiring.counters.BackpressureObjectCounter; -import com.swirlds.common.wiring.counters.ObjectCounter; -import com.swirlds.common.wiring.model.WiringModel; -import com.swirlds.common.wiring.model.WiringModelBuilder; -import com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType; -import com.swirlds.common.wiring.wires.SolderType; -import com.swirlds.common.wiring.wires.input.BindableInputWire; -import com.swirlds.common.wiring.wires.output.StandardOutputWire; +import org.hiero.wiring.framework.counters.BackpressureObjectCounter; +import org.hiero.wiring.framework.counters.ObjectCounter; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.model.WiringModelBuilder; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.wires.SolderType; +import org.hiero.wiring.framework.wires.input.BindableInputWire; +import org.hiero.wiring.framework.wires.output.StandardOutputWire; import java.time.Duration; import java.util.HashSet; import java.util.Random; diff --git a/platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring/schedulers/ThrowingSquelcherTests.java b/platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring/schedulers/ThrowingSquelcherTests.java index 7185ef8f527..2b800cb23cb 100644 --- a/platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring/schedulers/ThrowingSquelcherTests.java +++ b/platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring/schedulers/ThrowingSquelcherTests.java @@ -19,8 +19,8 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertThrows; -import com.swirlds.common.wiring.schedulers.internal.Squelcher; -import com.swirlds.common.wiring.schedulers.internal.ThrowingSquelcher; +import org.hiero.wiring.framework.schedulers.internal.Squelcher; +import org.hiero.wiring.framework.schedulers.internal.ThrowingSquelcher; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring/transformers/TaskSchedulerTransformersTests.java b/platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring/transformers/TaskSchedulerTransformersTests.java index f8a970c7e77..7b460a84692 100644 --- a/platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring/transformers/TaskSchedulerTransformersTests.java +++ b/platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring/transformers/TaskSchedulerTransformersTests.java @@ -23,11 +23,12 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import com.swirlds.common.TestWiringModelBuilder; -import com.swirlds.common.wiring.model.WiringModel; -import com.swirlds.common.wiring.schedulers.TaskScheduler; -import com.swirlds.common.wiring.wires.SolderType; -import com.swirlds.common.wiring.wires.input.BindableInputWire; -import com.swirlds.common.wiring.wires.output.OutputWire; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.transformers.AdvancedTransformation; +import org.hiero.wiring.framework.wires.SolderType; +import org.hiero.wiring.framework.wires.input.BindableInputWire; +import org.hiero.wiring.framework.wires.output.OutputWire; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; import java.lang.Thread.UncaughtExceptionHandler; diff --git a/platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring/wires/OutputWireTests.java b/platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring/wires/OutputWireTests.java index cacf3edcfc7..d320089c5fa 100644 --- a/platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring/wires/OutputWireTests.java +++ b/platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring/wires/OutputWireTests.java @@ -21,12 +21,12 @@ import com.swirlds.common.context.PlatformContext; import com.swirlds.common.test.fixtures.platform.TestPlatformContextBuilder; -import com.swirlds.common.wiring.model.WiringModel; -import com.swirlds.common.wiring.model.WiringModelBuilder; -import com.swirlds.common.wiring.schedulers.TaskScheduler; -import com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType; -import com.swirlds.common.wiring.wires.input.BindableInputWire; -import com.swirlds.common.wiring.wires.input.InputWire; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.model.WiringModelBuilder; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.wires.input.BindableInputWire; +import org.hiero.wiring.framework.wires.input.InputWire; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; import org.junit.jupiter.api.Test; diff --git a/platform-sdk/swirlds-merkledb/src/main/java/com/swirlds/merkledb/files/hashmap/HalfDiskHashMap.java b/platform-sdk/swirlds-merkledb/src/main/java/com/swirlds/merkledb/files/hashmap/HalfDiskHashMap.java index 4d746702bb0..34b6713203d 100644 --- a/platform-sdk/swirlds-merkledb/src/main/java/com/swirlds/merkledb/files/hashmap/HalfDiskHashMap.java +++ b/platform-sdk/swirlds-merkledb/src/main/java/com/swirlds/merkledb/files/hashmap/HalfDiskHashMap.java @@ -22,7 +22,7 @@ import com.hedera.pbj.runtime.io.buffer.BufferedData; import com.hedera.pbj.runtime.io.buffer.Bytes; -import com.swirlds.common.wiring.tasks.AbstractTask; +import org.hiero.wiring.framework.tasks.AbstractTask; import com.swirlds.config.api.Configuration; import com.swirlds.merkledb.FileStatisticAware; import com.swirlds.merkledb.Snapshotable; diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/builder/PlatformBuilder.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/builder/PlatformBuilder.java index 74a13be5199..d5721284782 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/builder/PlatformBuilder.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/builder/PlatformBuilder.java @@ -32,9 +32,9 @@ import com.swirlds.common.crypto.Signature; import com.swirlds.common.notification.NotificationEngine; import com.swirlds.common.platform.NodeId; -import com.swirlds.common.wiring.WiringConfig; -import com.swirlds.common.wiring.model.WiringModel; -import com.swirlds.common.wiring.model.WiringModelBuilder; +import org.hiero.wiring.framework.WiringConfig; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.model.WiringModelBuilder; import com.swirlds.config.api.Configuration; import com.swirlds.platform.SwirldsPlatform; import com.swirlds.platform.consensus.ConsensusSnapshot; diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/builder/PlatformBuildingBlocks.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/builder/PlatformBuildingBlocks.java index 8b8b9e2bafc..b0f589df2aa 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/builder/PlatformBuildingBlocks.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/builder/PlatformBuildingBlocks.java @@ -21,7 +21,7 @@ import com.swirlds.common.context.PlatformContext; import com.swirlds.common.notification.NotificationEngine; import com.swirlds.common.platform.NodeId; -import com.swirlds.common.wiring.model.WiringModel; +import org.hiero.wiring.framework.model.WiringModel; import com.swirlds.platform.consensus.ConsensusSnapshot; import com.swirlds.platform.crypto.KeysAndCerts; import com.swirlds.platform.event.PlatformEvent; diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/builder/PlatformComponentBuilder.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/builder/PlatformComponentBuilder.java index 53415c3ee9e..786a64f2ee7 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/builder/PlatformComponentBuilder.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/builder/PlatformComponentBuilder.java @@ -103,6 +103,7 @@ import java.io.IOException; import java.io.UncheckedIOException; import java.util.Objects; +import org.hiero.wiring.framework.component.ComponentWiring; /** * The advanced platform builder is responsible for constructing platform components. This class is exposed so that @@ -116,7 +117,7 @@ *

  • A component must not communicate with other components except through the wiring framework * (with a very small number of exceptions due to tech debt that has not yet been paid off).
  • *
  • A component should have an interface and at default implementation.
  • - *
  • A component should use {@link com.swirlds.common.wiring.component.ComponentWiring ComponentWiring} to define + *
  • A component should use {@link ComponentWiring ComponentWiring} to define * wiring API.
  • *
  • The order in which components are constructed should not matter.
  • *
  • A component must not be a static singleton or use static stateful variables in any way.
  • diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/cli/DiagramCommand.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/cli/DiagramCommand.java index 51b49dbff62..7ba860a8418 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/cli/DiagramCommand.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/cli/DiagramCommand.java @@ -20,11 +20,11 @@ import com.swirlds.cli.utility.AbstractCommand; import com.swirlds.cli.utility.SubcommandOf; import com.swirlds.common.context.PlatformContext; -import com.swirlds.common.wiring.model.WiringModel; -import com.swirlds.common.wiring.model.WiringModelBuilder; -import com.swirlds.common.wiring.model.diagram.ModelEdgeSubstitution; -import com.swirlds.common.wiring.model.diagram.ModelGroup; -import com.swirlds.common.wiring.model.diagram.ModelManualLink; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.model.WiringModelBuilder; +import org.hiero.wiring.framework.model.diagram.ModelEdgeSubstitution; +import org.hiero.wiring.framework.model.diagram.ModelGroup; +import org.hiero.wiring.framework.model.diagram.ModelManualLink; import com.swirlds.config.api.Configuration; import com.swirlds.config.api.ConfigurationBuilder; import com.swirlds.platform.builder.ApplicationCallbacks; diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/cli/DiagramLegendCommand.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/cli/DiagramLegendCommand.java index 3e2c598b4c3..90fdd5caab9 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/cli/DiagramLegendCommand.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/cli/DiagramLegendCommand.java @@ -19,14 +19,14 @@ import com.swirlds.cli.utility.AbstractCommand; import com.swirlds.cli.utility.SubcommandOf; import com.swirlds.common.context.PlatformContext; -import com.swirlds.common.wiring.model.WiringModel; -import com.swirlds.common.wiring.model.WiringModelBuilder; -import com.swirlds.common.wiring.model.diagram.ModelEdgeSubstitution; -import com.swirlds.common.wiring.model.diagram.ModelGroup; -import com.swirlds.common.wiring.model.diagram.ModelManualLink; -import com.swirlds.common.wiring.schedulers.TaskScheduler; -import com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType; -import com.swirlds.common.wiring.wires.SolderType; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.model.WiringModelBuilder; +import org.hiero.wiring.framework.model.diagram.ModelEdgeSubstitution; +import org.hiero.wiring.framework.model.diagram.ModelGroup; +import org.hiero.wiring.framework.model.diagram.ModelManualLink; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.wires.SolderType; import com.swirlds.config.api.Configuration; import com.swirlds.config.api.ConfigurationBuilder; import com.swirlds.platform.config.DefaultConfiguration; diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/components/AppNotifier.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/components/AppNotifier.java index e89714a8211..0ad1eabda04 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/components/AppNotifier.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/components/AppNotifier.java @@ -16,7 +16,7 @@ package com.swirlds.platform.components; -import com.swirlds.common.wiring.component.InputWireLabel; +import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.components.appcomm.CompleteStateNotificationWithCleanup; import com.swirlds.platform.listeners.ReconnectCompleteNotification; import com.swirlds.platform.listeners.StateWriteToDiskCompleteNotification; diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/components/EventWindowManager.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/components/EventWindowManager.java index f390aa15fb1..55a6acf5df7 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/components/EventWindowManager.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/components/EventWindowManager.java @@ -16,7 +16,7 @@ package com.swirlds.platform.components; -import com.swirlds.common.wiring.component.InputWireLabel; +import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.consensus.EventWindow; import com.swirlds.platform.internal.ConsensusRound; import edu.umd.cs.findbugs.annotations.NonNull; diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/components/SavedStateController.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/components/SavedStateController.java index c3123d3c629..657127f7bff 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/components/SavedStateController.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/components/SavedStateController.java @@ -16,7 +16,7 @@ package com.swirlds.platform.components; -import com.swirlds.common.wiring.component.InputWireLabel; +import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.state.signed.ReservedSignedState; import com.swirlds.platform.state.signed.SignedState; import com.swirlds.platform.wiring.components.StateAndRound; diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/components/appcomm/LatestCompleteStateNotifier.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/components/appcomm/LatestCompleteStateNotifier.java index 76844ddad7a..af435aa9d6d 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/components/appcomm/LatestCompleteStateNotifier.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/components/appcomm/LatestCompleteStateNotifier.java @@ -16,7 +16,7 @@ package com.swirlds.platform.components.appcomm; -import com.swirlds.common.wiring.component.InputWireLabel; +import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.state.signed.ReservedSignedState; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/components/consensus/ConsensusEngine.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/components/consensus/ConsensusEngine.java index 4a7639a1c28..b14df2f7b66 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/components/consensus/ConsensusEngine.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/components/consensus/ConsensusEngine.java @@ -16,7 +16,7 @@ package com.swirlds.platform.components.consensus; -import com.swirlds.common.wiring.component.InputWireLabel; +import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.Consensus; import com.swirlds.platform.consensus.ConsensusSnapshot; import com.swirlds.platform.event.PlatformEvent; diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/config/PlatformConfigurationExtension.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/config/PlatformConfigurationExtension.java index 0f38a026ec1..bf3188b5fda 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/config/PlatformConfigurationExtension.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/config/PlatformConfigurationExtension.java @@ -27,8 +27,8 @@ import com.swirlds.common.metrics.platform.prometheus.PrometheusConfig; import com.swirlds.common.platform.NodeId; import com.swirlds.common.platform.NodeIdConverter; -import com.swirlds.common.wiring.WiringConfig; -import com.swirlds.common.wiring.schedulers.builders.TaskSchedulerConfiguration; +import org.hiero.wiring.framework.WiringConfig; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerConfiguration; import com.swirlds.config.api.ConfigurationExtension; import com.swirlds.logging.api.internal.configuration.InternalLoggingConfig; import com.swirlds.merkledb.config.MerkleDbConfig; diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/FutureEventBuffer.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/FutureEventBuffer.java index 59eb3d2000e..84ee1f1f355 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/FutureEventBuffer.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/FutureEventBuffer.java @@ -16,7 +16,7 @@ package com.swirlds.platform.event; -import com.swirlds.common.wiring.component.InputWireLabel; +import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.consensus.EventWindow; import com.swirlds.platform.wiring.NoInput; import edu.umd.cs.findbugs.annotations.NonNull; diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/branching/BranchDetector.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/branching/BranchDetector.java index b1fd50897a8..542795a0218 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/branching/BranchDetector.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/branching/BranchDetector.java @@ -16,7 +16,7 @@ package com.swirlds.platform.event.branching; -import com.swirlds.common.wiring.component.InputWireLabel; +import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.consensus.EventWindow; import com.swirlds.platform.event.PlatformEvent; import edu.umd.cs.findbugs.annotations.NonNull; diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/branching/BranchReporter.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/branching/BranchReporter.java index 5b09594134a..dc53a6e14b8 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/branching/BranchReporter.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/branching/BranchReporter.java @@ -16,7 +16,7 @@ package com.swirlds.platform.event.branching; -import com.swirlds.common.wiring.component.InputWireLabel; +import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.consensus.EventWindow; import com.swirlds.platform.event.PlatformEvent; import edu.umd.cs.findbugs.annotations.NonNull; diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/creation/EventCreationManager.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/creation/EventCreationManager.java index 4625c4c07e0..a66de462ed2 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/creation/EventCreationManager.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/creation/EventCreationManager.java @@ -16,7 +16,7 @@ package com.swirlds.platform.event.creation; -import com.swirlds.common.wiring.component.InputWireLabel; +import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.consensus.EventWindow; import com.swirlds.platform.event.PlatformEvent; import com.swirlds.platform.system.events.UnsignedEvent; diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/deduplication/EventDeduplicator.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/deduplication/EventDeduplicator.java index 7e13c23dedb..1be735bed5c 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/deduplication/EventDeduplicator.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/deduplication/EventDeduplicator.java @@ -16,7 +16,7 @@ package com.swirlds.platform.event.deduplication; -import com.swirlds.common.wiring.component.InputWireLabel; +import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.consensus.EventWindow; import com.swirlds.platform.event.PlatformEvent; import com.swirlds.platform.wiring.NoInput; diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/hashing/EventHasher.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/hashing/EventHasher.java index 47958ef6844..c3fec5f0867 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/hashing/EventHasher.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/hashing/EventHasher.java @@ -16,7 +16,7 @@ package com.swirlds.platform.event.hashing; -import com.swirlds.common.wiring.component.InputWireLabel; +import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.event.PlatformEvent; import edu.umd.cs.findbugs.annotations.NonNull; diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/linking/InOrderLinker.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/linking/InOrderLinker.java index 9bb9ec29513..e669da3dcbf 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/linking/InOrderLinker.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/linking/InOrderLinker.java @@ -16,7 +16,7 @@ package com.swirlds.platform.event.linking; -import com.swirlds.common.wiring.component.InputWireLabel; +import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.consensus.EventWindow; import com.swirlds.platform.event.PlatformEvent; import com.swirlds.platform.gossip.shadowgraph.Shadowgraph; diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/orphan/OrphanBuffer.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/orphan/OrphanBuffer.java index 5870b6c3070..26da523e55e 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/orphan/OrphanBuffer.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/orphan/OrphanBuffer.java @@ -16,7 +16,7 @@ package com.swirlds.platform.event.orphan; -import com.swirlds.common.wiring.component.InputWireLabel; +import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.consensus.EventWindow; import com.swirlds.platform.event.PlatformEvent; import edu.umd.cs.findbugs.annotations.NonNull; diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/preconsensus/InlinePcesWriter.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/preconsensus/InlinePcesWriter.java index 0843f86dd8c..44c5ea43d09 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/preconsensus/InlinePcesWriter.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/preconsensus/InlinePcesWriter.java @@ -16,7 +16,7 @@ package com.swirlds.platform.event.preconsensus; -import com.swirlds.common.wiring.component.InputWireLabel; +import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.consensus.EventWindow; import com.swirlds.platform.event.PlatformEvent; import edu.umd.cs.findbugs.annotations.NonNull; diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/preconsensus/PcesReplayer.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/preconsensus/PcesReplayer.java index a190688c081..ceacef5b659 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/preconsensus/PcesReplayer.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/preconsensus/PcesReplayer.java @@ -26,7 +26,7 @@ import com.swirlds.common.formatting.UnitFormatter; import com.swirlds.common.io.IOIterator; import com.swirlds.common.utility.throttle.RateLimiter; -import com.swirlds.common.wiring.wires.output.StandardOutputWire; +import org.hiero.wiring.framework.wires.output.StandardOutputWire; import com.swirlds.platform.event.PlatformEvent; import com.swirlds.platform.state.signed.ReservedSignedState; import com.swirlds.platform.wiring.NoInput; diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/preconsensus/PcesSequencer.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/preconsensus/PcesSequencer.java index 2403568d41d..08ba8c72266 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/preconsensus/PcesSequencer.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/preconsensus/PcesSequencer.java @@ -16,7 +16,7 @@ package com.swirlds.platform.event.preconsensus; -import com.swirlds.common.wiring.component.InputWireLabel; +import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.event.PlatformEvent; import edu.umd.cs.findbugs.annotations.NonNull; diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/preconsensus/PcesWriter.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/preconsensus/PcesWriter.java index b04cbb44edc..408deb8e6c7 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/preconsensus/PcesWriter.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/preconsensus/PcesWriter.java @@ -16,7 +16,7 @@ package com.swirlds.platform.event.preconsensus; -import com.swirlds.common.wiring.component.InputWireLabel; +import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.consensus.EventWindow; import com.swirlds.platform.event.PlatformEvent; import edu.umd.cs.findbugs.annotations.NonNull; diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/preconsensus/durability/RoundDurabilityBuffer.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/preconsensus/durability/RoundDurabilityBuffer.java index 0d9b46c8424..0f7a4b50073 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/preconsensus/durability/RoundDurabilityBuffer.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/preconsensus/durability/RoundDurabilityBuffer.java @@ -16,7 +16,7 @@ package com.swirlds.platform.event.preconsensus.durability; -import com.swirlds.common.wiring.component.InputWireLabel; +import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.internal.ConsensusRound; import edu.umd.cs.findbugs.annotations.NonNull; import java.time.Instant; diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/resubmitter/TransactionResubmitter.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/resubmitter/TransactionResubmitter.java index 8cb430a8f5a..d087471e40e 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/resubmitter/TransactionResubmitter.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/resubmitter/TransactionResubmitter.java @@ -17,7 +17,7 @@ package com.swirlds.platform.event.resubmitter; import com.hedera.hapi.platform.event.EventTransaction; -import com.swirlds.common.wiring.component.InputWireLabel; +import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.consensus.EventWindow; import com.swirlds.platform.event.PlatformEvent; import edu.umd.cs.findbugs.annotations.NonNull; diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/signing/SelfEventSigner.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/signing/SelfEventSigner.java index e5dd2dfcf1b..496367f66b5 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/signing/SelfEventSigner.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/signing/SelfEventSigner.java @@ -16,7 +16,7 @@ package com.swirlds.platform.event.signing; -import com.swirlds.common.wiring.component.InputWireLabel; +import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.event.PlatformEvent; import com.swirlds.platform.system.events.UnsignedEvent; import edu.umd.cs.findbugs.annotations.NonNull; diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/stale/DefaultStaleEventDetector.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/stale/DefaultStaleEventDetector.java index f26e32dee5d..db8b201f419 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/stale/DefaultStaleEventDetector.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/stale/DefaultStaleEventDetector.java @@ -20,7 +20,7 @@ import com.swirlds.common.context.PlatformContext; import com.swirlds.common.platform.NodeId; -import com.swirlds.common.wiring.transformers.RoutableData; +import org.hiero.wiring.framework.transformers.RoutableData; import com.swirlds.platform.consensus.EventWindow; import com.swirlds.platform.event.AncientMode; import com.swirlds.platform.event.PlatformEvent; diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/stale/StaleEventDetector.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/stale/StaleEventDetector.java index e0fc20c6c43..c96e641c132 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/stale/StaleEventDetector.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/stale/StaleEventDetector.java @@ -16,8 +16,8 @@ package com.swirlds.platform.event.stale; -import com.swirlds.common.wiring.component.InputWireLabel; -import com.swirlds.common.wiring.transformers.RoutableData; +import org.hiero.wiring.framework.component.InputWireLabel; +import org.hiero.wiring.framework.transformers.RoutableData; import com.swirlds.platform.consensus.EventWindow; import com.swirlds.platform.event.PlatformEvent; import com.swirlds.platform.internal.ConsensusRound; diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/stream/ConsensusEventStream.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/stream/ConsensusEventStream.java index 159d7c55c6a..9dd17ea04ac 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/stream/ConsensusEventStream.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/stream/ConsensusEventStream.java @@ -17,7 +17,7 @@ package com.swirlds.platform.event.stream; import com.swirlds.common.stream.RunningEventHashOverride; -import com.swirlds.common.wiring.component.InputWireLabel; +import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.system.events.CesEvent; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.List; diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/validation/EventSignatureValidator.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/validation/EventSignatureValidator.java index 7a93e1b73da..0bc83d5aac3 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/validation/EventSignatureValidator.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/validation/EventSignatureValidator.java @@ -16,7 +16,7 @@ package com.swirlds.platform.event.validation; -import com.swirlds.common.wiring.component.InputWireLabel; +import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.consensus.EventWindow; import com.swirlds.platform.event.PlatformEvent; import edu.umd.cs.findbugs.annotations.NonNull; diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/validation/InternalEventValidator.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/validation/InternalEventValidator.java index 2330965ab0b..e675ca03992 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/validation/InternalEventValidator.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/validation/InternalEventValidator.java @@ -16,7 +16,7 @@ package com.swirlds.platform.event.validation; -import com.swirlds.common.wiring.component.InputWireLabel; +import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.event.PlatformEvent; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/eventhandling/DefaultTransactionHandler.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/eventhandling/DefaultTransactionHandler.java index 16c3b238608..80f4759131c 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/eventhandling/DefaultTransactionHandler.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/eventhandling/DefaultTransactionHandler.java @@ -31,7 +31,7 @@ import com.swirlds.common.context.PlatformContext; import com.swirlds.common.crypto.Hash; import com.swirlds.common.stream.RunningEventHashOverride; -import com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; import com.swirlds.platform.components.transaction.system.ScopedSystemTransaction; import com.swirlds.platform.consensus.ConsensusConfig; import com.swirlds.platform.crypto.CryptoStatic; diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/eventhandling/TransactionHandler.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/eventhandling/TransactionHandler.java index a533c68e145..89dcd1835df 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/eventhandling/TransactionHandler.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/eventhandling/TransactionHandler.java @@ -17,7 +17,7 @@ package com.swirlds.platform.eventhandling; import com.swirlds.common.stream.RunningEventHashOverride; -import com.swirlds.common.wiring.component.InputWireLabel; +import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.internal.ConsensusRound; import com.swirlds.platform.wiring.components.StateAndRound; import edu.umd.cs.findbugs.annotations.NonNull; diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/eventhandling/TransactionPrehandler.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/eventhandling/TransactionPrehandler.java index de53d1258ab..0b9c21246db 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/eventhandling/TransactionPrehandler.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/eventhandling/TransactionPrehandler.java @@ -17,7 +17,7 @@ package com.swirlds.platform.eventhandling; import com.hedera.hapi.platform.event.StateSignatureTransaction; -import com.swirlds.common.wiring.component.InputWireLabel; +import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.components.transaction.system.ScopedSystemTransaction; import com.swirlds.platform.event.PlatformEvent; import edu.umd.cs.findbugs.annotations.NonNull; diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/gossip/SyncGossip.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/gossip/SyncGossip.java index bbc127c84da..093dbd77e77 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/gossip/SyncGossip.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/gossip/SyncGossip.java @@ -30,9 +30,9 @@ import com.swirlds.common.threading.manager.ThreadManager; import com.swirlds.common.threading.pool.CachedPoolParallelExecutor; import com.swirlds.common.threading.pool.ParallelExecutor; -import com.swirlds.common.wiring.model.WiringModel; -import com.swirlds.common.wiring.wires.input.BindableInputWire; -import com.swirlds.common.wiring.wires.output.StandardOutputWire; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.wires.input.BindableInputWire; +import org.hiero.wiring.framework.wires.output.StandardOutputWire; import com.swirlds.platform.Utilities; import com.swirlds.platform.config.BasicConfig; import com.swirlds.platform.config.StateConfig; diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/pool/TransactionPool.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/pool/TransactionPool.java index 5f53a15207c..824b14b2650 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/pool/TransactionPool.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/pool/TransactionPool.java @@ -17,7 +17,7 @@ package com.swirlds.platform.pool; import com.hedera.hapi.platform.event.StateSignatureTransaction; -import com.swirlds.common.wiring.component.InputWireLabel; +import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.system.status.PlatformStatus; import edu.umd.cs.findbugs.annotations.NonNull; import java.time.Duration; diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/publisher/PlatformPublisher.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/publisher/PlatformPublisher.java index e4d2792e012..8284bc4bced 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/publisher/PlatformPublisher.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/publisher/PlatformPublisher.java @@ -16,7 +16,7 @@ package com.swirlds.platform.publisher; -import com.swirlds.common.wiring.component.InputWireLabel; +import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.consensus.ConsensusSnapshot; import com.swirlds.platform.event.PlatformEvent; import edu.umd.cs.findbugs.annotations.NonNull; diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/state/hasher/StateHasher.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/state/hasher/StateHasher.java index 63c72d1ef32..eebb4db9d6d 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/state/hasher/StateHasher.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/state/hasher/StateHasher.java @@ -16,7 +16,7 @@ package com.swirlds.platform.state.hasher; -import com.swirlds.common.wiring.component.InputWireLabel; +import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.wiring.components.StateAndRound; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/state/hashlogger/HashLogger.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/state/hashlogger/HashLogger.java index 78055ed0d74..9cfedff68c2 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/state/hashlogger/HashLogger.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/state/hashlogger/HashLogger.java @@ -16,7 +16,7 @@ package com.swirlds.platform.state.hashlogger; -import com.swirlds.common.wiring.component.InputWireLabel; +import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.state.signed.ReservedSignedState; import edu.umd.cs.findbugs.annotations.NonNull; diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/state/nexus/LatestCompleteStateNexus.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/state/nexus/LatestCompleteStateNexus.java index e98bd1c8b07..14d32f1855b 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/state/nexus/LatestCompleteStateNexus.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/state/nexus/LatestCompleteStateNexus.java @@ -16,7 +16,7 @@ package com.swirlds.platform.state.nexus; -import com.swirlds.common.wiring.component.InputWireLabel; +import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.consensus.EventWindow; import com.swirlds.platform.state.signed.ReservedSignedState; import edu.umd.cs.findbugs.annotations.NonNull; diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/state/nexus/SignedStateNexus.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/state/nexus/SignedStateNexus.java index 4d83c6bf6fb..ba6b49d94b5 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/state/nexus/SignedStateNexus.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/state/nexus/SignedStateNexus.java @@ -17,7 +17,7 @@ package com.swirlds.platform.state.nexus; import com.swirlds.common.utility.Clearable; -import com.swirlds.common.wiring.component.SchedulerLabel; +import org.hiero.wiring.framework.component.SchedulerLabel; import com.swirlds.platform.consensus.ConsensusConstants; import com.swirlds.platform.state.signed.ReservedSignedState; import edu.umd.cs.findbugs.annotations.NonNull; diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/state/signed/StateSignatureCollector.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/state/signed/StateSignatureCollector.java index 7a9493ed3cc..02b4f103f9f 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/state/signed/StateSignatureCollector.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/state/signed/StateSignatureCollector.java @@ -17,7 +17,7 @@ package com.swirlds.platform.state.signed; import com.hedera.hapi.platform.event.StateSignatureTransaction; -import com.swirlds.common.wiring.component.InputWireLabel; +import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.components.transaction.system.ScopedSystemTransaction; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/system/events/BirthRoundMigrationShim.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/system/events/BirthRoundMigrationShim.java index 3bf9e8a4724..57ea972546a 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/system/events/BirthRoundMigrationShim.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/system/events/BirthRoundMigrationShim.java @@ -16,7 +16,7 @@ package com.swirlds.platform.system.events; -import com.swirlds.common.wiring.component.InputWireLabel; +import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.event.PlatformEvent; import edu.umd.cs.findbugs.annotations.NonNull; diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/system/status/StatusStateMachine.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/system/status/StatusStateMachine.java index 5d3f995f479..04e8f4a442d 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/system/status/StatusStateMachine.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/system/status/StatusStateMachine.java @@ -16,7 +16,7 @@ package com.swirlds.platform.system.status; -import com.swirlds.common.wiring.component.InputWireLabel; +import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.system.status.actions.PlatformStatusAction; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/PlatformCoordinator.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/PlatformCoordinator.java index c424d01ee5b..a733cbe6ca8 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/PlatformCoordinator.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/PlatformCoordinator.java @@ -17,8 +17,8 @@ package com.swirlds.platform.wiring; import com.hedera.hapi.platform.event.StateSignatureTransaction; -import com.swirlds.common.wiring.component.ComponentWiring; -import com.swirlds.common.wiring.transformers.RoutableData; +import org.hiero.wiring.framework.component.ComponentWiring; +import org.hiero.wiring.framework.transformers.RoutableData; import com.swirlds.platform.components.consensus.ConsensusEngine; import com.swirlds.platform.components.transaction.system.ScopedSystemTransaction; import com.swirlds.platform.event.PlatformEvent; diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/PlatformSchedulersConfig.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/PlatformSchedulersConfig.java index 216edb4fb0a..e673886fc6f 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/PlatformSchedulersConfig.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/PlatformSchedulersConfig.java @@ -16,7 +16,7 @@ package com.swirlds.platform.wiring; -import com.swirlds.common.wiring.schedulers.builders.TaskSchedulerConfiguration; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerConfiguration; import com.swirlds.config.api.ConfigData; import com.swirlds.config.api.ConfigProperty; import java.time.Duration; diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/PlatformWiring.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/PlatformWiring.java index d615e073540..f302606e18b 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/PlatformWiring.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/PlatformWiring.java @@ -16,10 +16,10 @@ package com.swirlds.platform.wiring; -import static com.swirlds.common.wiring.schedulers.builders.TaskSchedulerConfiguration.DIRECT_THREADSAFE_CONFIGURATION; -import static com.swirlds.common.wiring.schedulers.builders.TaskSchedulerConfiguration.NO_OP_CONFIGURATION; -import static com.swirlds.common.wiring.wires.SolderType.INJECT; -import static com.swirlds.common.wiring.wires.SolderType.OFFER; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerConfiguration.DIRECT_THREADSAFE_CONFIGURATION; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerConfiguration.NO_OP_CONFIGURATION; +import static org.hiero.wiring.framework.wires.SolderType.INJECT; +import static org.hiero.wiring.framework.wires.SolderType.OFFER; import static com.swirlds.platform.event.stale.StaleEventDetectorOutput.SELF_EVENT; import static com.swirlds.platform.event.stale.StaleEventDetectorOutput.STALE_SELF_EVENT; @@ -27,15 +27,15 @@ import com.swirlds.common.context.PlatformContext; import com.swirlds.common.io.IOIterator; import com.swirlds.common.stream.RunningEventHashOverride; -import com.swirlds.common.wiring.component.ComponentWiring; -import com.swirlds.common.wiring.model.WiringModel; -import com.swirlds.common.wiring.schedulers.builders.TaskSchedulerConfiguration; -import com.swirlds.common.wiring.transformers.RoutableData; -import com.swirlds.common.wiring.transformers.WireFilter; -import com.swirlds.common.wiring.transformers.WireTransformer; -import com.swirlds.common.wiring.wires.input.InputWire; -import com.swirlds.common.wiring.wires.output.OutputWire; -import com.swirlds.common.wiring.wires.output.StandardOutputWire; +import org.hiero.wiring.framework.component.ComponentWiring; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerConfiguration; +import org.hiero.wiring.framework.transformers.RoutableData; +import org.hiero.wiring.framework.transformers.WireFilter; +import org.hiero.wiring.framework.transformers.WireTransformer; +import org.hiero.wiring.framework.wires.input.InputWire; +import org.hiero.wiring.framework.wires.output.OutputWire; +import org.hiero.wiring.framework.wires.output.StandardOutputWire; import com.swirlds.platform.builder.ApplicationCallbacks; import com.swirlds.platform.builder.PlatformComponentBuilder; import com.swirlds.platform.components.AppNotifier; diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/SignedStateReserver.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/SignedStateReserver.java index d1a9ce83c82..612c71408c6 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/SignedStateReserver.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/SignedStateReserver.java @@ -16,7 +16,7 @@ package com.swirlds.platform.wiring; -import com.swirlds.common.wiring.transformers.AdvancedTransformation; +import org.hiero.wiring.framework.transformers.AdvancedTransformation; import com.swirlds.platform.state.signed.ReservedSignedState; import edu.umd.cs.findbugs.annotations.NonNull; diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/StateAndRoundReserver.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/StateAndRoundReserver.java index 803b85ca89a..fff1c5368eb 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/StateAndRoundReserver.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/StateAndRoundReserver.java @@ -16,7 +16,7 @@ package com.swirlds.platform.wiring; -import com.swirlds.common.wiring.transformers.AdvancedTransformation; +import org.hiero.wiring.framework.transformers.AdvancedTransformation; import com.swirlds.platform.wiring.components.StateAndRound; import edu.umd.cs.findbugs.annotations.NonNull; diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/StateAndRoundToStateReserver.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/StateAndRoundToStateReserver.java index 1da7d97cb6f..a188a1f2e59 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/StateAndRoundToStateReserver.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/StateAndRoundToStateReserver.java @@ -16,7 +16,7 @@ package com.swirlds.platform.wiring; -import com.swirlds.common.wiring.transformers.AdvancedTransformation; +import org.hiero.wiring.framework.transformers.AdvancedTransformation; import com.swirlds.platform.state.signed.ReservedSignedState; import com.swirlds.platform.wiring.components.StateAndRound; import edu.umd.cs.findbugs.annotations.NonNull; diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/components/Gossip.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/components/Gossip.java index c077c4e48ad..961615fa96a 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/components/Gossip.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/components/Gossip.java @@ -16,9 +16,9 @@ package com.swirlds.platform.wiring.components; -import com.swirlds.common.wiring.model.WiringModel; -import com.swirlds.common.wiring.wires.input.BindableInputWire; -import com.swirlds.common.wiring.wires.output.StandardOutputWire; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.wires.input.BindableInputWire; +import org.hiero.wiring.framework.wires.output.StandardOutputWire; import com.swirlds.platform.consensus.EventWindow; import com.swirlds.platform.event.PlatformEvent; import com.swirlds.platform.system.status.PlatformStatus; diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/components/GossipWiring.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/components/GossipWiring.java index 7b1e0f5231c..17f6e88a27c 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/components/GossipWiring.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/components/GossipWiring.java @@ -17,12 +17,12 @@ package com.swirlds.platform.wiring.components; import com.swirlds.common.context.PlatformContext; -import com.swirlds.common.wiring.model.WiringModel; -import com.swirlds.common.wiring.schedulers.TaskScheduler; -import com.swirlds.common.wiring.wires.input.BindableInputWire; -import com.swirlds.common.wiring.wires.input.InputWire; -import com.swirlds.common.wiring.wires.output.OutputWire; -import com.swirlds.common.wiring.wires.output.StandardOutputWire; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.wires.input.BindableInputWire; +import org.hiero.wiring.framework.wires.input.InputWire; +import org.hiero.wiring.framework.wires.output.OutputWire; +import org.hiero.wiring.framework.wires.output.StandardOutputWire; import com.swirlds.platform.consensus.EventWindow; import com.swirlds.platform.event.PlatformEvent; import com.swirlds.platform.system.status.PlatformStatus; diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/components/PassThroughWiring.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/components/PassThroughWiring.java index 56cd89c7432..31339f99a0a 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/components/PassThroughWiring.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/components/PassThroughWiring.java @@ -16,12 +16,12 @@ package com.swirlds.platform.wiring.components; -import com.swirlds.common.wiring.model.WiringModel; -import com.swirlds.common.wiring.schedulers.TaskScheduler; -import com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType; -import com.swirlds.common.wiring.wires.input.BindableInputWire; -import com.swirlds.common.wiring.wires.input.InputWire; -import com.swirlds.common.wiring.wires.output.OutputWire; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.wires.input.BindableInputWire; +import org.hiero.wiring.framework.wires.input.InputWire; +import org.hiero.wiring.framework.wires.output.OutputWire; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.Objects; import java.util.function.Function; diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/components/PcesReplayerWiring.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/components/PcesReplayerWiring.java index 9183a1b7d84..9c152eae1f3 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/components/PcesReplayerWiring.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/components/PcesReplayerWiring.java @@ -16,16 +16,16 @@ package com.swirlds.platform.wiring.components; -import static com.swirlds.common.wiring.model.diagram.HyperlinkBuilder.platformCoreHyperlink; -import static com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType.DIRECT; +import static org.hiero.wiring.framework.model.diagram.HyperlinkBuilder.platformCoreHyperlink; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.DIRECT; import com.swirlds.common.io.IOIterator; -import com.swirlds.common.wiring.model.WiringModel; -import com.swirlds.common.wiring.schedulers.TaskScheduler; -import com.swirlds.common.wiring.wires.input.BindableInputWire; -import com.swirlds.common.wiring.wires.input.InputWire; -import com.swirlds.common.wiring.wires.output.OutputWire; -import com.swirlds.common.wiring.wires.output.StandardOutputWire; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.wires.input.BindableInputWire; +import org.hiero.wiring.framework.wires.input.InputWire; +import org.hiero.wiring.framework.wires.output.OutputWire; +import org.hiero.wiring.framework.wires.output.StandardOutputWire; import com.swirlds.platform.event.PlatformEvent; import com.swirlds.platform.event.preconsensus.PcesReplayer; import com.swirlds.platform.wiring.NoInput; diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/components/RunningEventHashOverrideWiring.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/components/RunningEventHashOverrideWiring.java index d9f08797d86..c38e94f1cbe 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/components/RunningEventHashOverrideWiring.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/components/RunningEventHashOverrideWiring.java @@ -16,15 +16,15 @@ package com.swirlds.platform.wiring.components; -import static com.swirlds.common.wiring.model.diagram.HyperlinkBuilder.platformCoreHyperlink; -import static com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType.DIRECT_THREADSAFE; +import static org.hiero.wiring.framework.model.diagram.HyperlinkBuilder.platformCoreHyperlink; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.DIRECT_THREADSAFE; import com.swirlds.common.stream.RunningEventHashOverride; -import com.swirlds.common.wiring.model.WiringModel; -import com.swirlds.common.wiring.schedulers.TaskScheduler; -import com.swirlds.common.wiring.wires.input.BindableInputWire; -import com.swirlds.common.wiring.wires.input.InputWire; -import com.swirlds.common.wiring.wires.output.OutputWire; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.wires.input.BindableInputWire; +import org.hiero.wiring.framework.wires.input.InputWire; +import org.hiero.wiring.framework.wires.output.OutputWire; import edu.umd.cs.findbugs.annotations.NonNull; /** diff --git a/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/components/EventWindowManagerTests.java b/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/components/EventWindowManagerTests.java index 143c9007fbe..4ac130166ed 100644 --- a/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/components/EventWindowManagerTests.java +++ b/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/components/EventWindowManagerTests.java @@ -22,10 +22,10 @@ import static org.mockito.Mockito.when; import com.swirlds.common.test.fixtures.platform.TestPlatformContextBuilder; -import com.swirlds.common.wiring.component.ComponentWiring; -import com.swirlds.common.wiring.model.WiringModel; -import com.swirlds.common.wiring.model.WiringModelBuilder; -import com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.component.ComponentWiring; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.model.WiringModelBuilder; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; import com.swirlds.platform.consensus.EventWindow; import com.swirlds.platform.internal.ConsensusRound; import java.util.concurrent.atomic.AtomicReference; diff --git a/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/event/stale/StaleEventDetectorTests.java b/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/event/stale/StaleEventDetectorTests.java index 8965d3fe7f7..73a4bd828a6 100644 --- a/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/event/stale/StaleEventDetectorTests.java +++ b/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/event/stale/StaleEventDetectorTests.java @@ -27,7 +27,7 @@ import com.swirlds.common.platform.NodeId; import com.swirlds.common.test.fixtures.Randotron; import com.swirlds.common.test.fixtures.platform.TestPlatformContextBuilder; -import com.swirlds.common.wiring.transformers.RoutableData; +import org.hiero.wiring.framework.transformers.RoutableData; import com.swirlds.config.api.Configuration; import com.swirlds.config.extensions.test.fixtures.TestConfigBuilder; import com.swirlds.platform.consensus.ConsensusSnapshot; diff --git a/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/event/stream/ConsensusEventStreamTest.java b/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/event/stream/ConsensusEventStreamTest.java index 84a327bcf86..667a174847c 100644 --- a/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/event/stream/ConsensusEventStreamTest.java +++ b/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/event/stream/ConsensusEventStreamTest.java @@ -27,10 +27,10 @@ import com.swirlds.common.stream.RunningEventHashOverride; import com.swirlds.common.test.fixtures.RandomUtils; import com.swirlds.common.test.fixtures.platform.TestPlatformContextBuilder; -import com.swirlds.common.wiring.component.ComponentWiring; -import com.swirlds.common.wiring.model.WiringModel; -import com.swirlds.common.wiring.model.WiringModelBuilder; -import com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.component.ComponentWiring; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.model.WiringModelBuilder; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; import com.swirlds.platform.system.events.CesEvent; import java.util.List; import java.util.Random; diff --git a/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/turtle/gossip/SimulatedGossipTests.java b/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/turtle/gossip/SimulatedGossipTests.java index 805b957a31f..2c9299db9a2 100644 --- a/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/turtle/gossip/SimulatedGossipTests.java +++ b/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/turtle/gossip/SimulatedGossipTests.java @@ -16,7 +16,7 @@ package com.swirlds.platform.turtle.gossip; -import static com.swirlds.common.wiring.schedulers.builders.TaskSchedulerConfiguration.DIRECT_THREADSAFE_CONFIGURATION; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerConfiguration.DIRECT_THREADSAFE_CONFIGURATION; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.mock; @@ -25,12 +25,12 @@ import com.swirlds.common.platform.NodeId; import com.swirlds.common.test.fixtures.Randotron; import com.swirlds.common.test.fixtures.platform.TestPlatformContextBuilder; -import com.swirlds.common.wiring.model.TraceableWiringModel; -import com.swirlds.common.wiring.model.WiringModel; -import com.swirlds.common.wiring.model.WiringModelBuilder; -import com.swirlds.common.wiring.schedulers.TaskScheduler; -import com.swirlds.common.wiring.wires.input.BindableInputWire; -import com.swirlds.common.wiring.wires.output.StandardOutputWire; +import org.hiero.wiring.framework.model.TraceableWiringModel; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.model.WiringModelBuilder; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.wires.input.BindableInputWire; +import org.hiero.wiring.framework.wires.output.StandardOutputWire; import com.swirlds.platform.event.PlatformEvent; import com.swirlds.platform.event.hashing.DefaultEventHasher; import com.swirlds.platform.system.address.AddressBook; diff --git a/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/turtle/runner/TurtleNode.java b/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/turtle/runner/TurtleNode.java index aef2e685229..196db2d3494 100644 --- a/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/turtle/runner/TurtleNode.java +++ b/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/turtle/runner/TurtleNode.java @@ -29,8 +29,8 @@ import com.swirlds.common.platform.NodeId; import com.swirlds.common.test.fixtures.Randotron; import com.swirlds.common.test.fixtures.platform.TestPlatformContextBuilder; -import com.swirlds.common.wiring.model.DeterministicWiringModel; -import com.swirlds.common.wiring.model.WiringModelBuilder; +import org.hiero.wiring.framework.model.DeterministicWiringModel; +import org.hiero.wiring.framework.model.WiringModelBuilder; import com.swirlds.config.api.Configuration; import com.swirlds.config.extensions.test.fixtures.TestConfigBuilder; import com.swirlds.platform.builder.PlatformBuilder; diff --git a/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/wiring/PlatformWiringTests.java b/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/wiring/PlatformWiringTests.java index 930e5cdfd76..fe39385beae 100644 --- a/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/wiring/PlatformWiringTests.java +++ b/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/wiring/PlatformWiringTests.java @@ -21,8 +21,8 @@ import com.swirlds.common.context.PlatformContext; import com.swirlds.common.test.fixtures.platform.TestPlatformContextBuilder; -import com.swirlds.common.wiring.model.WiringModel; -import com.swirlds.common.wiring.model.WiringModelBuilder; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.model.WiringModelBuilder; import com.swirlds.config.api.ConfigurationBuilder; import com.swirlds.platform.builder.ApplicationCallbacks; import com.swirlds.platform.builder.PlatformBuildingBlocks; diff --git a/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/wiring/SignedStateReserverTest.java b/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/wiring/SignedStateReserverTest.java index 9a9cecda908..4ee80ec4ac1 100644 --- a/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/wiring/SignedStateReserverTest.java +++ b/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/wiring/SignedStateReserverTest.java @@ -23,12 +23,12 @@ import com.swirlds.common.context.PlatformContext; import com.swirlds.common.test.fixtures.platform.TestPlatformContextBuilder; import com.swirlds.common.utility.ValueReference; -import com.swirlds.common.wiring.model.WiringModel; -import com.swirlds.common.wiring.model.WiringModelBuilder; -import com.swirlds.common.wiring.schedulers.TaskScheduler; -import com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType; -import com.swirlds.common.wiring.wires.input.BindableInputWire; -import com.swirlds.common.wiring.wires.output.OutputWire; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.model.WiringModelBuilder; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.wires.input.BindableInputWire; +import org.hiero.wiring.framework.wires.output.OutputWire; import com.swirlds.platform.crypto.SignatureVerifier; import com.swirlds.platform.state.PlatformMerkleStateRoot; import com.swirlds.platform.state.signed.ReservedSignedState; diff --git a/platform-sdk/swirlds-platform-core/src/testFixtures/java/com/swirlds/platform/test/fixtures/turtle/gossip/SimulatedGossip.java b/platform-sdk/swirlds-platform-core/src/testFixtures/java/com/swirlds/platform/test/fixtures/turtle/gossip/SimulatedGossip.java index f743ee4cac8..bfb6d77d954 100644 --- a/platform-sdk/swirlds-platform-core/src/testFixtures/java/com/swirlds/platform/test/fixtures/turtle/gossip/SimulatedGossip.java +++ b/platform-sdk/swirlds-platform-core/src/testFixtures/java/com/swirlds/platform/test/fixtures/turtle/gossip/SimulatedGossip.java @@ -17,9 +17,9 @@ package com.swirlds.platform.test.fixtures.turtle.gossip; import com.swirlds.common.platform.NodeId; -import com.swirlds.common.wiring.model.WiringModel; -import com.swirlds.common.wiring.wires.input.BindableInputWire; -import com.swirlds.common.wiring.wires.output.StandardOutputWire; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.wires.input.BindableInputWire; +import org.hiero.wiring.framework.wires.output.StandardOutputWire; import com.swirlds.platform.consensus.EventWindow; import com.swirlds.platform.event.PlatformEvent; import com.swirlds.platform.gossip.IntakeEventCounter; diff --git a/platform-sdk/swirlds-unit-tests/core/swirlds-platform-test/src/main/java/com/swirlds/platform/test/consensus/TestIntake.java b/platform-sdk/swirlds-unit-tests/core/swirlds-platform-test/src/main/java/com/swirlds/platform/test/consensus/TestIntake.java index 5a542e9e40c..6c08813e923 100644 --- a/platform-sdk/swirlds-unit-tests/core/swirlds-platform-test/src/main/java/com/swirlds/platform/test/consensus/TestIntake.java +++ b/platform-sdk/swirlds-unit-tests/core/swirlds-platform-test/src/main/java/com/swirlds/platform/test/consensus/TestIntake.java @@ -16,19 +16,19 @@ package com.swirlds.platform.test.consensus; -import static com.swirlds.common.wiring.wires.SolderType.INJECT; +import static org.hiero.wiring.framework.wires.SolderType.INJECT; import static com.swirlds.platform.consensus.SyntheticSnapshot.GENESIS_SNAPSHOT; import static com.swirlds.platform.event.AncientMode.GENERATION_THRESHOLD; import com.swirlds.base.time.Time; import com.swirlds.common.context.PlatformContext; import com.swirlds.common.platform.NodeId; -import com.swirlds.common.wiring.component.ComponentWiring; -import com.swirlds.common.wiring.model.WiringModel; -import com.swirlds.common.wiring.model.WiringModelBuilder; -import com.swirlds.common.wiring.schedulers.TaskScheduler; -import com.swirlds.common.wiring.schedulers.builders.TaskSchedulerType; -import com.swirlds.common.wiring.wires.output.OutputWire; +import org.hiero.wiring.framework.component.ComponentWiring; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.model.WiringModelBuilder; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.wires.output.OutputWire; import com.swirlds.platform.components.DefaultEventWindowManager; import com.swirlds.platform.components.EventWindowManager; import com.swirlds.platform.components.consensus.ConsensusEngine; diff --git a/platform-sdk/swirlds-unit-tests/core/swirlds-platform-test/src/test/java/com/swirlds/platform/test/event/preconsensus/PcesReplayerTests.java b/platform-sdk/swirlds-unit-tests/core/swirlds-platform-test/src/test/java/com/swirlds/platform/test/event/preconsensus/PcesReplayerTests.java index 2d8f8598e38..192898056ee 100644 --- a/platform-sdk/swirlds-unit-tests/core/swirlds-platform-test/src/test/java/com/swirlds/platform/test/event/preconsensus/PcesReplayerTests.java +++ b/platform-sdk/swirlds-unit-tests/core/swirlds-platform-test/src/test/java/com/swirlds/platform/test/event/preconsensus/PcesReplayerTests.java @@ -30,7 +30,7 @@ import com.swirlds.common.io.IOIterator; import com.swirlds.common.test.fixtures.Randotron; import com.swirlds.common.test.fixtures.platform.TestPlatformContextBuilder; -import com.swirlds.common.wiring.wires.output.StandardOutputWire; +import org.hiero.wiring.framework.wires.output.StandardOutputWire; import com.swirlds.config.extensions.test.fixtures.TestConfigBuilder; import com.swirlds.platform.event.PlatformEvent; import com.swirlds.platform.event.preconsensus.PcesConfig_; diff --git a/platform-sdk/swirlds-virtualmap/src/main/java/com/swirlds/virtualmap/internal/hash/VirtualHasher.java b/platform-sdk/swirlds-virtualmap/src/main/java/com/swirlds/virtualmap/internal/hash/VirtualHasher.java index a1ecf0aa3ae..bb865d09253 100644 --- a/platform-sdk/swirlds-virtualmap/src/main/java/com/swirlds/virtualmap/internal/hash/VirtualHasher.java +++ b/platform-sdk/swirlds-virtualmap/src/main/java/com/swirlds/virtualmap/internal/hash/VirtualHasher.java @@ -25,7 +25,7 @@ import com.swirlds.common.crypto.CryptographyHolder; import com.swirlds.common.crypto.Hash; import com.swirlds.common.crypto.HashBuilder; -import com.swirlds.common.wiring.tasks.AbstractTask; +import org.hiero.wiring.framework.tasks.AbstractTask; import com.swirlds.virtualmap.VirtualKey; import com.swirlds.virtualmap.VirtualMap; import com.swirlds.virtualmap.VirtualValue; From fd52bbc85fc0904b1f02665ed31641373aba21f2 Mon Sep 17 00:00:00 2001 From: mxtartaglia Date: Tue, 14 Jan 2025 20:00:37 -0300 Subject: [PATCH 4/6] chore: new module for wiring framework Signed-off-by: mxtartaglia --- .../blocks/impl/BlockStreamManagerImpl.java | 2 +- .../hedera-app/src/main/java/module-info.java | 17 + .../src/main/java/module-info.java | 31 +- .../hiero/wiring/framework/WiringConfig.java | 51 - .../framework/component/ComponentWiring.java | 780 -------- .../framework/component/InputWireLabel.java | 39 - .../framework/component/SchedulerLabel.java | 41 - .../component/internal/FilterToBind.java | 32 - .../component/internal/InputWireToBind.java | 48 - .../component/internal/TransformerToBind.java | 34 - .../internal/WiringComponentProxy.java | 67 - .../counters/BackpressureObjectCounter.java | 199 -- .../framework/counters/EmptyBlocker.java | 69 - .../counters/MultiObjectCounter.java | 109 - .../framework/counters/NoOpObjectCounter.java | 79 - .../framework/counters/ObjectCounter.java | 81 - .../counters/StandardObjectCounter.java | 101 - .../model/DeterministicWiringModel.java | 150 -- .../framework/model/StandardWiringModel.java | 256 --- .../framework/model/TraceableWiringModel.java | 334 ---- .../wiring/framework/model/WiringModel.java | 160 -- .../framework/model/WiringModelBuilder.java | 278 --- .../model/diagram/HyperlinkBuilder.java | 81 - .../model/diagram/ModelEdgeSubstitution.java | 31 - .../framework/model/diagram/ModelGroup.java | 40 - .../model/diagram/ModelManualLink.java | 29 - .../model/internal/analysis/CycleFinder.java | 138 -- .../analysis/DirectSchedulerChecks.java | 177 -- .../model/internal/analysis/GroupVertex.java | 171 -- .../internal/analysis/InputWireChecks.java | 68 - .../analysis/InputWireDescriptor.java | 30 - .../analysis/MermaidNameShortener.java | 51 - .../analysis/MermaidStyleManager.java | 83 - .../model/internal/analysis/ModelEdge.java | 196 -- .../model/internal/analysis/ModelVertex.java | 102 - .../analysis/ModelVertexMetaType.java | 37 - .../internal/analysis/StandardVertex.java | 267 --- .../internal/analysis/WiringFlowchart.java | 425 ---- .../DeterministicHeartbeatScheduler.java | 111 -- .../DeterministicTaskScheduler.java | 138 -- .../DeterministicTaskSchedulerBuilder.java | 106 - .../model/internal/monitor/HealthMonitor.java | 150 -- .../internal/monitor/HealthMonitorLogger.java | 98 - .../monitor/HealthMonitorMetrics.java | 71 - .../standard/AbstractHeartbeatScheduler.java | 118 -- .../internal/standard/HeartbeatScheduler.java | 68 - .../internal/standard/HeartbeatTask.java | 85 - .../model/internal/standard/JvmAnchor.java | 68 - .../framework/schedulers/TaskScheduler.java | 289 --- .../builders/TaskSchedulerBuilder.java | 196 -- .../builders/TaskSchedulerConfigOption.java | 46 - .../builders/TaskSchedulerConfiguration.java | 237 --- .../builders/TaskSchedulerType.java | 84 - .../AbstractTaskSchedulerBuilder.java | 355 ---- .../StandardTaskSchedulerBuilder.java | 184 -- .../schedulers/internal/ConcurrentTask.java | 74 - .../internal/ConcurrentTaskScheduler.java | 132 -- .../schedulers/internal/DefaultSquelcher.java | 57 - .../internal/DirectTaskScheduler.java | 150 -- .../internal/NoOpTaskScheduler.java | 138 -- .../schedulers/internal/SequentialTask.java | 105 - .../internal/SequentialTaskScheduler.java | 166 -- .../internal/SequentialThreadTask.java | 36 - .../SequentialThreadTaskScheduler.java | 204 -- .../schedulers/internal/Squelcher.java | 51 - .../internal/ThrowingSquelcher.java | 52 - .../wiring/framework/tasks/AbstractTask.java | 87 - .../transformers/AdvancedTransformation.java | 71 - .../framework/transformers/RoutableData.java | 28 - .../framework/transformers/WireFilter.java | 126 -- .../transformers/WireListSplitter.java | 85 - .../framework/transformers/WireRouter.java | 122 -- .../transformers/WireTransformer.java | 119 -- .../wiring/framework/wires/SolderType.java | 39 - .../framework/wires/input/Bindable.java | 48 - .../wires/input/BindableInputWire.java | 118 -- .../framework/wires/input/InputWire.java | 123 -- .../framework/wires/input/NoOpInputWire.java | 86 - .../wires/input/TaskSchedulerInput.java | 65 - .../wires/output/NoOpOutputWire.java | 124 -- .../framework/wires/output/OutputWire.java | 289 --- .../wires/output/StandardOutputWire.java | 79 - .../output/internal/ForwardingOutputWire.java | 50 - .../internal/TransformingOutputWire.java | 128 -- .../wiring/benchmark/WiringBenchmark.java | 134 -- .../benchmark/WiringBenchmarkEvent.java | 37 - .../benchmark/WiringBenchmarkEventPool.java | 41 - .../WiringBenchmarkEventVerifier.java | 41 - .../benchmark/WiringBenchmarkGossip.java | 63 - ...WiringBenchmarkTopologicalEventSorter.java | 51 - .../TaskSchedulerConfigurationTests.java | 155 -- .../component/ComponentWiringRouterTests.java | 311 --- .../component/ComponentWiringTests.java | 540 ----- .../WiringComponentPerformanceTests.java | 133 -- .../BackpressureObjectCounterTests.java | 291 --- .../counters/MultiObjectCounterTests.java | 186 -- .../counters/NoOpObjectCounterTests.java | 40 - .../counters/StandardObjectCounterTests.java | 107 - .../DeterministicHeartbeatSchedulerTests.java | 149 -- .../wiring/model/DeterministicModelTests.java | 573 ------ .../common/wiring/model/ModelTests.java | 1765 ----------------- .../internal/monitor/HealthMonitorTests.java | 237 --- .../schedulers/NoOpTaskSchedulerTests.java | 112 -- .../wiring/transformers/WireRouterTests.java | 97 - .../files/hashmap/HalfDiskHashMap.java | 4 +- .../src/main/java/module-info.java | 26 +- .../swirlds-platform-core/build.gradle.kts | 1 + .../platform/builder/PlatformBuilder.java | 6 +- .../builder/PlatformBuildingBlocks.java | 2 +- .../swirlds/platform/cli/DiagramCommand.java | 12 +- .../platform/cli/DiagramLegendCommand.java | 18 +- .../platform/components/AppNotifier.java | 4 +- .../components/EventWindowManager.java | 4 +- .../components/SavedStateController.java | 4 +- .../appcomm/LatestCompleteStateNotifier.java | 4 +- .../components/consensus/ConsensusEngine.java | 4 +- .../PlatformConfigurationExtension.java | 4 +- .../platform/event/FutureEventBuffer.java | 4 +- .../event/branching/BranchDetector.java | 4 +- .../event/branching/BranchReporter.java | 4 +- .../event/creation/EventCreationManager.java | 4 +- .../deduplication/EventDeduplicator.java | 4 +- .../platform/event/hashing/EventHasher.java | 4 +- .../platform/event/linking/InOrderLinker.java | 4 +- .../platform/event/orphan/OrphanBuffer.java | 4 +- .../event/preconsensus/InlinePcesWriter.java | 4 +- .../event/preconsensus/PcesReplayer.java | 4 +- .../event/preconsensus/PcesSequencer.java | 4 +- .../event/preconsensus/PcesWriter.java | 4 +- .../durability/RoundDurabilityBuffer.java | 4 +- .../resubmitter/TransactionResubmitter.java | 4 +- .../event/signing/SelfEventSigner.java | 4 +- .../stale/DefaultStaleEventDetector.java | 4 +- .../event/stale/StaleEventDetector.java | 6 +- .../event/stream/ConsensusEventStream.java | 4 +- .../validation/EventSignatureValidator.java | 4 +- .../validation/InternalEventValidator.java | 4 +- .../DefaultTransactionHandler.java | 2 +- .../eventhandling/TransactionHandler.java | 4 +- .../eventhandling/TransactionPrehandler.java | 4 +- .../swirlds/platform/gossip/SyncGossip.java | 6 +- .../platform/pool/TransactionPool.java | 4 +- .../platform/publisher/PlatformPublisher.java | 4 +- .../platform/state/hasher/StateHasher.java | 4 +- .../platform/state/hashlogger/HashLogger.java | 4 +- .../state/nexus/LatestCompleteStateNexus.java | 4 +- .../state/nexus/SignedStateNexus.java | 4 +- .../state/signed/StateSignatureCollector.java | 4 +- .../events/BirthRoundMigrationShim.java | 4 +- .../system/status/StatusStateMachine.java | 4 +- .../platform/wiring/PlatformCoordinator.java | 6 +- .../wiring/PlatformSchedulersConfig.java | 4 +- .../platform/wiring/PlatformWiring.java | 24 +- .../platform/wiring/SignedStateReserver.java | 4 +- .../wiring/StateAndRoundReserver.java | 4 +- .../wiring/StateAndRoundToStateReserver.java | 4 +- .../platform/wiring/components/Gossip.java | 8 +- .../wiring/components/GossipWiring.java | 14 +- .../wiring/components/PassThroughWiring.java | 8 +- .../wiring/components/PcesReplayerWiring.java | 10 +- .../RunningEventHashOverrideWiring.java | 4 +- .../src/main/java/module-info.java | 17 + .../components/EventWindowManagerTests.java | 8 +- .../event/stale/StaleEventDetectorTests.java | 4 +- .../stream/ConsensusEventStreamTest.java | 8 +- .../turtle/gossip/SimulatedGossipTests.java | 12 +- .../platform/turtle/runner/TurtleNode.java | 4 +- .../platform/wiring/PlatformWiringTests.java | 6 +- .../wiring/SignedStateReserverTest.java | 12 +- .../turtle/gossip/SimulatedGossip.java | 8 +- .../src/testFixtures/java/module-info.java | 19 +- .../platform/test/consensus/TestIntake.java | 16 +- .../src/main/java/module-info.java | 19 +- .../event/preconsensus/PcesReplayerTests.java | 4 +- .../internal/hash/VirtualHasher.java | 4 +- .../src/main/java/module-info.java | 19 +- .../wiring-framework/build.gradle.kts | 2 +- .../src/main/java/module-info.java | 12 + .../framework}/TestWiringModelBuilder.java | 2 +- .../ConcurrentTaskSchedulerTests.java | 15 +- .../schedulers/DefaultSquelcherTests.java | 4 +- .../schedulers/DirectTaskSchedulerTests.java | 15 +- .../schedulers/HeartbeatSchedulerTests.java | 11 +- .../SequentialTaskSchedulerTests.java | 25 +- .../schedulers/ThrowingSquelcherTests.java | 4 +- .../TaskSchedulerTransformersTests.java | 17 +- .../framework}/wires/OutputWireTests.java | 8 +- 187 files changed, 369 insertions(+), 15526 deletions(-) delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/WiringConfig.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/component/ComponentWiring.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/component/InputWireLabel.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/component/SchedulerLabel.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/component/internal/FilterToBind.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/component/internal/InputWireToBind.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/component/internal/TransformerToBind.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/component/internal/WiringComponentProxy.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/counters/BackpressureObjectCounter.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/counters/EmptyBlocker.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/counters/MultiObjectCounter.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/counters/NoOpObjectCounter.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/counters/ObjectCounter.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/counters/StandardObjectCounter.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/DeterministicWiringModel.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/StandardWiringModel.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/TraceableWiringModel.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/WiringModel.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/WiringModelBuilder.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/diagram/HyperlinkBuilder.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/diagram/ModelEdgeSubstitution.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/diagram/ModelGroup.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/diagram/ModelManualLink.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/CycleFinder.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/DirectSchedulerChecks.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/GroupVertex.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/InputWireChecks.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/InputWireDescriptor.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/MermaidNameShortener.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/MermaidStyleManager.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/ModelEdge.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/ModelVertex.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/ModelVertexMetaType.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/StandardVertex.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/WiringFlowchart.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/deterministic/DeterministicHeartbeatScheduler.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/deterministic/DeterministicTaskScheduler.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/deterministic/DeterministicTaskSchedulerBuilder.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/monitor/HealthMonitor.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/monitor/HealthMonitorLogger.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/monitor/HealthMonitorMetrics.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/standard/AbstractHeartbeatScheduler.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/standard/HeartbeatScheduler.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/standard/HeartbeatTask.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/standard/JvmAnchor.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/TaskScheduler.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/builders/TaskSchedulerBuilder.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/builders/TaskSchedulerConfigOption.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/builders/TaskSchedulerConfiguration.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/builders/TaskSchedulerType.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/builders/internal/AbstractTaskSchedulerBuilder.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/builders/internal/StandardTaskSchedulerBuilder.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/ConcurrentTask.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/ConcurrentTaskScheduler.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/DefaultSquelcher.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/DirectTaskScheduler.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/NoOpTaskScheduler.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/SequentialTask.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/SequentialTaskScheduler.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/SequentialThreadTask.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/SequentialThreadTaskScheduler.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/Squelcher.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/ThrowingSquelcher.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/tasks/AbstractTask.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/transformers/AdvancedTransformation.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/transformers/RoutableData.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/transformers/WireFilter.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/transformers/WireListSplitter.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/transformers/WireRouter.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/transformers/WireTransformer.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/SolderType.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/input/Bindable.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/input/BindableInputWire.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/input/InputWire.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/input/NoOpInputWire.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/input/TaskSchedulerInput.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/output/NoOpOutputWire.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/output/OutputWire.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/output/StandardOutputWire.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/output/internal/ForwardingOutputWire.java delete mode 100644 platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/output/internal/TransformingOutputWire.java delete mode 100644 platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/benchmark/WiringBenchmark.java delete mode 100644 platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/benchmark/WiringBenchmarkEvent.java delete mode 100644 platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/benchmark/WiringBenchmarkEventPool.java delete mode 100644 platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/benchmark/WiringBenchmarkEventVerifier.java delete mode 100644 platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/benchmark/WiringBenchmarkGossip.java delete mode 100644 platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/benchmark/WiringBenchmarkTopologicalEventSorter.java delete mode 100644 platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/builders/TaskSchedulerConfigurationTests.java delete mode 100644 platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/component/ComponentWiringRouterTests.java delete mode 100644 platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/component/ComponentWiringTests.java delete mode 100644 platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/component/WiringComponentPerformanceTests.java delete mode 100644 platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/counters/BackpressureObjectCounterTests.java delete mode 100644 platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/counters/MultiObjectCounterTests.java delete mode 100644 platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/counters/NoOpObjectCounterTests.java delete mode 100644 platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/counters/StandardObjectCounterTests.java delete mode 100644 platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/model/DeterministicHeartbeatSchedulerTests.java delete mode 100644 platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/model/DeterministicModelTests.java delete mode 100644 platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/model/ModelTests.java delete mode 100644 platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/model/internal/monitor/HealthMonitorTests.java delete mode 100644 platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/schedulers/NoOpTaskSchedulerTests.java delete mode 100644 platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/transformers/WireRouterTests.java rename platform-sdk/{swirlds-common/src/timingSensitive/java/com/swirlds/common => wiring-framework/src/test/java/org/hiero/wiring/framework}/TestWiringModelBuilder.java (97%) rename platform-sdk/{swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring => wiring-framework/src/test/java/org/hiero/wiring/framework}/schedulers/ConcurrentTaskSchedulerTests.java (97%) rename platform-sdk/{swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring => wiring-framework/src/test/java/org/hiero/wiring/framework}/schedulers/DefaultSquelcherTests.java (95%) rename platform-sdk/{swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring => wiring-framework/src/test/java/org/hiero/wiring/framework}/schedulers/DirectTaskSchedulerTests.java (97%) rename platform-sdk/{swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring => wiring-framework/src/test/java/org/hiero/wiring/framework}/schedulers/HeartbeatSchedulerTests.java (97%) rename platform-sdk/{swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring => wiring-framework/src/test/java/org/hiero/wiring/framework}/schedulers/SequentialTaskSchedulerTests.java (99%) rename platform-sdk/{swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring => wiring-framework/src/test/java/org/hiero/wiring/framework}/schedulers/ThrowingSquelcherTests.java (93%) rename platform-sdk/{swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring => wiring-framework/src/test/java/org/hiero/wiring/framework}/transformers/TaskSchedulerTransformersTests.java (99%) rename platform-sdk/{swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring => wiring-framework/src/test/java/org/hiero/wiring/framework}/wires/OutputWireTests.java (98%) diff --git a/hedera-node/hedera-app/src/main/java/com/hedera/node/app/blocks/impl/BlockStreamManagerImpl.java b/hedera-node/hedera-app/src/main/java/com/hedera/node/app/blocks/impl/BlockStreamManagerImpl.java index de298f679a9..cf6589232c4 100644 --- a/hedera-node/hedera-app/src/main/java/com/hedera/node/app/blocks/impl/BlockStreamManagerImpl.java +++ b/hedera-node/hedera-app/src/main/java/com/hedera/node/app/blocks/impl/BlockStreamManagerImpl.java @@ -58,7 +58,6 @@ import com.hedera.node.config.types.BlockStreamWriterMode; import com.hedera.node.config.types.DiskNetworkExport; import com.hedera.pbj.runtime.io.buffer.Bytes; -import org.hiero.wiring.framework.tasks.AbstractTask; import com.swirlds.config.api.Configuration; import com.swirlds.platform.state.service.PlatformStateService; import com.swirlds.platform.state.service.schemas.V0540PlatformStateSchema; @@ -90,6 +89,7 @@ import javax.inject.Singleton; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.hiero.wiring.framework.tasks.AbstractTask; @Singleton public class BlockStreamManagerImpl implements BlockStreamManager { diff --git a/hedera-node/hedera-app/src/main/java/module-info.java b/hedera-node/hedera-app/src/main/java/module-info.java index 8b618d827ca..fcadff6009e 100644 --- a/hedera-node/hedera-app/src/main/java/module-info.java +++ b/hedera-node/hedera-app/src/main/java/module-info.java @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2025 Hedera Hashgraph, LLC + * + * 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. + */ + import com.hedera.node.app.config.ServicesConfigExtension; import com.swirlds.config.api.ConfigurationExtension; @@ -42,6 +58,7 @@ requires com.swirlds.merkle; requires com.swirlds.merkledb; requires com.swirlds.virtualmap; + requires org.hiero.wiring.framework; requires com.google.common; requires com.google.protobuf; requires io.grpc.netty; diff --git a/platform-sdk/swirlds-common/src/main/java/module-info.java b/platform-sdk/swirlds-common/src/main/java/module-info.java index 7402d2a18a0..657c61167bc 100644 --- a/platform-sdk/swirlds-common/src/main/java/module-info.java +++ b/platform-sdk/swirlds-common/src/main/java/module-info.java @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2025 Hedera Hashgraph, LLC + * + * 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. + */ + module com.swirlds.common { /* Exported packages. This list should remain alphabetized. */ @@ -61,17 +77,6 @@ exports com.swirlds.common.utility.throttle; exports com.swirlds.common.jackson; exports com.swirlds.common.units; - exports com.swirlds.common.wiring; - exports org.hiero.wiring.framework.component; - exports org.hiero.wiring.framework.counters; - exports org.hiero.wiring.framework.model; - exports org.hiero.wiring.framework.schedulers; - exports org.hiero.wiring.framework.schedulers.builders; - exports org.hiero.wiring.framework.tasks; - exports org.hiero.wiring.framework.transformers; - exports org.hiero.wiring.framework.wires; - exports org.hiero.wiring.framework.wires.input; - exports org.hiero.wiring.framework.wires.output; /* Targeted exports */ exports com.swirlds.common.crypto.internal to @@ -140,11 +145,10 @@ com.swirlds.platform.gui; exports com.swirlds.common.startup; exports com.swirlds.common.threading.atomic; - exports org.hiero.wiring.framework.model.diagram; exports com.swirlds.common.concurrent; exports com.swirlds.common.merkle.synchronization.stats; - exports org.hiero.wiring.framework; + requires transitive com.hedera.pbj.runtime; requires transitive com.swirlds.base; requires transitive com.swirlds.config.api; requires transitive com.swirlds.logging; @@ -152,7 +156,6 @@ requires transitive com.swirlds.metrics.impl; requires transitive com.fasterxml.jackson.core; requires transitive com.fasterxml.jackson.databind; - requires transitive com.hedera.pbj.runtime; requires transitive io.prometheus.simpleclient; requires transitive lazysodium.java; requires transitive org.apache.logging.log4j; diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/WiringConfig.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/WiringConfig.java deleted file mode 100644 index dcef5e4ee04..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/WiringConfig.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework; - -import com.swirlds.config.api.ConfigData; -import com.swirlds.config.api.ConfigProperty; -import java.time.Duration; - -/** - * Configuration for the wiring framework. - * - * @param healthMonitorEnabled whether the health monitor is enabled - * @param hardBackpressureEnabled whether hard backpressure is enabled - * @param defaultPoolMultiplier used when calculating the size of the default platform fork join pool. Maximum - * parallelism in this pool is calculated as max(1, (defaultPoolMultiplier * - * [number of processors] + defaultPoolConstant)). - * @param defaultPoolConstant used when calculating the size of the default platform fork join pool. Maximum - * parallelism in this pool is calculated as max(1, (defaultPoolMultiplier * - * [number of processors] + defaultPoolConstant)). It is legal for this constant - * to be a negative number. - * @param healthMonitorSchedulerCapacity the unhandled task capacity of the health monitor's scheduler - * @param healthMonitorHeartbeatPeriod the period between heartbeats sent to the health monitor - * @param healthLogThreshold the amount of time a scheduler may be unhealthy before the platform is - * considered to be unhealthy and starts to write log warnings - * @param healthLogPeriod the minimum amount of time that must pass between health log messages for the - * same scheduler - */ -@ConfigData("platform.wiring") -public record WiringConfig( - @ConfigProperty(defaultValue = "true") boolean healthMonitorEnabled, - @ConfigProperty(defaultValue = "false") boolean hardBackpressureEnabled, - @ConfigProperty(defaultValue = "0") double defaultPoolMultiplier, - @ConfigProperty(defaultValue = "8") int defaultPoolConstant, - @ConfigProperty(defaultValue = "500") int healthMonitorSchedulerCapacity, - @ConfigProperty(defaultValue = "1ms") Duration healthMonitorHeartbeatPeriod, - @ConfigProperty(defaultValue = "1s") Duration healthLogThreshold, - @ConfigProperty(defaultValue = "10m") Duration healthLogPeriod) {} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/component/ComponentWiring.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/component/ComponentWiring.java deleted file mode 100644 index 49bee085300..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/component/ComponentWiring.java +++ /dev/null @@ -1,780 +0,0 @@ -/* - * Copyright (C) 2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.component; - -import static org.hiero.wiring.framework.model.diagram.HyperlinkBuilder.platformCoreHyperlink; - -import org.hiero.wiring.framework.component.internal.FilterToBind; -import org.hiero.wiring.framework.component.internal.InputWireToBind; -import org.hiero.wiring.framework.component.internal.TransformerToBind; -import org.hiero.wiring.framework.component.internal.WiringComponentProxy; -import org.hiero.wiring.framework.model.WiringModel; -import org.hiero.wiring.framework.schedulers.TaskScheduler; -import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerConfiguration; -import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; -import org.hiero.wiring.framework.transformers.RoutableData; -import org.hiero.wiring.framework.transformers.WireFilter; -import org.hiero.wiring.framework.transformers.WireRouter; -import org.hiero.wiring.framework.transformers.WireTransformer; -import org.hiero.wiring.framework.wires.input.BindableInputWire; -import org.hiero.wiring.framework.wires.input.InputWire; -import org.hiero.wiring.framework.wires.output.OutputWire; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.function.BiConsumer; -import java.util.function.BiFunction; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.function.Supplier; -import java.util.function.ToLongFunction; - -/** - * Builds and manages input/output wires for a component. - * - * @param the type of the component - * @param the output type of the component - */ -@SuppressWarnings("unchecked") -public class ComponentWiring { - - private final WiringModel model; - private final TaskScheduler scheduler; - - private final WiringComponentProxy proxy = new WiringComponentProxy(); - private final COMPONENT_TYPE proxyComponent; - - /** - * The component that implements the business logic. Will be null until {@link #bind(Object)} is called. - */ - private COMPONENT_TYPE component; - - /** - * Input wires that have been created for this component. - */ - private final Map> inputWires = new HashMap<>(); - - /** - * Input wires that need to be bound. - */ - private final List> inputsToBind = new ArrayList<>(); - - /** - * Previously created transformers/splitters/filters. - */ - private final Map> alternateOutputs = new HashMap<>(); - - /** - * Transformers that need to be bound. - */ - private final List> transformersToBind = new ArrayList<>(); - - /** - * Filters that need to be bound. - */ - private final List> filtersToBind = new ArrayList<>(); - - /** - * A splitter (if one has been constructed). - */ - private OutputWire splitterOutput; - - /** - * A router (if one has been constructed). - */ - private WireRouter router; - - /** - * A router that consumes the output of a splitter (if one has been constructed). - */ - private WireRouter splitRouter; - - /** - * Create a new component wiring. - * - * @param model the wiring model that will contain the component - * @param clazz the interface class of the component - * @param scheduler the task scheduler that will run the component - * @deprecated use {@link #ComponentWiring(WiringModel, Class, TaskSchedulerConfiguration)} instead. Once all uses - * have been updated, this constructor will be removed. - */ - @Deprecated - public ComponentWiring( - @NonNull final WiringModel model, - @NonNull final Class clazz, - @NonNull final TaskScheduler scheduler) { - - this.model = Objects.requireNonNull(model); - this.scheduler = Objects.requireNonNull(scheduler); - - if (!clazz.isInterface()) { - throw new IllegalArgumentException("Component class " + clazz.getName() + " is not an interface."); - } - - proxyComponent = (COMPONENT_TYPE) Proxy.newProxyInstance(clazz.getClassLoader(), new Class[] {clazz}, proxy); - } - - /** - * Create a new component wiring. - * - * @param model the wiring model that will contain the component - * @param clazz the interface class of the component - * @param schedulerConfiguration for the task scheduler that will run the component - */ - public ComponentWiring( - @NonNull final WiringModel model, - @NonNull final Class clazz, - @NonNull final TaskSchedulerConfiguration schedulerConfiguration) { - this(model, clazz, schedulerConfiguration, data -> 1); - } - - /** - * Create a new component wiring. - * - * @param model the wiring model that will contain the component - * @param clazz the interface class of the component - * @param schedulerConfiguration for the task scheduler that will run the component - * @param dataCounter the function to weight input data objects for health monitoring - */ - public ComponentWiring( - @NonNull final WiringModel model, - @NonNull final Class clazz, - @NonNull final TaskSchedulerConfiguration schedulerConfiguration, - @NonNull final ToLongFunction dataCounter) { - - this.model = Objects.requireNonNull(model); - Objects.requireNonNull(schedulerConfiguration); - - final String schedulerName; - final SchedulerLabel schedulerLabelAnnotation = clazz.getAnnotation(SchedulerLabel.class); - if (schedulerLabelAnnotation == null) { - schedulerName = clazz.getSimpleName(); - } else { - schedulerName = schedulerLabelAnnotation.value(); - } - - this.scheduler = model.schedulerBuilder(schedulerName) - .configure(schedulerConfiguration) - // FUTURE WORK: all components not currently in platform core should move there - .withHyperlink(platformCoreHyperlink(clazz)) - .withDataCounter(dataCounter) - .build() - .cast(); - - if (!clazz.isInterface()) { - throw new IllegalArgumentException("Component class " + clazz.getName() + " is not an interface."); - } - - proxyComponent = (COMPONENT_TYPE) Proxy.newProxyInstance(clazz.getClassLoader(), new Class[] {clazz}, proxy); - } - - /** - * Get the output wire of this component. - * - * @return the output wire - */ - @NonNull - public OutputWire getOutputWire() { - return scheduler.getOutputWire(); - } - - /** - * Get an input wire for this component. - * - * @param handler the component method that will handle the input, e.g. "MyComponent::handleInput". Should be a - * method on the class, not a method on a specific instance. - * @param the type of the input - * @return the input wire - */ - public InputWire getInputWire( - @NonNull final BiFunction handler) { - - Objects.requireNonNull(handler); - - try { - handler.apply(proxyComponent, null); - } catch (final NullPointerException e) { - throw new IllegalStateException( - "Component wiring does not support primitive input types or return types. Use a boxed primitive " - + "instead.", - e); - } - - return getOrBuildInputWire(proxy.getMostRecentlyInvokedMethod(), handler, null, null, null); - } - - /** - * Get an input wire for this component. - * - * @param handler the component method that will handle the input, e.g. "MyComponent::handleInput". Should be a - * method on the class, not a method on a specific instance. - * @param the input type - * @return the input wire - */ - public InputWire getInputWire( - @NonNull final BiConsumer handler) { - - Objects.requireNonNull(handler); - - try { - handler.accept(proxyComponent, null); - } catch (final NullPointerException e) { - throw new IllegalStateException( - "Component wiring does not support primitive input types. Use a boxed primitive instead.", e); - } - - return getOrBuildInputWire(proxy.getMostRecentlyInvokedMethod(), null, handler, null, null); - } - - /** - * Get an input wire for this component. - * - * @param handler the component method that will handle the input, e.g. "MyComponent::handleInput". Should be a - * method on the class, not a method on a specific instance. - * @param the input type - * @return the input wire - */ - @NonNull - public InputWire getInputWire( - @NonNull final Function handler) { - Objects.requireNonNull(handler); - - try { - handler.apply(proxyComponent); - } catch (final NullPointerException e) { - throw new IllegalStateException( - "Component wiring does not support primitive input types. Use a boxed primitive instead.", e); - } - - return getOrBuildInputWire(proxy.getMostRecentlyInvokedMethod(), null, null, handler, null); - } - - /** - * Get an input wire for this component. - * - * @param handler the component method that will handle the input, e.g. "MyComponent::handleInput". Should be a - * method on the class, not a method on a specific instance. - * @param the input type - * @return the input wire - */ - @NonNull - public InputWire getInputWire(@NonNull final Consumer handler) { - Objects.requireNonNull(handler); - - try { - handler.accept(proxyComponent); - } catch (final NullPointerException e) { - throw new IllegalStateException( - "Component wiring does not support primitive input types. Use a boxed primitive instead.", e); - } - - return getOrBuildInputWire(proxy.getMostRecentlyInvokedMethod(), null, null, null, handler); - } - - /** - * Get the output wire of this component, transformed by a function. - * - * @param transformation the function that will transform the output, must be a static method on the component - * @param the type of the transformed output - * @return the transformed output wire - */ - @NonNull - public OutputWire getTransformedOutput( - @NonNull final BiFunction transformation) { - - return getOrBuildTransformer(transformation, getOutputWire()); - } - - /** - * Get the output wire of a splitter of this component, transformed by a function. Automatically constructs the - * splitter if it does not already exist. Intended for use only with components that produce lists of items. - * - * @param transformation the function that will transform the output, must be a static method on the component - * @param the type of the elements in the list, the base type of this component's output is expected - * to be a list of this type - */ - public OutputWire getSplitAndTransformedOutput( - @NonNull final BiFunction transformation) { - return getOrBuildTransformer(transformation, getSplitOutput()); - } - - /** - * Create a filter for the output of this component. - * - * @param predicate the filter predicate - * @return the output wire of the filter - */ - @NonNull - public OutputWire getFilteredOutput( - @NonNull final BiFunction predicate) { - return getOrBuildFilter(predicate, getOutputWire()); - } - - /** - * Create a filter for the output of a splitter of this component. Automatically constructs the splitter if it does - * not already exist. Intended for use only with components that produce lists of items. - * - * @param predicate the filter predicate - * @param the type of the elements in the list, the base type of this component's output is expected to be - * a list of this type - * @return the output wire of the filter - */ - @NonNull - public OutputWire getSplitAndFilteredOutput( - @NonNull final BiFunction predicate) { - - return getOrBuildFilter(predicate, getSplitOutput()); - } - - /** - * Create a splitter for the output of this component. A splitter converts an output wire that produces lists of - * items into an output wire that produces individual items. Note that calling this method on a component that does - * not produce lists will result in a runtime exception. - * - * @param the type of the elements in the list, the base type of this component's output is expected to be - * a list of this type - * @return the output wire - */ - @NonNull - public OutputWire getSplitOutput() { - if (splitterOutput == null) { - - // Future work: there is not a clean way to specify the "splitterInputName" label, so as a short - // term work around we can just call it "data". This is ugly but ok as a temporary place holder. - // The proper way to fix this is to change the way we assign labels to wires in the diagram. - // Instead of defining names for input wires, we should instead define names for output wires, - // and require that any scheduler that has output define the label for its output data. - - splitterOutput = getOutputWire().buildSplitter(scheduler.getName() + "Splitter", "data"); - } - return (OutputWire) splitterOutput; - } - - /** - * Get an output wire that will emit a specific type of routed data. Data routing is when a component has multiple - * outputs, and different things want to receive a subset of that output. Each output is described by a routing - * address, which are implemented by enum values. - *

    - * This method should only be used for components which have an output type of - * {@link RoutableData RoutableData}. Calling this method more than once with - * different enum classes will throw. - * - * @param address an enum value that describes one of the different types of data that can be routed - * @param the enum that describes the different types of data handled by this router - * @param the type of data that travels over the output wire - * @return the output wire - */ - @NonNull - public , DATA_TYPE> OutputWire getRoutedOutput( - @NonNull final ROUTER_ENUM address) { - - final Class clazz = (Class) address.getClass(); - return getOrBuildRouter(clazz).getOutput(address); - } - - /** - * Get an output wire that will receive a specific type of routed data after being split apart. Data routing is when - * a component has multiple outputs, and different things want to receive a subset of that output. Each output is - * described by a routing address, which are implemented by enum values. - *

    - * This method should only be used for components which have an output type of - * {@link RoutableData List<RoutableData>}. Calling this method more - * than once with different enum classes will throw. - * - * @param address an enum value that describes one of the different types of data that can be routed - * @param the enum that describes the different types of data handled by this router - * @param the type of data that travels over the output wire - * @return the output wire - */ - @NonNull - public , DATA_TYPE> OutputWire getSplitAndRoutedOutput( - @NonNull final ROUTER_ENUM address) { - - final Class clazz = (Class) address.getClass(); - return getOrBuildSplitRouter(clazz).getOutput(address); - } - - /** - * Get the router for this component if one has been built. Build and return a new router if one has not been - * built. - * - * @param routerType the type of the router - * @param the type of the router - * @return the router - */ - @NonNull - private > WireRouter getOrBuildRouter( - @NonNull final Class routerType) { - - if (splitRouter != null) { - throw new IllegalStateException("Only one type of router can be constructed per task scheduler. " - + "This task scheduler already has a router that was built using the split output type, " - + "so a router cannot be created with the unmodified output type."); - } - - if (router != null) { - if (!router.getRouterType().equals(routerType)) { - throw new IllegalArgumentException("Only one type of router can be constructed per task scheduler. " - + "This task scheduler already has a router of type " - + router.getRouterType().getName() + "but an attempt was made to construct a router of type " - + routerType.getName()); - } - } else { - router = new WireRouter<>(model, getSchedulerName() + "Router", "data", routerType); - getOutputWire().solderTo((InputWire) router.getInput()); - } - - return (WireRouter) router; - } - - /** - * Get the router for split data for this component if one has been built. Build and return a new splitter and - * router if one has not been built. - * - * @param routerType the type of the router - * @param the type of the router - * @return the router - */ - @NonNull - private > WireRouter getOrBuildSplitRouter( - @NonNull final Class routerType) { - - if (router != null) { - throw new IllegalStateException("Only one type of router can be constructed per task scheduler. " - + "This task scheduler already has a router that was built using the unmodified output type, " - + "so a router cannot be created with the split output type."); - } - - if (splitRouter != null) { - if (!splitRouter.getRouterType().equals(routerType)) { - throw new IllegalArgumentException("Only one type of router can be constructed per task scheduler. " - + "This task scheduler already has a router of type " - + router.getRouterType().getName() + "but an attempt was made to construct a router of type " - + routerType.getName()); - } - } else { - splitRouter = new WireRouter<>(model, getSchedulerName() + "Router", "data", routerType); - final OutputWire> splitOutput = getSplitOutput(); - final InputWire> routerInput = ((WireRouter) splitRouter).getInput(); - splitOutput.solderTo(routerInput); - } - - return (WireRouter) splitRouter; - } - - /** - * Create a transformed output wire or return the existing one if it has already been created. - * - * @param transformation the function that will transform the output, must be a static method on the component - * @param transformerSource the source of the data to transform (i.e. the base output wire or the output wire of - * the splitter) - * @param the type of the elements passed to the transformer - * @param the type of the transformed output - * @return the transformed output wire - */ - @NonNull - private OutputWire getOrBuildTransformer( - @NonNull final BiFunction transformation, - @NonNull final OutputWire transformerSource) { - - Objects.requireNonNull(transformation); - try { - transformation.apply(proxyComponent, null); - } catch (final NullPointerException e) { - throw new IllegalStateException( - "Component wiring does not support primitive input types or return types. " - + "Use a boxed primitive instead.", - e); - } - - final Method method = proxy.getMostRecentlyInvokedMethod(); - if (!method.isDefault()) { - throw new IllegalArgumentException("Method " + method.getName() + " does not have a default."); - } - - if (alternateOutputs.containsKey(method)) { - // We've already created this transformer. - return (OutputWire) alternateOutputs.get(method); - } - - final String wireLabel; - final InputWireLabel inputWireLabel = method.getAnnotation(InputWireLabel.class); - if (inputWireLabel == null) { - wireLabel = "data to transform"; - } else { - wireLabel = inputWireLabel.value(); - } - - final String schedulerLabel; - final SchedulerLabel schedulerLabelAnnotation = method.getAnnotation(SchedulerLabel.class); - if (schedulerLabelAnnotation == null) { - schedulerLabel = method.getName(); - } else { - schedulerLabel = schedulerLabelAnnotation.value(); - } - - final WireTransformer transformer = - new WireTransformer<>(model, schedulerLabel, wireLabel); - transformerSource.solderTo(transformer.getInputWire()); - alternateOutputs.put(method, transformer.getOutputWire()); - - if (component == null) { - // we will bind this later - transformersToBind.add((TransformerToBind) - new TransformerToBind<>(transformer, transformation)); - } else { - // bind this now - transformer.bind(x -> transformation.apply(component, x)); - } - - return transformer.getOutputWire(); - } - - /** - * Create a filtered output wire or return the existing one if it has already been created. - * - * @param predicate the filter predicate - * @param filterSource the source of the data to filter (i.e. the base output wire or the output wire of the - * splitter) - * @param the type of the elements passed to the filter - * @return the output wire of the filter - */ - private OutputWire getOrBuildFilter( - @NonNull final BiFunction predicate, - @NonNull final OutputWire filterSource) { - - Objects.requireNonNull(predicate); - try { - predicate.apply(proxyComponent, null); - } catch (final NullPointerException e) { - throw new IllegalStateException( - "Component wiring does not support primitive input types or return types. " - + "Use a boxed primitive instead.", - e); - } - - final Method method = proxy.getMostRecentlyInvokedMethod(); - if (!method.isDefault()) { - throw new IllegalArgumentException("Method " + method.getName() + " does not have a default."); - } - - if (alternateOutputs.containsKey(method)) { - // We've already created this filter. - return (OutputWire) alternateOutputs.get(method); - } - - final String wireLabel; - final InputWireLabel inputWireLabel = method.getAnnotation(InputWireLabel.class); - if (inputWireLabel == null) { - wireLabel = "data to filter"; - } else { - wireLabel = inputWireLabel.value(); - } - - final String schedulerLabel; - final SchedulerLabel schedulerLabelAnnotation = method.getAnnotation(SchedulerLabel.class); - if (schedulerLabelAnnotation == null) { - schedulerLabel = method.getName(); - } else { - schedulerLabel = schedulerLabelAnnotation.value(); - } - - final WireFilter filter = new WireFilter<>(model, schedulerLabel, wireLabel); - filterSource.solderTo(filter.getInputWire()); - alternateOutputs.put(method, filter.getOutputWire()); - - if (component == null) { - // we will bind this later - filtersToBind.add((FilterToBind) new FilterToBind<>(filter, predicate)); - } else { - // bind this now - filter.bind(x -> predicate.apply(component, x)); - } - - return filter.getOutputWire(); - } - - /** - * Get the input wire for a specified method. - * - * @param method the method that will handle data on the input wire - * @param handlerWithReturn the handler for the method if it has a return type - * @param handlerWithoutReturn the handler for the method if it does not have a return type - * @param handlerWithoutParameter the handler for the method if it does not have a parameter - * @param handlerWithoutReturnAndWithoutParameter the handler for the method if it does not have a return type and - * does not have a parameter - * @param the input type - * @return the input wire - */ - private InputWire getOrBuildInputWire( - @NonNull final Method method, - @Nullable final BiFunction handlerWithReturn, - @Nullable final BiConsumer handlerWithoutReturn, - @Nullable final Function handlerWithoutParameter, - @Nullable final Consumer handlerWithoutReturnAndWithoutParameter) { - - if (inputWires.containsKey(method)) { - // We've already created this wire - return (InputWire) inputWires.get(method); - } - - final String label; - final InputWireLabel inputWireLabel = method.getAnnotation(InputWireLabel.class); - if (inputWireLabel == null) { - label = method.getName(); - } else { - label = inputWireLabel.value(); - } - - final BindableInputWire inputWire = scheduler.buildInputWire(label); - inputWires.put(method, (BindableInputWire) inputWire); - - if (component == null) { - // we will bind this later - inputsToBind.add((InputWireToBind) new InputWireToBind<>( - inputWire, - handlerWithReturn, - handlerWithoutReturn, - handlerWithoutParameter, - handlerWithoutReturnAndWithoutParameter)); - } else { - // bind this now - if (handlerWithReturn != null) { - inputWire.bind(x -> handlerWithReturn.apply(component, x)); - } else if (handlerWithoutReturn != null) { - inputWire.bindConsumer(x -> { - handlerWithoutReturn.accept(component, x); - }); - } else if (handlerWithoutParameter != null) { - inputWire.bind(x -> handlerWithoutParameter.apply(component)); - } else { - assert handlerWithoutReturnAndWithoutParameter != null; - inputWire.bindConsumer(x -> { - handlerWithoutReturnAndWithoutParameter.accept(component); - }); - } - } - - return inputWire; - } - - /** - * Flush all data in the task scheduler. Blocks until all data currently in flight has been processed. - * - * @throws UnsupportedOperationException if the scheduler does not support flushing - */ - public void flush() { - scheduler.flush(); - } - - /** - * Start squelching the output of this component. - * - * @throws UnsupportedOperationException if the scheduler does not support squelching - * @throws IllegalStateException if the scheduler is already squelching - */ - public void startSquelching() { - scheduler.startSquelching(); - } - - /** - * Stop squelching the output of this component. - * - * @throws UnsupportedOperationException if the scheduler does not support squelching - * @throws IllegalStateException if the scheduler is not squelching - */ - public void stopSquelching() { - scheduler.stopSquelching(); - } - - /** - * Bind the component to the input wires. - * - * @param component the component to bind - */ - public void bind(@NonNull final COMPONENT_TYPE component) { - Objects.requireNonNull(component); - - this.component = component; - - // Bind input wires - for (final InputWireToBind wireToBind : inputsToBind) { - if (wireToBind.handlerWithReturn() != null) { - final BiFunction handlerWithReturn = - (BiFunction) wireToBind.handlerWithReturn(); - wireToBind.inputWire().bind(x -> handlerWithReturn.apply(component, x)); - } else if (wireToBind.handlerWithoutReturn() != null) { - final BiConsumer handlerWithoutReturn = - (BiConsumer) wireToBind.handlerWithoutReturn(); - wireToBind.inputWire().bindConsumer(x -> { - handlerWithoutReturn.accept(component, x); - }); - } else if (wireToBind.handlerWithoutParameter() != null) { - wireToBind - .inputWire() - .bind(x -> wireToBind.handlerWithoutParameter().apply(component)); - } else { - assert wireToBind.handlerWithoutReturnAndWithoutParameter() != null; - wireToBind.inputWire().bindConsumer(x -> { - wireToBind.handlerWithoutReturnAndWithoutParameter().accept(component); - }); - } - } - - // Bind transformers - for (final TransformerToBind transformerToBind : transformersToBind) { - final WireTransformer transformer = transformerToBind.transformer(); - final BiFunction transformation = transformerToBind.transformation(); - transformer.bind(x -> transformation.apply(component, x)); - } - - // Bind filters - for (final FilterToBind filterToBind : filtersToBind) { - filterToBind.filter().bind(x -> filterToBind.predicate().apply(component, x)); - } - } - - /** - * Bind to a component. This method is similar to {@link #bind(Object)}, but it allows the component to be created - * if and only if we need to bind to it. This method will invoke the supplier if the task scheduler type is anything - * other than a {@link TaskSchedulerType#NO_OP NO_OP} scheduler. - * - * @param componentBuilder builds or supplies the component - */ - public void bind(@NonNull final Supplier componentBuilder) { - Objects.requireNonNull(componentBuilder); - if (scheduler.getType() != TaskSchedulerType.NO_OP) { - bind(componentBuilder.get()); - } - } - - /** - * Get the name of the scheduler that is running this component. - * - * @return the name of the scheduler - */ - @NonNull - public String getSchedulerName() { - return scheduler.getName(); - } -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/component/InputWireLabel.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/component/InputWireLabel.java deleted file mode 100644 index 12b15ef7db2..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/component/InputWireLabel.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.component; - -import edu.umd.cs.findbugs.annotations.NonNull; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Label the input wire that a method is associated with. - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.METHOD) -public @interface InputWireLabel { - - /** - * The label of the input wire. - * - * @return the label of the input wire - */ - @NonNull - String value(); -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/component/SchedulerLabel.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/component/SchedulerLabel.java deleted file mode 100644 index b8ddbf959fa..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/component/SchedulerLabel.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.component; - -import edu.umd.cs.findbugs.annotations.NonNull; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Annotates a name that should be used as an override for the task scheduler's name instead of a component's interface - * name. Can also be used to annotate a method parameter used to implement a transformer/filter (these get turned into - * direct schedulers, which need to be named). - */ -@Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.TYPE, ElementType.METHOD}) -public @interface SchedulerLabel { - - /** - * The label of the task scheduler that will operate the transformer/filter. - * - * @return the label of the task scheduler that will operate the transformer/filter - */ - @NonNull - String value(); -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/component/internal/FilterToBind.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/component/internal/FilterToBind.java deleted file mode 100644 index 81f10eb1c43..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/component/internal/FilterToBind.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.component.internal; - -import org.hiero.wiring.framework.transformers.WireFilter; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.function.BiFunction; - -/** - * A filter and the predicate to bind. - * - * @param filter the filter we eventually want to bind - * @param predicate the predicate method - * @param the type of the component - * @param the input type - */ -public record FilterToBind( - @NonNull WireFilter filter, @NonNull BiFunction predicate) {} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/component/internal/InputWireToBind.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/component/internal/InputWireToBind.java deleted file mode 100644 index c7adb681e5a..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/component/internal/InputWireToBind.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.component.internal; - -import org.hiero.wiring.framework.wires.input.BindableInputWire; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import java.util.function.BiConsumer; -import java.util.function.BiFunction; -import java.util.function.Consumer; -import java.util.function.Function; - -/** - * Contains information necessary to bind an input wire when we eventually get the implementation of the component. - * - * @param inputWire the input wire to bind - * @param handlerWithReturn null if initially bound. If not initially bound, will be non-null - * if the method has a non-void return type - * @param handlerWithoutReturn null if initially bound. If not initially bound, will be non-null - * if the method has a void return type - * @param handlerWithoutParameter null if initially bound. If not initially bound, will be non-null - * if the method has no parameters - * @param handlerWithoutReturnAndWithoutParameter null if initially bound. If not initially bound, will be non-null if - * the method has no parameters and a void return type - * @param the type of the component - * @param the input type of the input wire - * @param the output type of the component - */ -public record InputWireToBind( - @NonNull BindableInputWire inputWire, - @Nullable BiFunction handlerWithReturn, - @Nullable BiConsumer handlerWithoutReturn, - @Nullable Function handlerWithoutParameter, - @Nullable Consumer handlerWithoutReturnAndWithoutParameter) {} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/component/internal/TransformerToBind.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/component/internal/TransformerToBind.java deleted file mode 100644 index 90637b6a63e..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/component/internal/TransformerToBind.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.component.internal; - -import org.hiero.wiring.framework.transformers.WireTransformer; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.function.BiFunction; - -/** - * A transformer and the transformation to bind to a component. - * - * @param transformer the transformer we eventually want to bind - * @param transformation the transformation method - * @param the type of the component - * @param the input type of the transformer (equal to the output type of the base output wire) - * @param the output type of the transformer - */ -public record TransformerToBind( - @NonNull WireTransformer transformer, - @NonNull BiFunction transformation) {} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/component/internal/WiringComponentProxy.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/component/internal/WiringComponentProxy.java deleted file mode 100644 index 0724818e4e4..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/component/internal/WiringComponentProxy.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.component.internal; - -import edu.umd.cs.findbugs.annotations.NonNull; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Method; -import java.util.Objects; -import org.hiero.wiring.framework.component.ComponentWiring; - -/** - * This dynamic proxy is used by the {@link ComponentWiring} to capture the most - * recently invoked method. - */ -public class WiringComponentProxy implements InvocationHandler { - - private Method mostRecentlyInvokedMethod = null; - - /** - * {@inheritDoc} - */ - @Override - public Object invoke(@NonNull final Object proxy, @NonNull final Method method, @NonNull final Object[] args) - throws Throwable { - - if (method.getName().equals("toString")) { - // Handle this specially, the debugger likes to call toString() - // on the proxy which disrupts normal behavior when debugging. - return "WiringComponentProxy"; - } - - mostRecentlyInvokedMethod = Objects.requireNonNull(method); - return null; - } - - /** - * Get the most recently invoked method. Calling this method resets the most recently invoked method to null - * as a safety measure. - * - * @return the most recently invoked method - */ - @NonNull - public Method getMostRecentlyInvokedMethod() { - if (mostRecentlyInvokedMethod == null) { - throw new IllegalArgumentException("Provided lambda is not a method on the component interface."); - } - try { - return mostRecentlyInvokedMethod; - } finally { - mostRecentlyInvokedMethod = null; - } - } -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/counters/BackpressureObjectCounter.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/counters/BackpressureObjectCounter.java deleted file mode 100644 index 59b61f64f95..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/counters/BackpressureObjectCounter.java +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.counters; - -import static java.util.concurrent.TimeUnit.NANOSECONDS; - -import edu.umd.cs.findbugs.annotations.NonNull; -import java.time.Duration; -import java.util.Objects; -import java.util.concurrent.ForkJoinPool; -import java.util.concurrent.ForkJoinPool.ManagedBlocker; -import java.util.concurrent.RejectedExecutionException; -import java.util.concurrent.atomic.AtomicLong; - -/** - * A utility for counting the number of objects in various parts of the pipeline. Will apply backpressure if the number - * of objects exceeds a specified capacity. - *

    - * In order to achieve higher performance in high contention environments, this class allows the count returned by - * {@link #getCount()} to temporarily exceed the capacity even if {@link #forceOnRamp()} is not used. This doesn't allow - * objects to be on-ramped in excess of the capacity, but it may add some slight fuzziness to the count. - */ -public class BackpressureObjectCounter extends ObjectCounter { - - private final String name; - private final AtomicLong count = new AtomicLong(0); - private final long capacity; - - /** - * The amount of time to sleep while waiting for capacity to become available, or 0 to not sleep. - */ - private final long sleepNanos; - - /** - * When waiting for the count to reach zero, this object is used to efficiently sleep on the fork join pool. - */ - private final ManagedBlocker waitUntilEmptyBlocker; - - /** - * Constructor. - * - * @param name the name of the object counter, used creating more informative exceptions - * @param capacity the maximum number of objects that can be in the part of the system that this object is - * being used to monitor before backpressure is applied - * @param sleepDuration when a method needs to block, the duration to sleep while blocking - */ - public BackpressureObjectCounter( - @NonNull final String name, final long capacity, @NonNull final Duration sleepDuration) { - if (capacity <= 0) { - throw new IllegalArgumentException("Capacity must be greater than zero"); - } - - this.name = Objects.requireNonNull(name); - this.capacity = capacity; - this.sleepNanos = sleepDuration.toNanos(); - - waitUntilEmptyBlocker = new EmptyBlocker(count, sleepNanos); - } - - /** - * {@inheritDoc} - */ - @Override - public void onRamp(final long delta) { - if (attemptOnRamp(delta)) { - return; - } - - // Slow case. Capacity wasn't reserved, so we need to block. - - while (true) { - try { - // This will block until capacity is available and the count has been incremented. - // - // This is logically equivalent to the following pseudocode. - // Note that the managed block is thread safe when onRamp() is being called from multiple threads, - // even though this pseudocode is not. - // - // while (count >= capacity) { - // Thread.sleep(sleepNanos); - // } - // count++; - // - // The reason why we use the managedBlock() strategy instead of something simpler has to do with - // the fork join pool paradigm. Unlike traditional thread pools where we have more threads than - // CPUs, blocking (e.g. Thread.sleep()) on a fork join pool may monopolize an entire CPU core. - // The managedBlock() pattern allows us to block while yielding the physical CPU core to other - // tasks. - ForkJoinPool.managedBlock(new ManagedBlocker() { - - @Override - public boolean block() throws InterruptedException { - if (sleepNanos > 0) { - try { - NANOSECONDS.sleep(sleepNanos); - } catch (final InterruptedException e) { - // Don't throw an interrupted exception, but allow the thread to maintain its - // interrupted status. - Thread.currentThread().interrupt(); - } - } - - // Although we could technically check the count here and stop the back pressure if the count is - // below the threshold, it's simpler not to. Immediately after this method is called, - // isReleasable() will be called, which will do the checking for us. Easier to just let that - // method do the work, and have this method only be responsible for sleeping. - return false; - } - - @Override - public boolean isReleasable() { - return attemptOnRamp(delta); - } - }); - return; - } catch (final InterruptedException ex) { - // This should be impossible. - Thread.currentThread().interrupt(); - throw new IllegalStateException("Interrupted while blocking on an onRamp() for " + name); - } catch (final RejectedExecutionException ex) { - // We've exhausted our supply of background threads, we have no choice but to busy wait. - Thread.onSpinWait(); - } - } - } - - /** - * {@inheritDoc} - */ - @Override - public boolean attemptOnRamp(final long delta) { - final long resultingCount = count.addAndGet(delta); - if (resultingCount <= capacity) { - // We didn't violate capacity by incrementing the count, so we're done. - return true; - } else { - // We may have violated capacity restrictions by incrementing the count. - // Decrement count and return failure. - count.addAndGet(-delta); - return false; - } - } - - /** - * {@inheritDoc} - */ - @Override - public void forceOnRamp(final long delta) { - count.addAndGet(delta); - } - - /** - * {@inheritDoc} - */ - @Override - public void offRamp(final long delta) { - count.addAndGet(-delta); - } - - /** - * {@inheritDoc} - */ - @Override - public long getCount() { - return count.get(); - } - - /** - * {@inheritDoc} - */ - @Override - public void waitUntilEmpty() { - if (count.get() == 0) { - return; - } - - try { - ForkJoinPool.managedBlock(waitUntilEmptyBlocker); - } catch (final InterruptedException e) { - // This should be impossible. - Thread.currentThread().interrupt(); - throw new IllegalStateException("Interrupted while blocking on an waitUntilEmpty() for " + name); - } - } -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/counters/EmptyBlocker.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/counters/EmptyBlocker.java deleted file mode 100644 index e159f3e7591..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/counters/EmptyBlocker.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.counters; - -import static java.util.concurrent.TimeUnit.NANOSECONDS; - -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.Objects; -import java.util.concurrent.ForkJoinPool.ManagedBlocker; -import java.util.concurrent.atomic.AtomicLong; - -/** - * This class is used to implement flushing in a {@link java.util.concurrent.ForkJoinPool} friendly way. Blocks until - * the count reaches zero. - */ -class EmptyBlocker implements ManagedBlocker { - - private final AtomicLong count; - private final long sleepNanos; - - /** - * Constructor. - * - * @param count the counter to use - * @param sleepNanos the number of nanoseconds to sleep while blocking, or 0 to not sleep - */ - public EmptyBlocker(@NonNull final AtomicLong count, final long sleepNanos) { - this.count = Objects.requireNonNull(count); - this.sleepNanos = sleepNanos; - } - - /** - * {@inheritDoc} - */ - @Override - public boolean block() throws InterruptedException { - if (sleepNanos > 0) { - try { - NANOSECONDS.sleep(sleepNanos); - } catch (final InterruptedException e) { - // Don't throw an interrupted exception, but allow the thread to maintain its interrupted status. - Thread.currentThread().interrupt(); - } - } - return false; - } - - /** - * {@inheritDoc} - */ - @Override - public boolean isReleasable() { - return count.get() == 0; - } -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/counters/MultiObjectCounter.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/counters/MultiObjectCounter.java deleted file mode 100644 index a1690a527d3..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/counters/MultiObjectCounter.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.counters; - -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.Objects; - -/** - * This object counter combines multiple counters into a single counter. Every time a method on this object is called, - * the same method is also called on all child counters. - */ -public class MultiObjectCounter extends ObjectCounter { - - private final ObjectCounter[] counters; - - /** - * Constructor. - * - * @param counters one or more counters. The first counter in the array is the primary counter. {@link #getCount()} - * always return the count of the primary counter. When {@link #attemptOnRamp()} is called, - * on-ramping is attempted in the primary counter. If that fails, no other counter is on-ramped. If - * that succeeds then on-ramping is forced in all other counters. - */ - public MultiObjectCounter(@NonNull final ObjectCounter... counters) { - this.counters = Objects.requireNonNull(counters); - if (counters.length == 0) { - throw new IllegalArgumentException("Must have at least one counter"); - } - } - - /** - * {@inheritDoc} - */ - @Override - public void onRamp(final long delta) { - for (final ObjectCounter counter : counters) { - counter.onRamp(delta); - } - } - - /** - * {@inheritDoc} - */ - @Override - public boolean attemptOnRamp(final long delta) { - final boolean success = counters[0].attemptOnRamp(delta); - if (!success) { - return false; - } - - for (int i = 1; i < counters.length; i++) { - counters[i].forceOnRamp(delta); - } - - return true; - } - - /** - * {@inheritDoc} - */ - @Override - public void forceOnRamp(final long delta) { - for (final ObjectCounter counter : counters) { - counter.forceOnRamp(delta); - } - } - - /** - * {@inheritDoc} - */ - @Override - public void offRamp(final long delta) { - for (final ObjectCounter counter : counters) { - counter.offRamp(delta); - } - } - - /** - * {@inheritDoc} - */ - @Override - public long getCount() { - return counters[0].getCount(); - } - - /** - * {@inheritDoc} - */ - @Override - public void waitUntilEmpty() { - for (final ObjectCounter counter : counters) { - counter.waitUntilEmpty(); - } - } -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/counters/NoOpObjectCounter.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/counters/NoOpObjectCounter.java deleted file mode 100644 index a55b93c7c52..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/counters/NoOpObjectCounter.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.counters; - -/** - * A counter that doesn't actually count. Saves us from having to do a (counter == null) check in the standard case. - */ -public class NoOpObjectCounter extends ObjectCounter { - - private static final NoOpObjectCounter INSTANCE = new NoOpObjectCounter(); - - /** - * Get the singleton instance. - * - * @return the singleton instance - */ - public static NoOpObjectCounter getInstance() { - return INSTANCE; - } - - /** - * Constructor. - */ - private NoOpObjectCounter() {} - - /** - * {@inheritDoc} - */ - @Override - public void onRamp(final long delta) {} - - /** - * {@inheritDoc} - */ - @Override - public boolean attemptOnRamp(final long delta) { - return true; - } - - /** - * {@inheritDoc} - */ - @Override - public void forceOnRamp(final long delta) {} - - /** - * {@inheritDoc} - */ - @Override - public void offRamp(final long delta) {} - - /** - * {@inheritDoc} - */ - @Override - public long getCount() { - return COUNT_UNDEFINED; - } - - /** - * {@inheritDoc} - */ - @Override - public void waitUntilEmpty() {} -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/counters/ObjectCounter.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/counters/ObjectCounter.java deleted file mode 100644 index 5ee15e66dd9..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/counters/ObjectCounter.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.counters; - -/** - * A class that counts the number of objects in various parts of the pipeline. - */ -public abstract class ObjectCounter { - - /** - * The value returned by {@link #getCount()} if this object counter does not support counting. - */ - public static final long COUNT_UNDEFINED = -1L; - - /** - * Signal that an object is entering the part of the system that this object is being used to monitor. - */ - public abstract void onRamp(long delta); - - public final void onRamp() { - onRamp(1L); - } - - /** - * Signal that an object is entering the part of the system that this object is being used to monitor. Object is not - * "on ramped" if it is not immediately possible to do so without violating capacity constraints. - * - * @return true if there was available capacity to on ramp the object, false otherwise - */ - public abstract boolean attemptOnRamp(long delta); - - public final boolean attemptOnRamp() { - return attemptOnRamp(1L); - } - - /** - * Signal that an object is entering the part of the system that this object is being used to monitor. If there is - * not enough capacity to on ramp the object, on ramp it anyway and ignore all capacity restrictions. - */ - public abstract void forceOnRamp(long delta); - - public final void forceOnRamp() { - forceOnRamp(1L); - } - - /** - * Signal that an object is leaving the part of the system that this object is being used to monitor. - */ - public abstract void offRamp(long delta); - - public final void offRamp() { - offRamp(1L); - } - - /** - * Get the number of objects in the part of the system that this object is being used to monitor. If this object - * counter does not support counting, then {@link #COUNT_UNDEFINED} is returned. - */ - public abstract long getCount(); - - /** - * Blocks until the number of objects off-ramped is equal to the number of objects on-ramped. Does not prevent new - * objects from being on-ramped. If new objects are continuously on-ramped, it is possible that this method may - * block indefinitely. - */ - public abstract void waitUntilEmpty(); -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/counters/StandardObjectCounter.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/counters/StandardObjectCounter.java deleted file mode 100644 index 8fae4360909..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/counters/StandardObjectCounter.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.counters; - -import edu.umd.cs.findbugs.annotations.NonNull; -import java.time.Duration; -import java.util.concurrent.ForkJoinPool; -import java.util.concurrent.ForkJoinPool.ManagedBlocker; -import java.util.concurrent.atomic.AtomicLong; - -/** - * A utility for counting the number of objects in various parts of the pipeline. - */ -public class StandardObjectCounter extends ObjectCounter { - - private final AtomicLong count = new AtomicLong(0); - private final ManagedBlocker waitUntilEmptyBlocker; - - /** - * Constructor. - * - * @param sleepDuration when a method needs to block, the duration to sleep while blocking - */ - public StandardObjectCounter(@NonNull final Duration sleepDuration) { - final long sleepNanos = sleepDuration.toNanos(); - waitUntilEmptyBlocker = new EmptyBlocker(count, sleepNanos); - } - - /** - * {@inheritDoc} - */ - @Override - public void onRamp(final long delta) { - count.addAndGet(delta); - } - - /** - * {@inheritDoc} - */ - @Override - public boolean attemptOnRamp(final long delta) { - count.getAndAdd(delta); - return true; - } - - /** - * {@inheritDoc} - */ - @Override - public void forceOnRamp(final long delta) { - count.getAndAdd(delta); - } - - /** - * {@inheritDoc} - */ - @Override - public void offRamp(final long delta) { - count.addAndGet(-delta); - } - - /** - * {@inheritDoc} - */ - @Override - public long getCount() { - return count.get(); - } - - /** - * {@inheritDoc} - */ - @Override - public void waitUntilEmpty() { - if (count.get() == 0) { - return; - } - - try { - ForkJoinPool.managedBlock(waitUntilEmptyBlocker); - } catch (final InterruptedException e) { - // This should be impossible. - Thread.currentThread().interrupt(); - throw new IllegalStateException("Interrupted while blocking on an waitUntilEmpty()"); - } - } -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/DeterministicWiringModel.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/DeterministicWiringModel.java deleted file mode 100644 index d3a63e0df28..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/DeterministicWiringModel.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (C) 2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.model; - -import com.swirlds.common.context.PlatformContext; -import org.hiero.wiring.framework.model.internal.deterministic.DeterministicHeartbeatScheduler; -import org.hiero.wiring.framework.model.internal.deterministic.DeterministicTaskSchedulerBuilder; -import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerBuilder; -import org.hiero.wiring.framework.wires.output.NoOpOutputWire; -import org.hiero.wiring.framework.wires.output.OutputWire; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.time.Duration; -import java.time.Instant; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - -/** - * A deterministic implementation of a wiring model. Suitable for testing, not intended for production use cases. - */ -public class DeterministicWiringModel extends TraceableWiringModel { - - private final PlatformContext platformContext; - - /** - * Work that we will perform in the current cycle. - */ - private List currentCycleWork = new ArrayList<>(); - - /** - * Work that we will perform in the next cycle. - */ - private List nextCycleWork = new ArrayList<>(); - - private final DeterministicHeartbeatScheduler heartbeatScheduler; - - /** - * Constructor. - * - * @param platformContext the context for this node - */ - DeterministicWiringModel(@NonNull final PlatformContext platformContext) { - super(false); - this.platformContext = Objects.requireNonNull(platformContext); - this.heartbeatScheduler = new DeterministicHeartbeatScheduler(this, platformContext.getTime(), "heartbeat"); - } - - /** - * Advance time. Amount of time that advances depends on how {@link com.swirlds.base.time.Time Time} has been - * advanced. - */ - public void tick() { - for (final Runnable work : currentCycleWork) { - work.run(); - } - - // Note: heartbeats are handled at their destinations during the next cycle. - heartbeatScheduler.tick(); - - currentCycleWork = nextCycleWork; - nextCycleWork = new ArrayList<>(); - } - - /** - * Submit a unit of work to be performed. - * - * @param work the work to be performed - */ - private void submitWork(@NonNull final Runnable work) { - // Work is never handled in the same cycle as when it is submitted. - nextCycleWork.add(work); - } - - /** - * {@inheritDoc} - */ - @NonNull - @Override - public TaskSchedulerBuilder schedulerBuilder(@NonNull final String name) { - return new DeterministicTaskSchedulerBuilder<>(platformContext, this, name, this::submitWork); - } - - /** - * {@inheritDoc} - */ - @NonNull - @Override - public OutputWire buildHeartbeatWire(@NonNull final Duration period) { - return heartbeatScheduler.buildHeartbeatWire(period); - } - - /** - * {@inheritDoc} - */ - @NonNull - @Override - public OutputWire getHealthMonitorWire() { - return new NoOpOutputWire<>(this, "HealthMonitor"); - } - - /** - * {@inheritDoc} - */ - @NonNull - @Override - public Duration getUnhealthyDuration() { - return Duration.ZERO; - } - - /** - * {@inheritDoc} - */ - @NonNull - @Override - public OutputWire buildHeartbeatWire(final double frequency) { - return heartbeatScheduler.buildHeartbeatWire(frequency); - } - - /** - * {@inheritDoc} - */ - @Override - public void start() { - throwIfStarted(); - markAsStarted(); - heartbeatScheduler.start(); - } - - /** - * {@inheritDoc} - */ - @Override - public void stop() { - throwIfNotStarted(); - } -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/StandardWiringModel.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/StandardWiringModel.java deleted file mode 100644 index 5a0100de8e5..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/StandardWiringModel.java +++ /dev/null @@ -1,256 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.model; - -import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.NO_OP; -import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.SEQUENTIAL; -import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.SEQUENTIAL_THREAD; - -import com.swirlds.common.context.PlatformContext; -import org.hiero.wiring.framework.model.diagram.HyperlinkBuilder; -import org.hiero.wiring.framework.model.internal.monitor.HealthMonitor; -import org.hiero.wiring.framework.model.internal.standard.HeartbeatScheduler; -import org.hiero.wiring.framework.model.internal.standard.JvmAnchor; -import org.hiero.wiring.framework.schedulers.TaskScheduler; -import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerBuilder; -import org.hiero.wiring.framework.schedulers.builders.internal.StandardTaskSchedulerBuilder; -import org.hiero.wiring.framework.schedulers.internal.SequentialThreadTaskScheduler; -import org.hiero.wiring.framework.wires.input.BindableInputWire; -import org.hiero.wiring.framework.wires.output.OutputWire; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import java.time.Duration; -import java.time.Instant; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.concurrent.ForkJoinPool; - -/** - * A standard implementation of a wiring model suitable for production use. - */ -public class StandardWiringModel extends TraceableWiringModel { - - /** - * The platform context. - */ - private final PlatformContext platformContext; - - /** - * Schedules heartbeats. Not created unless needed. - */ - private HeartbeatScheduler heartbeatScheduler = null; - - /** - * The scheduler that the health monitor runs on. - */ - private final TaskScheduler healthMonitorScheduler; - - /** - * The health monitor. - */ - private HealthMonitor healthMonitor; - - /** - * The input wire for the health monitor. - */ - private final BindableInputWire healthMonitorInputWire; - - /** - * Thread schedulers need to have their threads started/stopped. - */ - private final List> threadSchedulers = new ArrayList<>(); - - /** - * The default fork join pool, schedulers not explicitly assigned a pool will use this one. - */ - private final ForkJoinPool defaultPool; - - /** - * Used to prevent the JVM from prematurely exiting. - */ - private final JvmAnchor anchor; - - /** - * The amount of time that must pass before we start logging health information. - */ - private final Duration healthLogThreshold; - - /** - * The period at which we log health information. - */ - private final Duration healthLogPeriod; - - /** - * Constructor. - * - * @param builder the builder for this model, contains all needed configuration - */ - StandardWiringModel(@NonNull final WiringModelBuilder builder) { - super(builder.isHardBackpressureEnabled()); - - this.platformContext = Objects.requireNonNull(builder.getPlatformContext()); - this.defaultPool = Objects.requireNonNull(builder.getDefaultPool()); - - final TaskSchedulerBuilder healthMonitorSchedulerBuilder = this.schedulerBuilder("HealthMonitor"); - healthMonitorSchedulerBuilder.withHyperlink(HyperlinkBuilder.platformCoreHyperlink(HealthMonitor.class)); - if (builder.isHealthMonitorEnabled()) { - healthMonitorSchedulerBuilder - .withType(SEQUENTIAL) - .withUnhandledTaskMetricEnabled(true) - .withUnhandledTaskCapacity(builder.getHealthMonitorCapacity()); - } else { - healthMonitorSchedulerBuilder.withType(NO_OP); - } - - healthLogThreshold = builder.getHealthLogThreshold(); - healthLogPeriod = builder.getHealthLogPeriod(); - healthMonitorScheduler = healthMonitorSchedulerBuilder.build(); - healthMonitorInputWire = healthMonitorScheduler.buildInputWire("check system health"); - buildHeartbeatWire(builder.getHealthMonitorPeriod()).solderTo(healthMonitorInputWire); - - if (builder.isJvmAnchorEnabled()) { - anchor = new JvmAnchor(); - } else { - anchor = null; - } - } - - /** - * {@inheritDoc} - */ - @NonNull - @Override - public final TaskSchedulerBuilder schedulerBuilder(@NonNull final String name) { - throwIfStarted(); - return new StandardTaskSchedulerBuilder<>(platformContext, this, name, defaultPool); - } - - /** - * {@inheritDoc} - */ - @Override - @NonNull - public OutputWire buildHeartbeatWire(@NonNull final Duration period) { - throwIfStarted(); - return getHeartbeatScheduler().buildHeartbeatWire(period); - } - - /** - * {@inheritDoc} - */ - @NonNull - @Override - public OutputWire getHealthMonitorWire() { - return healthMonitorScheduler.getOutputWire(); - } - - /** - * {@inheritDoc} - */ - @NonNull - @Override - public Duration getUnhealthyDuration() { - throwIfNotStarted(); - return healthMonitor.getUnhealthyDuration(); - } - - /** - * {@inheritDoc} - */ - @Override - @NonNull - public OutputWire buildHeartbeatWire(final double frequency) { - throwIfStarted(); - return getHeartbeatScheduler().buildHeartbeatWire(frequency); - } - - /** - * {@inheritDoc} - */ - @Override - public void registerScheduler(@NonNull final TaskScheduler scheduler, @Nullable final String hyperlink) { - super.registerScheduler(scheduler, hyperlink); - if (scheduler.getType() == SEQUENTIAL_THREAD) { - threadSchedulers.add((SequentialThreadTaskScheduler) scheduler); - } - } - - /** - * {@inheritDoc} - */ - @Override - public void start() { - throwIfStarted(); - - if (anchor != null) { - anchor.start(); - } - - healthMonitor = new HealthMonitor(platformContext, schedulers, healthLogThreshold, healthLogPeriod); - healthMonitorInputWire.bind(healthMonitor::checkSystemHealth); - - markAsStarted(); - - // We don't have to do anything with the output of these sanity checks. - // The methods below will log errors if they find problems. - checkForCyclicalBackpressure(); - checkForIllegalDirectSchedulerUsage(); - checkForUnboundInputWires(); - - if (heartbeatScheduler != null) { - heartbeatScheduler.start(); - } - - for (final SequentialThreadTaskScheduler threadScheduler : threadSchedulers) { - threadScheduler.start(); - } - } - - /** - * {@inheritDoc} - */ - @Override - public void stop() { - throwIfNotStarted(); - - if (heartbeatScheduler != null) { - heartbeatScheduler.stop(); - } - - for (final SequentialThreadTaskScheduler threadScheduler : threadSchedulers) { - threadScheduler.stop(); - } - - if (anchor != null) { - anchor.stop(); - } - } - - /** - * Get the heartbeat scheduler, creating it if necessary. - * - * @return the heartbeat scheduler - */ - @NonNull - private HeartbeatScheduler getHeartbeatScheduler() { - if (heartbeatScheduler == null) { - heartbeatScheduler = new HeartbeatScheduler(this, platformContext.getTime(), "Heartbeat"); - } - return heartbeatScheduler; - } -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/TraceableWiringModel.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/TraceableWiringModel.java deleted file mode 100644 index 7395a9ddd6d..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/TraceableWiringModel.java +++ /dev/null @@ -1,334 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.model; - -import static org.hiero.wiring.framework.model.internal.analysis.ModelVertexMetaType.SCHEDULER; -import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.DIRECT; -import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.DIRECT_THREADSAFE; - -import org.hiero.wiring.framework.model.diagram.ModelEdgeSubstitution; -import org.hiero.wiring.framework.model.diagram.ModelGroup; -import org.hiero.wiring.framework.model.diagram.ModelManualLink; -import org.hiero.wiring.framework.model.internal.analysis.CycleFinder; -import org.hiero.wiring.framework.model.internal.analysis.DirectSchedulerChecks; -import org.hiero.wiring.framework.model.internal.analysis.InputWireChecks; -import org.hiero.wiring.framework.model.internal.analysis.InputWireDescriptor; -import org.hiero.wiring.framework.model.internal.analysis.ModelEdge; -import org.hiero.wiring.framework.model.internal.analysis.ModelVertex; -import org.hiero.wiring.framework.model.internal.analysis.StandardVertex; -import org.hiero.wiring.framework.model.internal.analysis.WiringFlowchart; -import org.hiero.wiring.framework.schedulers.TaskScheduler; -import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; -import org.hiero.wiring.framework.wires.SolderType; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Set; - -/** - * Common functionality for wiring model implementations. Has methods for registering information about the topology of - * wiring that is appropriate for internal use by the framework, but should not be exposed to the end users of the - * wiring framework. - */ -public abstract class TraceableWiringModel implements WiringModel { - - /** - * A map of vertex names to vertices. - */ - private final Map vertices = new HashMap<>(); - - /** - * A set of all edges in the model. - */ - private final Set edges = new HashSet<>(); - - /** - * Input wires that have been created. - */ - private final Set inputWires = new HashSet<>(); - - /** - * Input wires that have been bound to a handler. - */ - private final Set boundInputWires = new HashSet<>(); - - /** - * Input wires with at least one thing soldered to them. - */ - private final Set solderedInputWires = new HashSet<>(); - - /** - * All task schedulers in the model. - */ - protected final List> schedulers = new ArrayList<>(); - - /** - * True if start() has been called. - */ - private boolean started = false; - - /** - * True if backpressure is enabled. - */ - private final boolean backpressureEnabled; - - /** - * Constructor. - * - * @param backpressureEnabled true if backpressure is enabled - */ - TraceableWiringModel(final boolean backpressureEnabled) { - this.backpressureEnabled = backpressureEnabled; - } - - /** - * If true then backpressure is enabled. If false then this model will never apply backpressure internally. - * - * @return true if backpressure is enabled for this model - */ - public boolean isBackpressureEnabled() { - return backpressureEnabled; - } - - /** - * {@inheritDoc} - */ - @Override - public boolean checkForCyclicalBackpressure() { - return CycleFinder.checkForCyclicalBackPressure(vertices.values()); - } - - /** - * {@inheritDoc} - */ - @Override - public boolean checkForIllegalDirectSchedulerUsage() { - return DirectSchedulerChecks.checkForIllegalDirectSchedulerUse(vertices.values()); - } - - /** - * {@inheritDoc} - */ - @Override - public boolean checkForUnboundInputWires() { - return InputWireChecks.checkForUnboundInputWires(inputWires, boundInputWires); - } - - /** - * {@inheritDoc} - */ - @NonNull - @Override - public String generateWiringDiagram( - @NonNull final List groups, - @NonNull final List substitutions, - @NonNull final List manualLinks, - final boolean moreMystery) { - addVertexForUnsolderedInputWires(moreMystery); - final WiringFlowchart flowchart = new WiringFlowchart(vertices, substitutions, groups, manualLinks); - return flowchart.render(); - } - - /** - * Add a special vertex for all unsoldered input wires. - */ - private void addVertexForUnsolderedInputWires(final boolean moreMystery) { - final Set unsolderedInputWires = new HashSet<>(inputWires); - unsolderedInputWires.removeAll(solderedInputWires); - - if (unsolderedInputWires.isEmpty()) { - return; - } - - final ModelVertex unsolderedDataSource = - new StandardVertex("Mystery Input", DIRECT_THREADSAFE, SCHEDULER, null, true); - vertices.put(unsolderedDataSource.getName(), unsolderedDataSource); - - for (final InputWireDescriptor unsolderedInputWire : unsolderedInputWires) { - final ModelVertex destination = getVertex(unsolderedInputWire.taskSchedulerName()); - - final String edgeDescription = moreMystery ? "mystery data" : unsolderedInputWire.name(); - final ModelEdge edge = new ModelEdge(unsolderedDataSource, destination, edgeDescription, true, true); - unsolderedDataSource.getOutgoingEdges().add(edge); - } - } - - /** - * Register a task scheduler with the wiring model. - * - * @param scheduler the task scheduler to register - * @param hyperlink the hyperlink to the documentation for this vertex, or null if there is no documentation - */ - public void registerScheduler(@NonNull final TaskScheduler scheduler, @Nullable final String hyperlink) { - throwIfStarted(); - Objects.requireNonNull(scheduler); - schedulers.add(scheduler); - registerVertex(scheduler.getName(), scheduler.getType(), hyperlink, scheduler.isInsertionBlocking()); - } - - /** - * Register a vertex in the wiring model. These are either task schedulers or wire transformers. - * - * @param vertexName the name of the vertex - * @param type the type of task scheduler that corresponds to this vertex. - * @param hyperlink the hyperlink to the documentation for this vertex, or null if there is no - * documentation - * @param insertionIsBlocking if true then insertion may block until capacity is available - */ - public void registerVertex( - @NonNull final String vertexName, - @NonNull final TaskSchedulerType type, - @Nullable final String hyperlink, - final boolean insertionIsBlocking) { - throwIfStarted(); - Objects.requireNonNull(vertexName); - Objects.requireNonNull(type); - final boolean unique = vertices.put( - vertexName, new StandardVertex(vertexName, type, SCHEDULER, hyperlink, insertionIsBlocking)) - == null; - if (!unique) { - throw new IllegalArgumentException("Duplicate vertex name: " + vertexName); - } - } - - /** - * Register an edge between two vertices. - * - * @param originVertex the origin vertex - * @param destinationVertex the destination vertex - * @param label the label of the edge - * @param solderType the type of solder connection - */ - public void registerEdge( - @NonNull final String originVertex, - @NonNull final String destinationVertex, - @NonNull final String label, - @NonNull final SolderType solderType) { - throwIfStarted(); - - final boolean blockingEdge = solderType == SolderType.PUT; - - final ModelVertex origin = getVertex(originVertex); - final ModelVertex destination = getVertex(destinationVertex); - final boolean blocking = blockingEdge && destination.isInsertionIsBlocking(); - - final ModelEdge edge = new ModelEdge(origin, destination, label, blocking, false); - origin.getOutgoingEdges().add(edge); - - final boolean unique = edges.add(edge); - if (!unique) { - throw new IllegalArgumentException( - "Duplicate edge: " + originVertex + " -> " + destinationVertex + ", label = " + label); - } - - solderedInputWires.add(new InputWireDescriptor(destinationVertex, label)); - } - - /** - * Register an input wire with the wiring model. For every input wire registered via this method, the model expects - * to see exactly one registration via {@link #registerInputWireBinding(String, String)}. - * - * @param taskSchedulerName the name of the task scheduler that the input wire is associated with - * @param inputWireName the name of the input wire - */ - public void registerInputWireCreation( - @NonNull final String taskSchedulerName, @NonNull final String inputWireName) { - throwIfStarted(); - - final boolean unique = inputWires.add(new InputWireDescriptor(taskSchedulerName, inputWireName)); - if (!unique) { - throw new IllegalStateException( - "Duplicate input wire " + inputWireName + " for scheduler " + taskSchedulerName); - } - } - - /** - * Register an input wire binding with the wiring model. For every input wire registered via - * {@link #registerInputWireCreation(String, String)}, the model expects to see exactly one registration via this - * method. - * - * @param taskSchedulerName the name of the task scheduler that the input wire is associated with - * @param inputWireName the name of the input wire - */ - public void registerInputWireBinding(@NonNull final String taskSchedulerName, @NonNull final String inputWireName) { - throwIfStarted(); - - final InputWireDescriptor descriptor = new InputWireDescriptor(taskSchedulerName, inputWireName); - - final boolean registered = inputWires.contains(descriptor); - if (!registered) { - throw new IllegalStateException( - "Input wire " + inputWireName + " for scheduler " + taskSchedulerName + " was not registered"); - } - - final boolean unique = boundInputWires.add(descriptor); - if (!unique) { - throw new IllegalStateException("Input wire " + inputWireName + " for scheduler " + taskSchedulerName - + " should not be bound more than once"); - } - } - - /** - * Throw an exception if start() has already been called. - */ - protected void throwIfStarted() { - if (started) { - throw new IllegalStateException("start() has already been called, operation not permitted."); - } - } - - /** - * Throw an exception if the wiring model has not been started. - */ - protected void throwIfNotStarted() { - if (!started) { - throw new IllegalStateException("start() has not been called, operation not permitted."); - } - } - - /** - * Mark the wiring model as started. - */ - protected void markAsStarted() { - started = true; - } - - /** - * Find an existing vertex - * - * @param vertexName the name of the vertex - * @return the vertex - */ - @NonNull - private ModelVertex getVertex(@NonNull final String vertexName) { - final ModelVertex vertex = vertices.get(vertexName); - if (vertex != null) { - return vertex; - } - - // Create an ad hoc vertex. - final StandardVertex adHocVertex = new StandardVertex(vertexName, DIRECT, SCHEDULER, null, true); - - vertices.put(vertexName, adHocVertex); - return adHocVertex; - } -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/WiringModel.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/WiringModel.java deleted file mode 100644 index 7c586cd1137..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/WiringModel.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.model; - -import com.swirlds.base.state.Startable; -import com.swirlds.base.state.Stoppable; -import org.hiero.wiring.framework.model.diagram.ModelEdgeSubstitution; -import org.hiero.wiring.framework.model.diagram.ModelGroup; -import org.hiero.wiring.framework.model.diagram.ModelManualLink; -import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerBuilder; -import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; -import org.hiero.wiring.framework.wires.output.OutputWire; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.time.Duration; -import java.time.Instant; -import java.util.List; - -/** - * A wiring model is a collection of task schedulers and the wires connecting them. It can be used to analyze the wiring - * of a system and to generate diagrams. - */ -public interface WiringModel extends Startable, Stoppable { - - /** - * Get a new task scheduler builder. - * - * @param name the name of the task scheduler. Used for metrics and debugging. Must be unique. Must only contain - * alphanumeric characters and underscores. - * @param the data type of the scheduler's primary output wire - * @return a new task scheduler builder - */ - @NonNull - TaskSchedulerBuilder schedulerBuilder(@NonNull final String name); - - /** - * Check to see if there is cyclic backpressure in the wiring model. Cyclical back pressure can lead to deadlocks, - * and so it should be avoided at all costs. - * - *

    - * If this method finds cyclical backpressure, it will log a message that will fail standard platform tests. - * - * @return true if there is cyclical backpressure, false otherwise - */ - boolean checkForCyclicalBackpressure(); - - /** - * Task schedulers using the {@link TaskSchedulerType#DIRECT} strategy have very strict rules about how data can be - * added to input wires. This method checks to see if these rules are being followed. - * - *

    - * If this method finds illegal direct scheduler usage, it will log a message that will fail standard platform - * tests. - * - * @return true if there is illegal direct scheduler usage, false otherwise - */ - boolean checkForIllegalDirectSchedulerUsage(); - - /** - * Check to see if there are any input wires that are unbound. - * - *

    - * If this method detects unbound input wires in the model, it will log a message that will fail standard platform - * tests. - * - * @return true if there are unbound input wires, false otherwise - */ - boolean checkForUnboundInputWires(); - - /** - * Generate a mermaid style wiring diagram. - * - * @param groups optional groupings of vertices - * @param substitutions edges to substitute - * @param manualLinks manual links to add to the diagram - * @param moreMystery if enabled then use a generic label for all input from mystery sources. This removes - * information about mystery edges, but allows the diagram to be easier to groc. Turn this off - * when attempting to debug mystery edges. - * @return a mermaid style wiring diagram - */ - @NonNull - String generateWiringDiagram( - @NonNull List groups, - @NonNull List substitutions, - @NonNull List manualLinks, - boolean moreMystery); - - /** - * Build a wire that produces an instant (reflecting current time) at the specified rate. Note that the exact rate - * of heartbeats may vary. This is a best effort algorithm, and actual rates may vary depending on a variety of - * factors. - * - * @param period the period of the heartbeat. For example, setting a period of 100ms will cause the heartbeat to be - * sent at 10 hertz. Note that time is measured at millisecond precision, and so periods less than 1ms - * are not supported. - * @return the output wire - * @throws IllegalStateException if start() has already been called - */ - @NonNull - OutputWire buildHeartbeatWire(@NonNull final Duration period); - - /** - * Get the output of the wiring model's health monitor. The output of this wire is the length of time that any - * particular scheduler has been in an unhealthy state, or {@link Duration#ZERO} if all schedulers are currently - * healthy. - * - * @return the output wire - */ - @NonNull - OutputWire getHealthMonitorWire(); - - /** - * Get the duration that any particular scheduler has been concurrently unhealthy. This getter is intended for use - * by things outside of the wiring framework. For use within the framework, the proper way to access this value is - * via the wire returned by {@link #getHealthMonitorWire()}. - * - * @return the duration that any particular scheduler has been concurrently unhealthy, or {@link Duration#ZERO} if - * no scheduler is currently unhealthy - */ - @NonNull - Duration getUnhealthyDuration(); - - /** - * Build a wire that produces an instant (reflecting current time) at the specified rate. Note that the exact rate - * of heartbeats may vary. This is a best effort algorithm, and actual rates may vary depending on a variety of - * factors. - * - * @param frequency the frequency of the heartbeat in hertz. Note that time is measured at millisecond precision, - * and so frequencies greater than 1000hz are not supported. - * @return the output wire - */ - @NonNull - OutputWire buildHeartbeatWire(final double frequency); - - /** - * Start everything in the model that needs to be started. Performs static analysis of the wiring topology and - * writes errors to the logs if problems are detected. - */ - @Override - void start(); - - /** - * Stops everything in the model that needs to be stopped. - */ - @Override - void stop(); -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/WiringModelBuilder.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/WiringModelBuilder.java deleted file mode 100644 index 8dea26704b8..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/WiringModelBuilder.java +++ /dev/null @@ -1,278 +0,0 @@ -/* - * Copyright (C) 2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.model; - -import com.swirlds.common.context.PlatformContext; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.time.Duration; -import java.util.Objects; -import java.util.concurrent.ForkJoinPool; - -/** - * Builds a {@link WiringModel}. - */ -public class WiringModelBuilder { - - private final PlatformContext platformContext; - - private boolean deterministicModeEnabled; - private ForkJoinPool defaultPool = ForkJoinPool.commonPool(); - private boolean healthMonitorEnabled = true; - private boolean hardBackpressureEnabled = false; - private boolean jvmAnchorEnabled = false; - private int healthMonitorCapacity = 500; - private Duration healthMonitorPeriod = Duration.ofMillis(100); - private Duration healthLogThreshold = Duration.ofSeconds(5); - private Duration healthLogPeriod = Duration.ofMinutes(10); - - /** - * Create a new builder. - * - * @param platformContext the platform context - * @return the builder - */ - @NonNull - public static WiringModelBuilder create(@NonNull final PlatformContext platformContext) { - return new WiringModelBuilder(platformContext); - } - - /** - * Constructor. - * - * @param platformContext the platform context - */ - private WiringModelBuilder(@NonNull final PlatformContext platformContext) { - this.platformContext = Objects.requireNonNull(platformContext); - } - - /** - * Specify the fork join pool to use for schedulers that don't specify a fork join pool. Schedulers not explicitly - * assigned a pool will use this one. Default is the common pool. - * - * @param defaultPool the default fork join pool - * @return this - */ - @NonNull - public WiringModelBuilder withDefaultPool(@NonNull final ForkJoinPool defaultPool) { - this.defaultPool = Objects.requireNonNull(defaultPool); - return this; - } - - /** - * Set if deterministic mode should be enabled. If enabled, the wiring model will be deterministic (and much - * slower). Suitable for simulations and testing. Default false. - * - * @param deterministicModeEnabled whether to enable deterministic mode - * @return this - */ - @NonNull - public WiringModelBuilder withDeterministicModeEnabled(final boolean deterministicModeEnabled) { - this.deterministicModeEnabled = deterministicModeEnabled; - return this; - } - - /** - * Set if the health monitor should be enabled. Default is true. - * - * @param healthMonitorEnabled whether to enable the health monitor - * @return this - */ - @NonNull - public WiringModelBuilder withHealthMonitorEnabled(final boolean healthMonitorEnabled) { - this.healthMonitorEnabled = healthMonitorEnabled; - return this; - } - - /** - * Set if hard backpressure should be enabled. Default is false. - * - * @param hardBackpressureEnabled whether to enable hard backpressure - * @return this - */ - @NonNull - public WiringModelBuilder withHardBackpressureEnabled(final boolean hardBackpressureEnabled) { - this.hardBackpressureEnabled = hardBackpressureEnabled; - return this; - } - - /** - * Set if the JVM anchor should be enabled. Default is false. If enabled and {@link WiringModel#start()} has been - * called, the JVM will not automatically exit due to lack of non-daemon threads until {@link WiringModel#stop()} is - * called. - * - * @param jvmAnchorEnabled whether to enable the JVM anchor - * @return this - */ - @NonNull - public WiringModelBuilder withJvmAnchorEnabled(final boolean jvmAnchorEnabled) { - this.jvmAnchorEnabled = jvmAnchorEnabled; - return this; - } - - /** - * Set the capacity of the health monitor's task scheduler's unhandled task capacity. Default is 500. - * - * @param healthMonitorCapacity the capacity of the health monitor - * @return this - */ - @NonNull - public WiringModelBuilder withHealthMonitorCapacity(final int healthMonitorCapacity) { - this.healthMonitorCapacity = healthMonitorCapacity; - return this; - } - - /** - * Set the period of the health monitor's task scheduler. Default is 100ms. - * - * @param healthMonitorPeriod the period of the health monitor - * @return this - */ - @NonNull - public WiringModelBuilder withHealthMonitorPeriod(@NonNull final Duration healthMonitorPeriod) { - this.healthMonitorPeriod = Objects.requireNonNull(healthMonitorPeriod); - return this; - } - - /** - * Set the amount of time a scheduler may be unhealthy before the platform is considered to be unhealthy. When a - * scheduler crosses this threshold, the health monitor will log a warning. Default is 5 seconds. - * - * @param healthThreshold the amount of time a scheduler may be unhealthy - * @return this - */ - @NonNull - public WiringModelBuilder withHealthLogThreshold(@NonNull final Duration healthThreshold) { - this.healthLogThreshold = Objects.requireNonNull(healthThreshold); - return this; - } - - /** - * Set the minimum amount of time that must pass between health log messages for the same scheduler. Default is 10 - * minutes. - * - * @param healthLogPeriod the minimum amount of time that must pass between health log messages - * @return this - */ - @NonNull - public WiringModelBuilder withHealthLogPeriod(@NonNull final Duration healthLogPeriod) { - this.healthLogPeriod = Objects.requireNonNull(healthLogPeriod); - return this; - } - - /** - * Build the wiring model. - * - * @param the type of wiring model - * @return the wiring model - */ - @SuppressWarnings("unchecked") - @NonNull - public T build() { - if (deterministicModeEnabled) { - return (T) new DeterministicWiringModel(platformContext); - } else { - return (T) new StandardWiringModel(this); - } - } - - /** - * Get the platform context. - * - * @return the platform context - */ - @NonNull - PlatformContext getPlatformContext() { - return platformContext; - } - - /** - * Get the default fork join pool for schedulers. Schedulers that have not been assigned a fork join pool should use - * this one. - * - * @return the default fork join pool - */ - @NonNull - ForkJoinPool getDefaultPool() { - return defaultPool; - } - - /** - * Check if the health monitor is enabled. - * - * @return true if the health monitor is enabled - */ - boolean isHealthMonitorEnabled() { - return healthMonitorEnabled; - } - - /** - * Check if hard backpressure is enabled. - * - * @return true if hard backpressure is enabled - */ - boolean isHardBackpressureEnabled() { - return hardBackpressureEnabled; - } - - /** - * Check if the JVM anchor is enabled. - * - * @return true if the JVM anchor is enabled - */ - boolean isJvmAnchorEnabled() { - return jvmAnchorEnabled; - } - - /** - * Get the capacity of the health monitor's task scheduler's unhandled task capacity. - * - * @return the capacity of the health monitor - */ - int getHealthMonitorCapacity() { - return healthMonitorCapacity; - } - - /** - * Get the period of the health monitor's task scheduler. - * - * @return the period of the health monitor - */ - @NonNull - Duration getHealthMonitorPeriod() { - return healthMonitorPeriod; - } - - /** - * Get the amount of time a scheduler may be unhealthy before the platform is considered to be unhealthy. - * - * @return the amount of time a scheduler may be unhealthy - */ - @NonNull - Duration getHealthLogThreshold() { - return healthLogThreshold; - } - - /** - * Get the minimum amount of time that must pass between health log messages for the same scheduler. - * - * @return the minimum amount of time that must pass between health log messages - */ - @NonNull - Duration getHealthLogPeriod() { - return healthLogPeriod; - } -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/diagram/HyperlinkBuilder.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/diagram/HyperlinkBuilder.java deleted file mode 100644 index 8cda7a5ac18..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/diagram/HyperlinkBuilder.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (C) 2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.model.diagram; - -import edu.umd.cs.findbugs.annotations.NonNull; - -/** - * Given a class, derive a hyperlink to the github for that class's source code (in main). - */ -public final class HyperlinkBuilder { - - public static final String PLATFORM_CORE_ROOT = "https://github.com/hashgraph/hedera-services/blob/main/" - + "platform-sdk/swirlds-platform-core/src/main/java"; - - public static final String PLATFORM_COMMON_ROOT = - "https://github.com/hashgraph/hedera-services/blob/main/platform-sdk/swirlds-common/src/main/java"; - - /** - * Build a hyperlink to the platform core source code for the given class. Only works for things in the core - * platform module. - * - * @param clazz the class - * @return the hyperlink - */ - public static String platformCoreHyperlink(@NonNull final Class clazz) { - return buildHyperlink(PLATFORM_CORE_ROOT, clazz); - } - - /** - * Build a hyperlink to the platform common source code for the given class. Only works for things in the common - * platform module. - * - * @param clazz the class - * @return the hyperlink - */ - public static String platformCommonHyperlink(@NonNull final Class clazz) { - return buildHyperlink(PLATFORM_COMMON_ROOT, clazz); - } - - /** - * Get a github hyperlink to this class (in main). - * - * @param clazz the class - * @return the hyperlink - */ - @NonNull - public static String buildHyperlink(@NonNull final String root, @NonNull final Class clazz) { - - final String className = clazz.getName(); - final String[] parts = className.split("\\."); - - final StringBuilder sb = new StringBuilder(); - sb.append(root); - if (!root.endsWith("/")) { - sb.append("/"); - } - for (int i = 0; i < parts.length; i++) { - sb.append(parts[i]); - if (i < parts.length - 1) { - sb.append("/"); - } - } - sb.append(".java"); - - return sb.toString(); - } -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/diagram/ModelEdgeSubstitution.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/diagram/ModelEdgeSubstitution.java deleted file mode 100644 index a5226d60121..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/diagram/ModelEdgeSubstitution.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.model.diagram; - -import edu.umd.cs.findbugs.annotations.NonNull; - -/** - * Describes an edge substitution. A substituted edge is not drawn on the diagram, and is instead noted using a label. - * Useful for situations where a component is connected with a large number of other components (thus making the diagram - * hard to read). - * - * @param source the name of the scheduler that produces the output wire corresponding to the edge we are - * attempting to substitute (NOT the group name, if grouped) - * @param edge the label on the edge(s) to be substituted - * @param substitution the substitute label - */ -public record ModelEdgeSubstitution(@NonNull String source, @NonNull String edge, @NonNull String substitution) {} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/diagram/ModelGroup.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/diagram/ModelGroup.java deleted file mode 100644 index c8ed076c050..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/diagram/ModelGroup.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.model.diagram; - -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.Set; - -/** - * Describes a group of components that should be visualized together in a wiring diagram. Specified via strings since - * this configuration is presumably read from the command line. - * - * @param name the name of the group - * @param elements the set of subcomponents in the group - * @param collapse true if the group should be collapsed into a single box - */ -public record ModelGroup(@NonNull String name, @NonNull Set elements, boolean collapse) - implements Comparable { - - /** - * Sorts groups by name. - */ - @Override - public int compareTo(@NonNull final ModelGroup that) { - return name.compareTo(that.name); - } -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/diagram/ModelManualLink.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/diagram/ModelManualLink.java deleted file mode 100644 index f55a9832d3a..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/diagram/ModelManualLink.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.model.diagram; - -import edu.umd.cs.findbugs.annotations.NonNull; - -/** - * Describes a manual link between two components. Useful for adding information to the diagram that is not captured by - * the wiring framework - * - * @param source the source scheduler - * @param label the label on the edge - * @param target the target scheduler - */ -public record ModelManualLink(@NonNull String source, @NonNull String label, @NonNull String target) {} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/CycleFinder.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/CycleFinder.java deleted file mode 100644 index 2774d98eb3c..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/CycleFinder.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.model.internal.analysis; - -import static com.swirlds.logging.legacy.LogMarker.EXCEPTION; -import static com.swirlds.logging.legacy.LogMarker.STARTUP; - -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Deque; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -/** - * A utility for finding cyclical back pressure in a wiring model. - */ -public final class CycleFinder { - - private static final Logger logger = LogManager.getLogger(CycleFinder.class); - - private CycleFinder() {} - - /** - * Check for cyclical back pressure in a wiring model. - * - * @param vertices the vertices in the wiring model - * @return true if there is cyclical backpressure - */ - public static boolean checkForCyclicalBackPressure(@NonNull final Collection vertices) { - for (final ModelVertex vertex : vertices) { - if (checkForCycleStartingFromVertex(vertex)) { - return true; - } - } - logger.info(STARTUP.getMarker(), "No cyclical back pressure detected in wiring model."); - return false; - } - - /** - * Check for a cycle starting from a vertex. - * - * @param start the vertex to start from - * @return true if there is a cycle - */ - private static boolean checkForCycleStartingFromVertex(@NonNull final ModelVertex start) { - - // Perform a depth first traversal of the graph starting from the given vertex. - // Ignore any edge that doesn't apply back pressure. - - final Deque stack = new LinkedList<>(); - stack.addLast(start); - - final Set visited = new HashSet<>(); - - // Track the parent of each vertex. Useful for tracing the cycle after it's detected. - final Map parents = new HashMap<>(); - - while (!stack.isEmpty()) { - - final ModelVertex parent = stack.removeLast(); - - for (final ModelEdge childEdge : parent.getOutgoingEdges()) { - if (!childEdge.isInsertionIsBlocking()) { - // Ignore non-blocking edges. - continue; - } - - final ModelVertex child = childEdge.getDestination(); - - if (child.equals(start)) { - // We've found a cycle! - parents.put(child, parent); - logCycle(start, parents); - return true; - } - - if (visited.add(child)) { - stack.addLast(child); - parents.put(child, parent); - } - } - } - return false; - } - - /** - * Logs a warning message when cyclical back pressure is detected. Is intended to fail standard test validators. - * - * @param start the vertex where the cycle was detected - * @param parents records the parents for the traversal, used to trace the cycle - */ - private static void logCycle( - @NonNull final ModelVertex start, @NonNull final Map parents) { - - final StringBuilder sb = new StringBuilder(); - sb.append("Cyclical back pressure detected in wiring model. Cycle: "); - - // Following parent links will walk the cycle in reverse order. - final List path = new ArrayList<>(); - path.add(start); - ModelVertex target = start; - - while (!target.equals(start) || path.size() == 1) { - target = parents.get(target); - path.add(target); - } - - for (int i = path.size() - 1; i >= 0; i--) { - sb.append(path.get(i).getName()); - if (i > 0) { - sb.append(" -> "); - } - } - - logger.error(EXCEPTION.getMarker(), sb.toString()); - } -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/DirectSchedulerChecks.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/DirectSchedulerChecks.java deleted file mode 100644 index e75052f3bc6..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/DirectSchedulerChecks.java +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.model.internal.analysis; - -import static com.swirlds.logging.legacy.LogMarker.EXCEPTION; -import static com.swirlds.logging.legacy.LogMarker.STARTUP; - -import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.Collection; -import java.util.Deque; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.Map; -import java.util.Set; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -/** - * A utility for checking direct scheduler use. - */ -public final class DirectSchedulerChecks { - - private static final Logger logger = LogManager.getLogger(DirectSchedulerChecks.class); - - private DirectSchedulerChecks() {} - - /** - * Check for illegal direct scheduler use. Rules are as follows: - * - *

      - *
    • - * Calling into a component with type {@link TaskSchedulerType#DIRECT DIRECT} - * from a component with {@link TaskSchedulerType#CONCURRENT CONCURRENT} is not - * allowed. - *
    • - *
    • - * Calling into a component with type {@link TaskSchedulerType#DIRECT DIRECT} - * from more than one component with type - * {@link TaskSchedulerType#SEQUENTIAL SEQUENTIAL} or type - * {@link TaskSchedulerType#SEQUENTIAL_THREAD SEQUENTIAL_THREAD} is not allowed. - *
    • - *
    • - * Calling into a component A with type - * {@link TaskSchedulerType#DIRECT DIRECT} from component B with type - * {@link TaskSchedulerType#DIRECT DIRECT} or type - * {@link TaskSchedulerType#DIRECT_THREADSAFE DIRECT_THREADSAFE} counts as a call - * into B from all components calling into component A. - *
    • - *
    - * - * @param vertices the vertices in the wiring model - * @return true if there is illegal direct scheduler use - */ - public static boolean checkForIllegalDirectSchedulerUse(@NonNull final Collection vertices) { - - boolean illegalAccessDetected = false; - - // Note: this is only logged if we detect a problem. - final StringBuilder sb = new StringBuilder("Illegal direct scheduler use detected:\n"); - - // A map from each direct vertex to a set of non-direct schedulers that call into it. - // If access is legal, then each of these sets should contain at most one element. - final Map> directVertexCallers = new HashMap<>(); - - for (final ModelVertex vertex : vertices) { - final TaskSchedulerType vertexType = vertex.getType(); - - if (vertexType == TaskSchedulerType.DIRECT || vertexType == TaskSchedulerType.DIRECT_THREADSAFE) { - // we can ignore direct schedulers at this phase. We care about calls INTO direct schedulers, - // not calls OUT OF direct schedulers. - continue; - } - - final Set directSchedulersAccessed = collectDirectVerticesAccessedByScheduler(vertex); - - if (vertexType == TaskSchedulerType.CONCURRENT && !directSchedulersAccessed.isEmpty()) { - // It is illegal for a concurrent scheduler to call into a direct scheduler. - illegalAccessDetected = true; - sb.append(" ") - .append(vertex.getName()) - .append(" is a concurrent scheduler that calls into direct scheduler(s):\n"); - for (final ModelVertex directScheduler : directSchedulersAccessed) { - sb.append(" - ").append(directScheduler.getName()).append("\n"); - } - } - - for (final ModelVertex directScheduler : directSchedulersAccessed) { - directVertexCallers - .computeIfAbsent(directScheduler, k -> new HashSet<>()) - .add(vertex); - } - } - - // Now, check to see if any direct schedulers are called into by more than one non-direct scheduler. - for (final Map.Entry> entry : directVertexCallers.entrySet()) { - final ModelVertex directScheduler = entry.getKey(); - final Set callers = entry.getValue(); - - if (callers.size() > 1) { - illegalAccessDetected = true; - sb.append(" ") - .append(directScheduler.getName()) - .append(" is called into by more than one non-direct scheduler:\n"); - for (final ModelVertex caller : callers) { - sb.append(" - ").append(caller.getName()).append("\n"); - } - } - } - - if (illegalAccessDetected) { - logger.error(EXCEPTION.getMarker(), sb.toString()); - } else { - logger.info(STARTUP.getMarker(), "No illegal direct scheduler use detected in the wiring model."); - } - - return illegalAccessDetected; - } - - /** - * Collect all direct vertices that are accessed by a scheduler. - * - * @param scheduler the scheduler to check - * @return the set of direct vertices accessed by the scheduler - */ - @NonNull - private static Set collectDirectVerticesAccessedByScheduler(@NonNull final ModelVertex scheduler) { - final Set directSchedulersAccessed = new HashSet<>(); - - final Deque stack = new LinkedList<>(); - final Set visited = new HashSet<>(); - - stack.addLast(scheduler); - visited.add(scheduler); - - while (!stack.isEmpty()) { - final ModelVertex next = stack.removeLast(); - - for (final ModelEdge edge : next.getOutgoingEdges()) { - final ModelVertex destination = edge.getDestination(); - final TaskSchedulerType destinationType = destination.getType(); - - if (destinationType != TaskSchedulerType.DIRECT - && destinationType != TaskSchedulerType.DIRECT_THREADSAFE) { - // we don't need to traverse edges that lead into non-direct schedulers - continue; - } - - if (destinationType == TaskSchedulerType.DIRECT) { - directSchedulersAccessed.add(destination); - } - - if (visited.add(destination)) { - stack.addLast(destination); - visited.add(destination); - } - } - } - - return directSchedulersAccessed; - } -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/GroupVertex.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/GroupVertex.java deleted file mode 100644 index d88a27f8806..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/GroupVertex.java +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.model.internal.analysis; - -import static org.hiero.wiring.framework.model.internal.analysis.WiringFlowchart.GROUP_COLOR; -import static org.hiero.wiring.framework.model.internal.analysis.WiringFlowchart.TEXT_COLOR; - -import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import java.util.HashSet; -import java.util.List; -import java.util.Objects; -import java.util.Set; - -/** - * A vertex that represents a nexted group of vertices. - */ -public class GroupVertex implements ModelVertex { - - /** - * The name of the vertex. - */ - private final String name; - - /** - * The outgoing edges of this vertex. - */ - private final Set outgoingEdges = new HashSet<>(); - - /** - * Vertices that are contained within this group. - */ - private final List subVertices; - - private int depth; - private final Set substitutedInputs = new HashSet<>(); - - public GroupVertex(@NonNull final String name, @NonNull final List subVertices) { - - this.name = Objects.requireNonNull(name); - this.subVertices = Objects.requireNonNull(subVertices); - - for (final ModelVertex vertex : subVertices) { - vertex.setDepth(1); - } - } - - /** - * {@inheritDoc} - */ - @NonNull - @Override - public String getName() { - return name; - } - - /** - * {@inheritDoc} - */ - @NonNull - @Override - public TaskSchedulerType getType() { - return TaskSchedulerType.DIRECT; - } - - /** - * {@inheritDoc} - */ - @Nullable - @Override - public String getHyperlink() { - return null; - } - - /** - * {@inheritDoc} - */ - @Override - public boolean isInsertionIsBlocking() { - return true; - } - - /** - * {@inheritDoc} - */ - @NonNull - @Override - public Set getOutgoingEdges() { - return outgoingEdges; - } - - /** - * {@inheritDoc} - */ - @NonNull - @Override - public Set getSubstitutedInputs() { - return substitutedInputs; - } - - /** - * Get the vertices that are contained within this group. - * - * @return the vertices that are contained within this group - */ - public List getSubVertices() { - return subVertices; - } - - /** - * {@inheritDoc} - */ - @Override - public void setDepth(final int depth) { - this.depth = depth; - for (final ModelVertex vertex : subVertices) { - vertex.setDepth(depth + 1); - } - } - - /** - * Generate the style for this vertex. - * - * @return the style for this vertex - */ - @NonNull - private String generateStyle() { - final int baseRedValue = Integer.parseInt(String.valueOf(GROUP_COLOR.charAt(0)), 16); - final int baseGreenValue = Integer.parseInt(String.valueOf(GROUP_COLOR.charAt(1)), 16); - final int baseBlueValue = Integer.parseInt(String.valueOf(GROUP_COLOR.charAt(2)), 16); - - final int redValue = Math.min(0xF, baseRedValue + depth * 2); - final int greenValue = Math.min(0xF, baseGreenValue + depth * 2); - final int blueValue = Math.min(0xF, baseBlueValue + depth * 2); - - final String color = String.format("%X%X%X", redValue, greenValue, blueValue); - - return "fill:#" + color + ",stroke:#" + TEXT_COLOR + ",stroke-width:2px"; - } - - /** - * {@inheritDoc} - */ - @Override - public void render( - @NonNull final StringBuilder sb, - @NonNull final MermaidNameShortener nameProvider, - @NonNull final MermaidStyleManager styleManager) { - final String shortName = nameProvider.getShortVertexName(name); - styleManager.registerStyle(shortName, generateStyle()); - - sb.append("subgraph ").append(shortName).append("[\"").append(name).append("\"]\n"); - subVertices.stream().sorted().forEachOrdered(vertex -> vertex.render(sb, nameProvider, styleManager)); - sb.append("end\n"); - } -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/InputWireChecks.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/InputWireChecks.java deleted file mode 100644 index 261812d5e56..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/InputWireChecks.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.model.internal.analysis; - -import static com.swirlds.logging.legacy.LogMarker.EXCEPTION; -import static com.swirlds.logging.legacy.LogMarker.STARTUP; - -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.Set; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -/** - * Utilities for sanity checking input wires. - */ -public final class InputWireChecks { - - private static final Logger logger = LogManager.getLogger(InputWireChecks.class); - - private InputWireChecks() {} - - /** - * Make sure every input wire was properly bound. - * - * @param inputWires the input wires that were created - * @param boundInputWires the input wires that were bound - * @return true if there were unbound input wires, false otherwise - */ - public static boolean checkForUnboundInputWires( - @NonNull final Set inputWires, - @NonNull final Set boundInputWires) { - if (inputWires.size() == boundInputWires.size()) { - logger.info(STARTUP.getMarker(), "All input wires have been bound."); - return false; - } - - final StringBuilder sb = new StringBuilder(); - sb.append("The following input wire(s) were created but not bound:\n"); - for (final InputWireDescriptor inputWire : inputWires) { - if (!boundInputWires.contains(inputWire)) { - sb.append(" - ") - .append("Input wire '") - .append(inputWire.name()) - .append("' in scheduler '") - .append(inputWire.taskSchedulerName()) - .append("'\n"); - } - } - - logger.error(EXCEPTION.getMarker(), sb.toString()); - - return true; - } -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/InputWireDescriptor.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/InputWireDescriptor.java deleted file mode 100644 index f90d31f7289..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/InputWireDescriptor.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.model.internal.analysis; - -import edu.umd.cs.findbugs.annotations.NonNull; - -/** - * Uniquely describes an input wire within a wiring model. - * - *

    - * This object exists so that standard input wires don't have to implement equals and hash code. - * - * @param taskSchedulerName the name of the task scheduler the input wire is bound to - * @param name the name of the input wire - */ -public record InputWireDescriptor(@NonNull String taskSchedulerName, @NonNull String name) {} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/MermaidNameShortener.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/MermaidNameShortener.java deleted file mode 100644 index e8dcd0bcd92..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/MermaidNameShortener.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.model.internal.analysis; - -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.HashMap; -import java.util.Map; - -/** - * Generates shortened names in a mermaid wiring flowchart. Reduces the resulting flowchart size. - */ -public class MermaidNameShortener { - - private final Map vertexNameMap = new HashMap<>(); - - /** - * Get the name that should be used for a vertex with the given base name. - * - * @param baseName the base name of the vertex - * @return the name that should be used for a vertex with the given base name - */ - @NonNull - public String getShortVertexName(@NonNull final String baseName) { - return vertexNameMap.computeIfAbsent(baseName, this::generateShortVertexName); - } - - /** - * Generate a name for a vertex with the given base name. - * - * @param baseName the base name of the vertex - * @return the name that should be used for a vertex with the given base name - */ - @NonNull - private String generateShortVertexName(@NonNull final String baseName) { - return "v" + vertexNameMap.size(); - } -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/MermaidStyleManager.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/MermaidStyleManager.java deleted file mode 100644 index 710000fb927..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/MermaidStyleManager.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.model.internal.analysis; - -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Manages the styles in a mermaid flowchart. - */ -public class MermaidStyleManager { - - private final Map styleToStyleName = new HashMap<>(); - private final Map styleNameToStyle = new HashMap<>(); - private final Map /* classes with style */> styleNameToClasses = - new HashMap<>(); - - /** - * Register a style string. Will be attached to a vertex with the given base name at a later time. - * - * @param name the name of the vertex with the style - * @param style the style string - */ - public void registerStyle(@NonNull final String name, @NonNull final String style) { - final String styleName = styleToStyleName.computeIfAbsent(style, this::generateShortStyleName); - styleNameToStyle.put(styleName, style); - styleNameToClasses.computeIfAbsent(styleName, x -> new ArrayList<>()).add(name); - } - - /** - * Generate a name for a style. - * - * @param style the style string - * @return the name that should be used for a style - */ - @NonNull - private String generateShortStyleName(@NonNull final String style) { - return "s" + styleToStyleName.size(); - } - - /** - * Render the styles to the given string builder. - * - * @param sb the string builder - */ - public void render(@NonNull final StringBuilder sb) { - styleNameToStyle.keySet().stream().sorted().forEachOrdered(styleName -> { - sb.append("classDef ") - .append(styleName) - .append(" ") - .append(styleNameToStyle.get(styleName)) - .append("\n"); - sb.append("class "); - final List classNames = styleNameToClasses.get(styleName); - Collections.sort(classNames); - for (int i = 0; i < classNames.size(); i++) { - sb.append(classNames.get(i)); - if (i < classNames.size() - 1) { - sb.append(","); - } - } - sb.append(" ").append(styleName).append("\n"); - }); - } -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/ModelEdge.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/ModelEdge.java deleted file mode 100644 index 3e9882c24e3..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/ModelEdge.java +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.model.internal.analysis; - -import static com.swirlds.common.utility.NonCryptographicHashing.hash32; - -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import java.util.Objects; - -/** - * A directed edge between to vertices. - */ -public class ModelEdge implements Comparable { - - private ModelVertex source; - private ModelVertex destination; - private final String label; - private final boolean insertionIsBlocking; - private final boolean manual; - - /** - * Constructor. - * - * @param source the source vertex - * @param destination the destination vertex - * @param label the label of the edge, if a label is not needed for an edge then holds the value "" - * @param insertionIsBlocking true if the insertion of this edge may block until capacity is available - * @param manual true if this edge has been manually added to the diagram, false if this edge - * represents something tracked by the wiring framework - */ - public ModelEdge( - @NonNull final ModelVertex source, - @NonNull final ModelVertex destination, - @NonNull final String label, - final boolean insertionIsBlocking, - final boolean manual) { - - this.source = Objects.requireNonNull(source); - this.destination = Objects.requireNonNull(destination); - this.label = Objects.requireNonNull(label); - this.insertionIsBlocking = insertionIsBlocking; - this.manual = manual; - } - - /** - * Get the source vertex. - * - * @return the source vertex - */ - @NonNull - public ModelVertex getSource() { - return source; - } - - /** - * Set the source vertex. - * - * @param source the source vertex - */ - public void setSource(@NonNull final StandardVertex source) { - this.source = Objects.requireNonNull(source); - } - - /** - * Get the destination vertex. - * - * @return the destination vertex - */ - @NonNull - public ModelVertex getDestination() { - return destination; - } - - /** - * Set the destination vertex. - * - * @param destination the destination vertex - */ - public void setDestination(@NonNull final StandardVertex destination) { - this.destination = Objects.requireNonNull(destination); - } - - /** - * Get the label of the edge. - * - * @return the label of the edge - */ - @NonNull - public String getLabel() { - return label; - } - - /** - * Get whether or not the insertion of this edge may block until capacity is available. - * - * @return true if the insertion of this edge may block until capacity is available - */ - public boolean isInsertionIsBlocking() { - return insertionIsBlocking; - } - - @Override - public boolean equals(@Nullable final Object obj) { - if (obj instanceof final ModelEdge that) { - return this.source.equals(that.source) - && this.destination.equals(that.destination) - && this.label.equals(that.label); - } - return false; - } - - @Override - public int hashCode() { - return hash32(source.hashCode(), destination.hashCode(), label.hashCode()); - } - - /** - * Useful for looking at a model in a debugger. - */ - @Override - public String toString() { - return source + " --" + label + "-->" + (insertionIsBlocking ? "" : ">") + " " + destination; - } - - /** - * Sorts first by source, then by destination, then by label. - */ - @Override - public int compareTo(@NonNull final ModelEdge that) { - if (!this.source.equals(that.source)) { - return this.source.compareTo(that.source); - } - if (!this.destination.equals(that.destination)) { - return this.destination.compareTo(that.destination); - } - return this.label.compareTo(that.label); - } - - /** - * Get the character for the outgoing end of this edge. - */ - @NonNull - private String getArrowCharacter() { - if (manual) { - return "o"; - } else { - return ">"; - } - } - - /** - * Render this edge to a string builder. - * - * @param sb the string builder to render to - * @param nameProvider provides short names for vertices - */ - public void render(@NonNull final StringBuilder sb, @NonNull final MermaidNameShortener nameProvider) { - - final String sourceName = nameProvider.getShortVertexName(source.getName()); - sb.append(sourceName).append(" "); - - if (insertionIsBlocking) { - if (label.isEmpty()) { - sb.append("--"); - } else { - sb.append("-- \"").append(label).append("\" --"); - } - } else { - if (label.isEmpty()) { - sb.append("-.-"); - } else { - sb.append("-. \"").append(label).append("\" .-"); - } - } - - sb.append(getArrowCharacter()).append(" "); - - final String destinationName = nameProvider.getShortVertexName(destination.getName()); - sb.append(destinationName).append("\n"); - } -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/ModelVertex.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/ModelVertex.java deleted file mode 100644 index d22d55ce2bb..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/ModelVertex.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.model.internal.analysis; - -import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import java.util.Set; - -/** - * A vertex in a wiring model. - */ -public interface ModelVertex extends Comparable { - - /** - * Get the name of the vertex. - * - * @return the name - */ - @NonNull - String getName(); - - /** - * Get the type of task scheduler that corresponds to this vertex, or null if this vertex does not correspond to a - * task scheduler. - * - * @return the type of task scheduler that corresponds to this vertex, or null if this vertex does not correspond to - * a task scheduler - */ - @NonNull - TaskSchedulerType getType(); - - /** - * Get the hyperlink to the documentation for this vertex, or null if there is no documentation. - * - * @return the hyperlink to the documentation for this vertex, or null if there is no documentation - */ - @Nullable - String getHyperlink(); - - /** - * Get whether the insertion of this vertex may block until capacity is available. - * - * @return true if the insertion of this vertex may block until capacity is available - */ - boolean isInsertionIsBlocking(); - - /** - * Get the outgoing edges of this vertex. - * - * @return the outgoing edges of this vertex - */ - @NonNull - Set getOutgoingEdges(); - - /** - * Get substituted inputs for this vertex. - */ - @NonNull - Set getSubstitutedInputs(); - - /** - * Render this vertex in mermaid format. Used when generating a wiring diagram. - * - * @param sb the string builder to render to - * @param nameProvider provides short names for vertices - * @param styleManager manages the styles of vertices - */ - void render( - @NonNull final StringBuilder sb, - @NonNull final MermaidNameShortener nameProvider, - @NonNull final MermaidStyleManager styleManager); - - /** - * Sorts by name. - */ - default int compareTo(@NonNull final ModelVertex that) { - return this.getName().compareTo(that.getName()); - } - - /** - * Set the depth of this vertex in the wiring diagram. Depth increases by 1 for every group that this vertex is - * nested within. - * - * @param depth the depth of this vertex in the wiring diagram - */ - void setDepth(int depth); -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/ModelVertexMetaType.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/ModelVertexMetaType.java deleted file mode 100644 index 914291fb82e..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/ModelVertexMetaType.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.model.internal.analysis; - -/** - * The type of a vertex in a wiring flowchart. Although the original graph will be constructed of SCHEDULER vertices - * alone, when generating the flowchart, verticies will be added, removed and combined. New verticies that do not - * directly correspond to a scheduler will be of type SUBSTITUTION or GROUP. - */ -public enum ModelVertexMetaType { - /** - * A vertex that corresponds to a scheduler. - */ - SCHEDULER, - /** - * A vertex that is used as a stand-in for a substituted edge. - */ - SUBSTITUTION, - /** - * A vertex that is used as a stand-in for a group of vertices. - */ - GROUP -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/StandardVertex.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/StandardVertex.java deleted file mode 100644 index c8c58940ee3..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/StandardVertex.java +++ /dev/null @@ -1,267 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.model.internal.analysis; - -import static org.hiero.wiring.framework.model.internal.analysis.WiringFlowchart.DIRECT_SCHEDULER_COLOR; -import static org.hiero.wiring.framework.model.internal.analysis.WiringFlowchart.GROUP_COLOR; -import static org.hiero.wiring.framework.model.internal.analysis.WiringFlowchart.SCHEDULER_COLOR; -import static org.hiero.wiring.framework.model.internal.analysis.WiringFlowchart.SUBSTITUTION_COLOR; -import static org.hiero.wiring.framework.model.internal.analysis.WiringFlowchart.TEXT_COLOR; - -import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import java.util.HashSet; -import java.util.Objects; -import java.util.Set; - -/** - * A standard vertex in a wiring model. Does not contain sub-vertices. - */ -public class StandardVertex implements ModelVertex { - - /** - * The name of the vertex. - */ - private final String name; - - /** - * When tasks are inserted into this vertex, is this component capable of applying back pressure? - */ - private final boolean insertionIsBlocking; - - /** - * The task scheduler type that corresponds to this vertex. - */ - private final TaskSchedulerType type; - - /** - * The meta-type of this vertex. Used by the wiring diagram, ignored by other use cases. - */ - private final ModelVertexMetaType metaType; - - /** - * The outgoing edges of this vertex. - */ - private final Set outgoingEdges = new HashSet<>(); - - /** - * Used to track inputs that have been substituted during diagram generation. - */ - private final Set substitutedInputs = new HashSet<>(); - - /** - * The link to the documentation for this vertex. If null, no hyperlink will be generated. - */ - private final String hyperlink; - - /** - * Constructor. - * - * @param name the name of the vertex - * @param type the type of task scheduler that corresponds to this vertex - * @param metaType the meta-type of this vertex, used to generate a wiring diagram - * @param hyperlink the link to the documentation for this vertex, ignored if null - * @param insertionIsBlocking true if the insertion of this vertex may block until capacity is available - */ - public StandardVertex( - @NonNull final String name, - @NonNull final TaskSchedulerType type, - @NonNull final ModelVertexMetaType metaType, - @Nullable final String hyperlink, - final boolean insertionIsBlocking) { - this.name = Objects.requireNonNull(name); - this.type = Objects.requireNonNull(type); - this.metaType = Objects.requireNonNull(metaType); - this.hyperlink = hyperlink; - this.insertionIsBlocking = insertionIsBlocking; - } - - /** - * {@inheritDoc} - */ - @NonNull - @Override - public String getName() { - return name; - } - - /** - * {@inheritDoc} - */ - @NonNull - @Override - public TaskSchedulerType getType() { - return type; - } - - /** - * {@inheritDoc} - */ - @Nullable - @Override - public String getHyperlink() { - return hyperlink; - } - - /** - * {@inheritDoc} - */ - @Override - public boolean isInsertionIsBlocking() { - return insertionIsBlocking; - } - - /** - * {@inheritDoc} - */ - @NonNull - @Override - public Set getOutgoingEdges() { - return outgoingEdges; - } - - /** - * {@inheritDoc} - */ - @NonNull - @Override - public Set getSubstitutedInputs() { - return substitutedInputs; - } - - /** - * {@inheritDoc} - */ - @Override - public int hashCode() { - return name.hashCode(); - } - - /** - * {@inheritDoc} - */ - @Override - public boolean equals(@Nullable final Object obj) { - if (obj instanceof final StandardVertex that) { - return name.equals(that.name); - } - return false; - } - - /** - * Makes the vertex nicer to look at in a debugger. - */ - @Override - public String toString() { - if (insertionIsBlocking) { - return "[" + name + "]"; - } else { - return "(" + name + ")"; - } - } - - /** - * Generate the style for this vertex. - * - * @return the style for this vertex - */ - @NonNull - private String generateStyle() { - final String color = - switch (metaType) { - case SUBSTITUTION -> SUBSTITUTION_COLOR; - case GROUP -> GROUP_COLOR; - case SCHEDULER -> switch (type) { - case DIRECT -> DIRECT_SCHEDULER_COLOR; - case DIRECT_THREADSAFE -> DIRECT_SCHEDULER_COLOR; - default -> SCHEDULER_COLOR; - }; - }; - - final StringBuilder sb = new StringBuilder(); - sb.append("fill:#").append(color).append(",stroke:#").append(TEXT_COLOR).append(",stroke-width:2px"); - - return sb.toString(); - } - - /** - * {@inheritDoc} - */ - @Override - public void render( - @NonNull final StringBuilder sb, - @NonNull final MermaidNameShortener nameProvider, - @NonNull final MermaidStyleManager styleManager) { - final String shortenedName = nameProvider.getShortVertexName(name); - sb.append(shortenedName); - - switch (metaType) { - case SUBSTITUTION -> sb.append("(("); - case GROUP -> sb.append("["); - case SCHEDULER -> { - switch (type) { - case CONCURRENT -> sb.append("[["); - case DIRECT -> sb.append("[/"); - case DIRECT_THREADSAFE -> sb.append("{{"); - default -> sb.append("["); - } - } - } - - sb.append("\""); - if (hyperlink != null) { - sb.append(""); - } - sb.append(name); - if (hyperlink != null) { - sb.append(""); - } - - if (!substitutedInputs.isEmpty()) { - sb.append("
    "); - substitutedInputs.stream().sorted().forEachOrdered(sb::append); - } - - sb.append("\""); - - switch (metaType) { - case SUBSTITUTION -> sb.append("))"); - case GROUP -> sb.append("]"); - case SCHEDULER -> { - switch (type) { - case CONCURRENT -> sb.append("]]"); - case DIRECT -> sb.append("/]"); - case DIRECT_THREADSAFE -> sb.append("}}"); - default -> sb.append("]"); - } - } - } - - sb.append("\n"); - - styleManager.registerStyle(shortenedName, generateStyle()); - } - - /** - * {@inheritDoc} - */ - @Override - public void setDepth(final int depth) { - // ignored - } -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/WiringFlowchart.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/WiringFlowchart.java deleted file mode 100644 index a666b8ed475..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/analysis/WiringFlowchart.java +++ /dev/null @@ -1,425 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.model.internal.analysis; - -import static org.hiero.wiring.framework.model.internal.analysis.ModelVertexMetaType.SCHEDULER; -import static org.hiero.wiring.framework.model.internal.analysis.ModelVertexMetaType.SUBSTITUTION; -import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.CONCURRENT; -import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.DIRECT; -import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.DIRECT_THREADSAFE; -import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.SEQUENTIAL; -import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.SEQUENTIAL_THREAD; - -import org.hiero.wiring.framework.model.diagram.ModelEdgeSubstitution; -import org.hiero.wiring.framework.model.diagram.ModelGroup; -import org.hiero.wiring.framework.model.diagram.ModelManualLink; -import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Set; - -/** - * A readable wiring flowchart. - */ -public class WiringFlowchart { - - public static final String SCHEDULER_COLOR = "135f12"; - public static final String DIRECT_SCHEDULER_COLOR = "12305f"; - public static final String TEXT_COLOR = "000"; - public static final String GROUP_COLOR = "9cf"; - public static final String SUBSTITUTION_COLOR = "5f1212"; - - private final MermaidNameShortener nameProvider = new MermaidNameShortener(); - private final MermaidStyleManager styleManager = new MermaidStyleManager(); - - /** - * A map from vertex name to vertex. - */ - private final Map vertexMap; - - /** - * Draws a mermaid flowchart from the given wiring model. - * - * @param modelVertexMap a map from vertex name to vertex - * @param substitutions a list of edge substitutions to perform - * @param groups a list of groups to create - * @param manualLinks a list of manual links to draw - */ - public WiringFlowchart( - @NonNull final Map modelVertexMap, - @NonNull final List substitutions, - @NonNull final List groups, - @NonNull final List manualLinks) { - - Objects.requireNonNull(modelVertexMap); - - vertexMap = copyVertexMap(modelVertexMap); - addManualLinks(manualLinks); - substituteEdges(substitutions); - handleGroups(groups); - } - - /** - * Do a deep copy of the vertex map. Allows the local copy to be modified without affecting the original. - * - * @return a deep copy of the vertex map - */ - @NonNull - private Map copyVertexMap(@NonNull final Map original) { - final Map copy = new HashMap<>(); - - // First, copy the vertices without copying the edges. - // We should only encounter StandardVertex instances here. - for (final ModelVertex vertex : original.values()) { - if (!(vertex instanceof StandardVertex)) { - throw new IllegalStateException("Encountered a vertex that is not a StandardVertex"); - } - final StandardVertex vertexCopy = new StandardVertex( - vertex.getName(), - vertex.getType(), - SCHEDULER, - vertex.getHyperlink(), - vertex.isInsertionIsBlocking()); - - copy.put(vertex.getName(), vertexCopy); - } - - // Next, copy the edges. - for (final ModelVertex vertex : original.values()) { - for (final ModelEdge edge : vertex.getOutgoingEdges()) { - - final ModelVertex source = copy.get(edge.getSource().getName()); - final ModelVertex destination = copy.get(edge.getDestination().getName()); - - final ModelEdge edgeCopy = - new ModelEdge(source, destination, edge.getLabel(), edge.isInsertionIsBlocking(), false); - - source.getOutgoingEdges().add(edgeCopy); - } - } - - return copy; - } - - /** - * Add manual links to the flowchart. - * - * @param manualLinks the manual links to add - */ - private void addManualLinks(@NonNull final List manualLinks) { - for (final ModelManualLink link : manualLinks) { - final ModelVertex source = vertexMap.get(link.source()); - final ModelVertex destination = vertexMap.get(link.target()); - - if (source == null) { - throw new IllegalStateException("Source vertex " + link.source() + " does not exist."); - } - - if (destination == null) { - throw new IllegalStateException("Destination vertex " + link.target() + " does not exist."); - } - - final ModelEdge edge = new ModelEdge(source, destination, link.label(), false, true); - source.getOutgoingEdges().add(edge); - } - } - - /** - * Find all edges that need to be substituted and perform the substitution. - */ - private void substituteEdges(@NonNull final List substitutions) { - for (final ModelEdgeSubstitution substitution : substitutions) { - substituteEdge(substitution); - } - } - - /** - * Perform a single edge substitution. - */ - private void substituteEdge(@NonNull final ModelEdgeSubstitution substitution) { - // First, create a new vertex that will represent the destination of the substitution. - final StandardVertex substitutedVertex = - new StandardVertex(substitution.substitution(), DIRECT, SUBSTITUTION, null, true); - vertexMap.put(substitution.substitution(), substitutedVertex); - - // Next, cause all substituted edges to point to this new vertex. - for (final ModelVertex vertex : vertexMap.values()) { - if (!substitution.source().equals(vertex.getName())) { - // Only replace edges with the given source. - continue; - } - - final HashSet uniqueEdges = new HashSet<>(); - - for (final ModelEdge edge : vertex.getOutgoingEdges()) { - if (!substitution.edge().equals(edge.getLabel())) { - // Only replace destinations for edges with the given label. - uniqueEdges.add(edge); - continue; - } - - edge.getDestination().getSubstitutedInputs().add(substitution.substitution()); - edge.setDestination(substitutedVertex); - uniqueEdges.add(edge); - } - - vertex.getOutgoingEdges().clear(); - vertex.getOutgoingEdges().addAll(uniqueEdges); - } - } - - /** - * Handle groups in the order provided. - */ - private void handleGroups(@NonNull final List groups) { - for (final ModelGroup group : groups) { - final GroupVertex groupVertex = createGroup(group); - if (group.collapse()) { - collapseGroup(groupVertex); - } - } - } - - /** - * Collect all vertices that are contained within the given group and create a new vertex that represents the - * group. - * - * @param group the group to create a vertex for - * @return the new vertex - */ - private GroupVertex createGroup(@NonNull final ModelGroup group) { - // Collect all vertices that are contained within the group. - final List subVertices = new ArrayList<>(); - - for (final String vertexName : group.elements()) { - final ModelVertex subVertex = vertexMap.get(vertexName); - if (subVertex == null) { - throw new IllegalStateException("Vertex " + vertexName - + " is not in the vertex map. Can not insert into group " + group.name() + "."); - } - - subVertices.add(subVertex); - } - - // Remove those vertices from the vertex map. - for (final ModelVertex subVertex : subVertices) { - vertexMap.remove(subVertex.getName()); - } - - // Create a new vertex that represents the group. - final GroupVertex groupVertex = new GroupVertex(group.name(), subVertices); - vertexMap.put(group.name(), groupVertex); - - return groupVertex; - } - - /** - * Collapse a group of vertices into a single vertex. - * - * @param group the group to collapse - */ - private void collapseGroup(@NonNull final GroupVertex group) { - final List edges = collectEdges(); - final List groupVertices = collectGroupVertices(group); - - final Set hyperlinks = new HashSet<>(); - for (final ModelVertex vertex : groupVertices) { - if (vertex.getHyperlink() != null) { - hyperlinks.add(vertex.getHyperlink()); - } - } - final String hyperlink = hyperlinks.size() == 1 ? hyperlinks.iterator().next() : null; - - final TaskSchedulerType schedulerType = getSchedulerTypeOfCollapsedGroup(groupVertices); - - final StandardVertex newVertex = new StandardVertex(group.getName(), schedulerType, SCHEDULER, hyperlink, true); - - // Assign all vertices with a source that is collapsed to the new vertex. - // Redirect all vertices with a destination that is collapsed to the new vertex. - for (final ModelEdge edge : edges) { - final boolean collapsedSource = groupVertices.contains(edge.getSource()); - final boolean collapsedDestination = groupVertices.contains(edge.getDestination()); - - if (collapsedSource && collapsedDestination) { - // If the source and or destination are collapsed, then the edge is removed. - continue; - } - - if (collapsedSource) { - edge.setSource(newVertex); - newVertex.getOutgoingEdges().add(edge); - } - - if (collapsedDestination) { - // Add and remove from set to avoid possible duplicates. - edge.getSource().getOutgoingEdges().remove(edge); - edge.setDestination(newVertex); - edge.getSource().getOutgoingEdges().add(edge); - } - } - - // Extract substitutions from collapsed vertices. - for (final ModelVertex vertex : groupVertices) { - for (final String input : vertex.getSubstitutedInputs()) { - newVertex.getSubstitutedInputs().add(input); - } - } - - // Remove old vertices from the vertex map. - for (final ModelVertex vertex : groupVertices) { - vertexMap.remove(vertex.getName()); - } - - // Finally, add the new vertex to the vertex map. - vertexMap.put(newVertex.getName(), newVertex); - } - - /** - * When collapsing a group, determine the type of task scheduler type that should be displayed. - */ - @NonNull - private TaskSchedulerType getSchedulerTypeOfCollapsedGroup(@NonNull final List groupVertices) { - - boolean hasSequential = false; - boolean hasState = false; - - for (final ModelVertex vertex : groupVertices) { - if (vertex.getType() == CONCURRENT) { - return CONCURRENT; - } - - if (vertex.getType() == SEQUENTIAL || vertex.getType() == SEQUENTIAL_THREAD) { - if (hasSequential) { - // We've detected more than one sequential scheduler type, so there is more than one logical - // thread of execution within this group. - return CONCURRENT; - } - hasSequential = true; - } - - if (vertex.getType() == DIRECT) { - hasState = true; - } - } - - if (hasSequential) { - return SEQUENTIAL; - } else { - if (hasState) { - return DIRECT; - } - return DIRECT_THREADSAFE; - } - } - - /** - * Get all edges in the flowchart. - * - * @return all edges in the flowchart, sorted - */ - private List collectGroupVertices(@NonNull final GroupVertex group) { - final List vertices = new ArrayList<>(); - final LinkedList stack = new LinkedList<>(); - stack.addLast(group); - - while (!stack.isEmpty()) { - final ModelVertex vertex = stack.removeLast(); - vertices.add(vertex); - if (vertex instanceof final GroupVertex groupVertex) { - for (final ModelVertex subVertex : groupVertex.getSubVertices()) { - stack.addLast(subVertex); - } - } - } - - Collections.sort(vertices); - return vertices; - } - - /** - * Get all edges in the flowchart. - * - * @return all edges in the flowchart, sorted - */ - private List collectEdges() { - final List edges = new ArrayList<>(); - final LinkedList stack = new LinkedList<>(); - - for (final ModelVertex vertex : vertexMap.values()) { - stack.addLast(vertex); - } - - while (!stack.isEmpty()) { - final ModelVertex vertex = stack.removeLast(); - edges.addAll(vertex.getOutgoingEdges()); - if (vertex instanceof final GroupVertex groupVertex) { - for (final ModelVertex subVertex : groupVertex.getSubVertices()) { - stack.addLast(subVertex); - } - } - } - - Collections.sort(edges); - return edges; - } - - /** - * Render the flowchart to a string. - * - * @return the rendered flowchart - */ - @NonNull - public String render() { - final StringBuilder sb = new StringBuilder(); - sb.append( - """ - %%{ - init: { - 'flowchart': {'defaultRenderer': 'elk'}, - 'theme': 'base', - 'themeVariables': { - 'primaryColor': '#454545', - 'primaryTextColor': '#EEEEEE', - 'lineColor': '#C0C0C0' - } - } - }%% - flowchart TD - """); - - final List sortedVertices = - vertexMap.values().stream().sorted().toList(); - for (final ModelVertex vertex : sortedVertices) { - vertex.render(sb, nameProvider, styleManager); - } - - for (final ModelEdge edge : collectEdges()) { - edge.render(sb, nameProvider); - } - - styleManager.render(sb); - - return sb.toString(); - } -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/deterministic/DeterministicHeartbeatScheduler.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/deterministic/DeterministicHeartbeatScheduler.java deleted file mode 100644 index ea71712d431..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/deterministic/DeterministicHeartbeatScheduler.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (C) 2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.model.internal.deterministic; - -import static com.swirlds.common.utility.CompareTo.isGreaterThanOrEqualTo; - -import com.swirlds.base.time.Time; -import org.hiero.wiring.framework.model.TraceableWiringModel; -import org.hiero.wiring.framework.model.internal.standard.AbstractHeartbeatScheduler; -import org.hiero.wiring.framework.model.internal.standard.HeartbeatTask; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.time.Duration; -import java.time.Instant; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -/** - * A deterministic implementation of a heartbeat scheduler. - */ -public class DeterministicHeartbeatScheduler extends AbstractHeartbeatScheduler { - - /** - * This maps from the period of the heartbeat to the list of heartbeats that want to be notified with that period. - */ - private final Map> heartbeatsByPeriod = new HashMap<>(); - - /** - * The timestamps of the previous heartbeats sent for each group of heartbeats that subscribe to the same period. - */ - private final Map previousHeartbeats = new HashMap<>(); - - /** - * Constructor. - * - * @param model the wiring model containing this heartbeat scheduler - * @param time provides wall clock time - * @param name the name of the heartbeat scheduler - */ - public DeterministicHeartbeatScheduler( - @NonNull final TraceableWiringModel model, @NonNull final Time time, @NonNull final String name) { - super(model, time, name); - } - - /** - * Send out heartbeats based on the amount of time that has passed. - */ - public void tick() { - if (!started) { - throw new IllegalStateException("Cannot tick the heartbeat before it has started"); - } - - final Instant currentTime = time.now(); - - for (final Entry> entry : heartbeatsByPeriod.entrySet()) { - final Duration period = entry.getKey(); - final List tasksForPeriod = entry.getValue(); - final Instant previousHeartbeat = previousHeartbeats.get(period); - final Duration timeSinceLastHeartbeat = Duration.between(previousHeartbeat, currentTime); - if (isGreaterThanOrEqualTo(timeSinceLastHeartbeat, period)) { - for (final HeartbeatTask task : tasksForPeriod) { - task.run(); - } - previousHeartbeats.put(period, currentTime); - } - } - } - - /** - * {@inheritDoc} - */ - @Override - public void start() { - if (started) { - throw new IllegalStateException("Cannot start the heartbeat more than once"); - } - - final Instant currentTime = time.now(); - for (final HeartbeatTask task : tasks) { - final List tasksForPeriod = - heartbeatsByPeriod.computeIfAbsent(task.getPeriod(), k -> new ArrayList<>()); - tasksForPeriod.add(task); - previousHeartbeats.put(task.getPeriod(), currentTime); - } - - started = true; - } - - @Override - public void stop() { - if (!started) { - throw new IllegalStateException("Cannot stop the heartbeat before it has started"); - } - } -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/deterministic/DeterministicTaskScheduler.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/deterministic/DeterministicTaskScheduler.java deleted file mode 100644 index 87894c04bd0..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/deterministic/DeterministicTaskScheduler.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (C) 2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.model.internal.deterministic; - -import org.hiero.wiring.framework.counters.ObjectCounter; -import org.hiero.wiring.framework.model.TraceableWiringModel; -import org.hiero.wiring.framework.schedulers.TaskScheduler; -import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.Objects; -import java.util.function.Consumer; - -/** - * A deterministic implementation of a task scheduler. - * - * @param the output type of the scheduler (use {@link Void} for a task scheduler with no output type) - */ -public class DeterministicTaskScheduler extends TaskScheduler { - - private final Consumer submitWork; - - private final ObjectCounter onRamp; - private final ObjectCounter offRamp; - private final long capacity; - - /** - * Constructor. - * - * @param model the wiring model containing this task scheduler - * @param name the name of the task scheduler - * @param type the type of task scheduler - * @param onRamp counts when things are added to this scheduler to be eventually handled - * @param offRamp counts when things are handled by this scheduler - * @param capacity the maximum desired capacity for this task scheduler - * @param flushEnabled if true, then {@link #flush()} will be enabled, otherwise it will throw. - * @param squelchingEnabled if true, then squelching will be enabled, otherwise trying to squelch will throw. - * @param insertionIsBlocking when data is inserted into this task scheduler, will it block until capacity is - * available? - * @param submitWork a method where all work should be submitted - */ - protected DeterministicTaskScheduler( - @NonNull final TraceableWiringModel model, - @NonNull final String name, - @NonNull final TaskSchedulerType type, - @NonNull final ObjectCounter onRamp, - @NonNull final ObjectCounter offRamp, - final long capacity, - final boolean flushEnabled, - final boolean squelchingEnabled, - final boolean insertionIsBlocking, - @NonNull final Consumer submitWork) { - super(model, name, type, flushEnabled, squelchingEnabled, insertionIsBlocking); - - this.onRamp = Objects.requireNonNull(onRamp); - this.offRamp = Objects.requireNonNull(offRamp); - this.submitWork = Objects.requireNonNull(submitWork); - this.capacity = capacity; - } - - /** - * {@inheritDoc} - */ - @Override - public long getUnprocessedTaskCount() { - return onRamp.getCount(); - } - - /** - * {@inheritDoc} - */ - @Override - public long getCapacity() { - return capacity; - } - - /** - * {@inheritDoc} - */ - @Override - public void flush() { - // Future work: flushing is incompatible with deterministic task schedulers. - // This is because flushing currently requires us to block thread A while - // thread B does work, but with turtle there is only a single thread. - } - - /** - * {@inheritDoc} - */ - @Override - protected void put(@NonNull final Consumer handler, @NonNull final Object data) { - onRamp.onRamp(); - submitWork.accept(() -> { - handler.accept(data); - offRamp.offRamp(); - }); - } - - /** - * {@inheritDoc} - */ - @Override - protected boolean offer(@NonNull final Consumer handler, @NonNull final Object data) { - if (onRamp.attemptOnRamp()) { - submitWork.accept(() -> { - handler.accept(data); - offRamp.offRamp(); - }); - return true; - } - return false; - } - - /** - * {@inheritDoc} - */ - @Override - protected void inject(@NonNull final Consumer handler, @NonNull final Object data) { - onRamp.forceOnRamp(); - submitWork.accept(() -> { - handler.accept(data); - offRamp.offRamp(); - }); - } -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/deterministic/DeterministicTaskSchedulerBuilder.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/deterministic/DeterministicTaskSchedulerBuilder.java deleted file mode 100644 index 58d151c56e4..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/deterministic/DeterministicTaskSchedulerBuilder.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (C) 2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.model.internal.deterministic; - -import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.DIRECT_THREADSAFE; -import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.NO_OP; - -import com.swirlds.common.context.PlatformContext; -import com.swirlds.common.metrics.extensions.FractionalTimer; -import com.swirlds.common.metrics.extensions.NoOpFractionalTimer; -import org.hiero.wiring.framework.model.DeterministicWiringModel; -import org.hiero.wiring.framework.model.TraceableWiringModel; -import org.hiero.wiring.framework.schedulers.TaskScheduler; -import org.hiero.wiring.framework.schedulers.builders.internal.AbstractTaskSchedulerBuilder; -import org.hiero.wiring.framework.schedulers.internal.DirectTaskScheduler; -import org.hiero.wiring.framework.schedulers.internal.NoOpTaskScheduler; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.Objects; -import java.util.concurrent.ForkJoinPool; -import java.util.function.Consumer; - -/** - * Builds schedulers for a {@link DeterministicWiringModel}. - * - * @param - */ -public class DeterministicTaskSchedulerBuilder extends AbstractTaskSchedulerBuilder { - - private final Consumer submitWork; - - /** - * Constructor. - * - * @param platformContext the platform context - * @param model the wiring model - * @param name the name of the task scheduler. Used for metrics and debugging. Must be unique. Must only - * contain alphanumeric characters and underscores. - * @param submitWork a method where all work should be submitted - */ - public DeterministicTaskSchedulerBuilder( - @NonNull final PlatformContext platformContext, - @NonNull final TraceableWiringModel model, - @NonNull final String name, - @NonNull final Consumer submitWork) { - super(platformContext, model, name, ForkJoinPool.commonPool()); - this.submitWork = Objects.requireNonNull(submitWork); - } - - /** - * {@inheritDoc} - */ - @NonNull - @Override - public TaskScheduler build() { - - final boolean insertionIsBlocking = unhandledTaskCapacity != UNLIMITED_CAPACITY || externalBackPressure; - - final Counters counters = buildCounters(); - final FractionalTimer busyFractionTimer = NoOpFractionalTimer.getInstance(); - - final TaskScheduler scheduler = - switch (type) { - case CONCURRENT, SEQUENTIAL, SEQUENTIAL_THREAD -> new DeterministicTaskScheduler<>( - model, - name, - type, - counters.onRamp(), - counters.offRamp(), - unhandledTaskCapacity, - flushingEnabled, - squelchingEnabled, - insertionIsBlocking, - submitWork); - case DIRECT, DIRECT_THREADSAFE -> new DirectTaskScheduler<>( - model, - name, - buildUncaughtExceptionHandler(), - counters.onRamp(), - counters.offRamp(), - squelchingEnabled, - busyFractionTimer, - type == DIRECT_THREADSAFE); - case NO_OP -> new NoOpTaskScheduler<>(model, name, type, flushingEnabled, squelchingEnabled); - }; - - if (type != NO_OP) { - model.registerScheduler(scheduler, hyperlink); - } - - return scheduler; - } -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/monitor/HealthMonitor.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/monitor/HealthMonitor.java deleted file mode 100644 index a91921b317d..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/monitor/HealthMonitor.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (C) 2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.model.internal.monitor; - -import static com.swirlds.common.utility.CompareTo.isGreaterThan; - -import com.swirlds.common.context.PlatformContext; -import org.hiero.wiring.framework.schedulers.TaskScheduler; -import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerBuilder; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import java.time.Duration; -import java.time.Instant; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.concurrent.atomic.AtomicReference; - -/** - * Monitors the health of a wiring model. A healthy wiring model is a model without too much work backed up in queues. - * An unhealthy wiring model is a model with at least one queue that is backed up with too much work. - */ -public class HealthMonitor { - - /** - * A list of task schedulers without unlimited capacities. - */ - private final List> schedulers; - - /** - * Corresponds to the schedulers list. The instant at the index of a scheduler indicates the last timestamp at which - * that scheduler was observed to be in a healthy state. - */ - private final List lastHealthyTimes = new ArrayList<>(); - - /** - * The previous value returned by {@link #checkSystemHealth(Instant)}. Used to avoid sending repeat output. - */ - private Duration previouslyReportedDuration = Duration.ZERO; - - /** - * Metrics for the health monitor. - */ - private final HealthMonitorMetrics metrics; - - /** - * Logs health issues. - */ - private final HealthMonitorLogger logger; - - /** - * The longest duration that any single scheduler has been concurrently unhealthy. - */ - private final AtomicReference longestUnhealthyDuration = new AtomicReference<>(Duration.ZERO); - - /** - * Constructor. - * - * @param platformContext the platform context - * @param schedulers the task schedulers to monitor - * @param healthLogThreshold the amount of time that must pass before we start logging health information - * @param healthLogPeriod the period at which we log health information - */ - public HealthMonitor( - @NonNull final PlatformContext platformContext, - @NonNull final List> schedulers, - @NonNull final Duration healthLogThreshold, - @NonNull final Duration healthLogPeriod) { - - metrics = new HealthMonitorMetrics(platformContext, healthLogThreshold); - - this.schedulers = new ArrayList<>(); - for (final TaskScheduler scheduler : schedulers) { - if (scheduler.getCapacity() != TaskSchedulerBuilder.UNLIMITED_CAPACITY) { - this.schedulers.add(Objects.requireNonNull(scheduler)); - lastHealthyTimes.add(null); - } - } - - logger = new HealthMonitorLogger(platformContext, this.schedulers, healthLogThreshold, healthLogPeriod); - } - - /** - * Called periodically. Scans the task schedulers for health issues. - * - * @param now the current time - * @return the amount of time any single scheduler has been concurrently unhealthy. Returns {@link Duration#ZERO} if - * all schedulers are healthy, returns null if there is no change in health status. - */ - @Nullable - public Duration checkSystemHealth(@NonNull final Instant now) { - Duration longestUnhealthyDuration = Duration.ZERO; - - for (int i = 0; i < lastHealthyTimes.size(); i++) { - final TaskScheduler scheduler = schedulers.get(i); - final boolean healthy = scheduler.getUnprocessedTaskCount() <= scheduler.getCapacity(); - if (healthy) { - lastHealthyTimes.set(i, null); - } else { - if (lastHealthyTimes.get(i) == null) { - lastHealthyTimes.set(i, now); - } - - final Duration unhealthyDuration = Duration.between(lastHealthyTimes.get(i), now); - logger.reportUnhealthyScheduler(scheduler, unhealthyDuration); - if (isGreaterThan(unhealthyDuration, longestUnhealthyDuration)) { - longestUnhealthyDuration = unhealthyDuration; - } - } - } - - try { - if (longestUnhealthyDuration.equals(previouslyReportedDuration)) { - // Only report when there is a change in health status - return null; - } else { - this.longestUnhealthyDuration.set(longestUnhealthyDuration); - metrics.reportUnhealthyDuration(longestUnhealthyDuration); - return longestUnhealthyDuration; - } - } finally { - previouslyReportedDuration = longestUnhealthyDuration; - } - } - - /** - * Get the duration that any particular scheduler has been concurrently unhealthy. - * - * @return the duration that any particular scheduler has been concurrently unhealthy, or {@link Duration#ZERO} if - * no scheduler is currently unhealthy - */ - @NonNull - public Duration getUnhealthyDuration() { - return longestUnhealthyDuration.get(); - } -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/monitor/HealthMonitorLogger.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/monitor/HealthMonitorLogger.java deleted file mode 100644 index bec6ad95aec..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/monitor/HealthMonitorLogger.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (C) 2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.model.internal.monitor; - -import static com.swirlds.common.units.TimeUnit.UNIT_NANOSECONDS; -import static com.swirlds.logging.legacy.LogMarker.STARTUP; - -import com.swirlds.common.context.PlatformContext; -import com.swirlds.common.utility.CompareTo; -import com.swirlds.common.utility.throttle.RateLimitedLogger; -import org.hiero.wiring.framework.schedulers.TaskScheduler; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.time.Duration; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -/** - * Encapsulates logging for the wiring health monitor. - */ -public class HealthMonitorLogger { - - private static final Logger logger = LogManager.getLogger(HealthMonitorLogger.class); - - /** - * The amount of time that must pass before we start logging health information. - */ - private final Duration healthLogThreshold; - - /** - * A rate limited logger for each scheduler. - */ - private final Map schedulerLoggers = new HashMap<>(); - - /** - * Constructor. - * - * @param platformContext the platform context - * @param schedulers the task schedulers being monitored - * @param healthLogThreshold the amount of time that must pass before we start logging health information - * @param healthLogPeriod the period at which we log health information - */ - public HealthMonitorLogger( - @NonNull final PlatformContext platformContext, - @NonNull final List> schedulers, - @NonNull final Duration healthLogThreshold, - @NonNull final Duration healthLogPeriod) { - - this.healthLogThreshold = healthLogThreshold; - for (final TaskScheduler scheduler : schedulers) { - final String schedulerName = scheduler.getName(); - final RateLimitedLogger rateLimitedLogger = - new RateLimitedLogger(logger, platformContext.getTime(), healthLogPeriod); - schedulerLoggers.put(schedulerName, rateLimitedLogger); - } - } - - /** - * Report an unhealthy scheduler. - * - * @param scheduler the unhealthy scheduler - * @param unhealthyDuration the duration for which the scheduler has been unhealthy - */ - public void reportUnhealthyScheduler( - @NonNull final TaskScheduler scheduler, @NonNull final Duration unhealthyDuration) { - if (CompareTo.isLessThan(unhealthyDuration, healthLogThreshold)) { - // Don't log about small unhealthy durations - return; - } - - final RateLimitedLogger rateLimitedLogger = schedulerLoggers.get(scheduler.getName()); - final String formattedDuration = - UNIT_NANOSECONDS.buildFormatter(unhealthyDuration.toNanos()).render(); - rateLimitedLogger.warn( - STARTUP.getMarker(), - "Task scheduler {} has been unhealthy for {}. It currently has {}/{} unhandled tasks.", - scheduler.getName(), - formattedDuration, - scheduler.getUnprocessedTaskCount(), - scheduler.getCapacity()); - } -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/monitor/HealthMonitorMetrics.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/monitor/HealthMonitorMetrics.java deleted file mode 100644 index 430417d70e2..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/monitor/HealthMonitorMetrics.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.model.internal.monitor; - -import static com.swirlds.common.utility.CompareTo.isLessThan; - -import com.swirlds.common.context.PlatformContext; -import com.swirlds.common.metrics.DurationGauge; -import com.swirlds.metrics.api.IntegerGauge; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.time.Duration; -import java.time.temporal.ChronoUnit; - -/** - * Encapsulates metrics for the wiring health monitor. - */ -public class HealthMonitorMetrics { - - private static final DurationGauge.Config DURATION_GAUGE_CONFIG = new DurationGauge.Config( - "platform", "unhealthyDuration", ChronoUnit.SECONDS) - .withDescription("The duration that the most unhealthy scheduler has been in an unhealthy state."); - private final DurationGauge unhealthyDuration; - - private static final IntegerGauge.Config HEALTHY_CONFIG = new IntegerGauge.Config("platform", "healthy") - .withDescription("1 if the platform is healthy, 0 otherwise. " - + "Triggers once unhealthyDuration metric crosses configured threshold."); - private final IntegerGauge healthy; - - private final Duration healthThreshold; - - /** - * Constructor. - * - * @param platformContext the platform context - * @param healthLogThreshold the duration after which the system is considered unhealthy - */ - public HealthMonitorMetrics( - @NonNull final PlatformContext platformContext, @NonNull final Duration healthLogThreshold) { - unhealthyDuration = platformContext.getMetrics().getOrCreate(DURATION_GAUGE_CONFIG); - healthy = platformContext.getMetrics().getOrCreate(HEALTHY_CONFIG); - - // Always initialize the system as healthy - healthy.set(1); - - healthThreshold = healthLogThreshold; - } - - /** - * Set the unhealthy duration. - * - * @param duration the unhealthy duration - */ - public void reportUnhealthyDuration(@NonNull final Duration duration) { - unhealthyDuration.set(duration); - healthy.set(isLessThan(duration, healthThreshold) ? 1 : 0); - } -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/standard/AbstractHeartbeatScheduler.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/standard/AbstractHeartbeatScheduler.java deleted file mode 100644 index cf702ba3fd9..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/standard/AbstractHeartbeatScheduler.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.model.internal.standard; - -import static org.hiero.wiring.framework.model.diagram.HyperlinkBuilder.platformCommonHyperlink; - -import com.swirlds.base.time.Time; -import org.hiero.wiring.framework.model.TraceableWiringModel; -import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; -import org.hiero.wiring.framework.wires.output.OutputWire; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.time.Duration; -import java.time.Instant; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - -/** - * A scheduler that produces heartbeats at a specified rate. - */ -public abstract class AbstractHeartbeatScheduler { - - private final TraceableWiringModel model; - protected final Time time; - protected final String name; - protected final List tasks = new ArrayList<>(); - protected boolean started; - - /** - * Constructor. - * - * @param model the wiring model containing this heartbeat scheduler - * @param time provides wall clock time - * @param name the name of the heartbeat scheduler - */ - public AbstractHeartbeatScheduler( - @NonNull final TraceableWiringModel model, @NonNull final Time time, @NonNull final String name) { - this.model = Objects.requireNonNull(model); - this.time = Objects.requireNonNull(time); - this.name = Objects.requireNonNull(name); - model.registerVertex( - name, TaskSchedulerType.SEQUENTIAL, platformCommonHyperlink(AbstractHeartbeatScheduler.class), false); - } - - /** - * Build a wire that produces an instant (reflecting current time) at the specified rate. Note that the exact rate - * of heartbeats may vary. This is a best effort algorithm, and actual rates may vary depending on a variety of - * factors. - * - * @param period the period of the heartbeat. For example, setting a period of 100ms will cause the heartbeat to be - * sent at 10 hertz. Note that time is measured at millisecond precision, and so periods less than 1ms - * are not supported. - * @return the output wire - * @throws IllegalStateException if start has already been called - */ - @NonNull - public OutputWire buildHeartbeatWire(@NonNull final Duration period) { - if (started) { - throw new IllegalStateException("Cannot create heartbeat wires after the heartbeat has started"); - } - - if (period.isNegative() || period.isZero()) { - throw new IllegalArgumentException("Period must be positive"); - } - - if (period.toMillis() == 0) { - throw new IllegalArgumentException( - "Time is measured at millisecond precision, and so periods less than 1ms are not supported. " - + "Requested period: " + period); - } - - final HeartbeatTask task = new HeartbeatTask(model, name, time, period); - tasks.add(task); - - return task.getOutputWire(); - } - - /** - * Build a wire that produces an instant (reflecting current time) at the specified rate. Note that the exact rate - * of heartbeats may vary. This is a best effort algorithm, and actual rates may vary depending on a variety of - * factors. - * - * @param frequency the frequency of the heartbeat in hertz. Note that time is measured at millisecond precision, - * and so frequencies greater than 1000hz are not supported. - * @return the output wire - */ - public OutputWire buildHeartbeatWire(final double frequency) { - if (frequency <= 0) { - throw new IllegalArgumentException("Frequency must be positive"); - } - final Duration period = Duration.ofMillis((long) (1000.0 / frequency)); - return buildHeartbeatWire(period); - } - - /** - * Start the heartbeats. - */ - public abstract void start(); - - /** - * Stop the heartbeats. - */ - public abstract void stop(); -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/standard/HeartbeatScheduler.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/standard/HeartbeatScheduler.java deleted file mode 100644 index 53b27a55ec1..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/standard/HeartbeatScheduler.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.model.internal.standard; - -import com.swirlds.base.time.Time; -import org.hiero.wiring.framework.model.StandardWiringModel; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.Timer; - -/** - * A scheduler that produces heartbeats at a specified rate. - */ -public class HeartbeatScheduler extends AbstractHeartbeatScheduler { - - private final Timer timer = new Timer(); - - /** - * Constructor. - * - * @param model the wiring model containing this heartbeat scheduler - * @param time provides wall clock time - * @param name the name of the heartbeat scheduler - */ - public HeartbeatScheduler( - @NonNull final StandardWiringModel model, @NonNull final Time time, @NonNull final String name) { - super(model, time, name); - } - - /** - * Start the heartbeats. - */ - @Override - public void start() { - if (started) { - throw new IllegalStateException("Cannot start the heartbeat more than once"); - } - started = true; - - for (final HeartbeatTask task : tasks) { - timer.scheduleAtFixedRate(task, 0, task.getPeriod().toMillis()); - } - } - - /** - * Stop the heartbeats. - */ - @Override - public void stop() { - if (!started) { - throw new IllegalStateException("Cannot stop the heartbeat before it has started"); - } - timer.cancel(); - } -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/standard/HeartbeatTask.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/standard/HeartbeatTask.java deleted file mode 100644 index 52d92c52d0d..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/standard/HeartbeatTask.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.model.internal.standard; - -import com.swirlds.base.time.Time; -import org.hiero.wiring.framework.model.TraceableWiringModel; -import org.hiero.wiring.framework.wires.output.OutputWire; -import org.hiero.wiring.framework.wires.output.StandardOutputWire; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.time.Duration; -import java.time.Instant; -import java.util.Objects; -import java.util.TimerTask; - -/** - * A task that produces a heartbeat at a specified rate. - */ -public class HeartbeatTask extends TimerTask { - - private final Time time; - private final Duration period; - private final StandardOutputWire outputWire; - - /** - * Constructor. - * - * @param model the wiring model that this heartbeat is for - * @param name the name of the output wire - * @param time provides wall clock time - * @param period the period of the heartbeat - */ - public HeartbeatTask( - @NonNull final TraceableWiringModel model, - @NonNull final String name, - @NonNull final Time time, - @NonNull final Duration period) { - this.time = Objects.requireNonNull(time); - this.period = Objects.requireNonNull(period); - Objects.requireNonNull(name); - - this.outputWire = new StandardOutputWire<>(model, name); - } - - /** - * Get the period of the heartbeat. - * - * @return the period of the heartbeat - */ - @NonNull - public Duration getPeriod() { - return period; - } - - /** - * Get the output wire. Produces an Instant with the current time at the specified rate. - * - * @return the output wire - */ - @NonNull - public OutputWire getOutputWire() { - return outputWire; - } - - /** - * Produce a single heartbeat. - */ - @Override - public void run() { - outputWire.forward(time.now()); - } -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/standard/JvmAnchor.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/standard/JvmAnchor.java deleted file mode 100644 index b484905bc75..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/model/internal/standard/JvmAnchor.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.model.internal.standard; - -import static java.util.concurrent.TimeUnit.SECONDS; - -import com.swirlds.base.state.Startable; -import com.swirlds.base.state.Stoppable; - -/** - * Creates a non-daemon JVM thread that does nothing. Keeps the JVM alive if all other threads are daemon threads. - */ -public class JvmAnchor implements Startable, Stoppable { - - private final Thread thread; - - /** - * Constructor. - */ - public JvmAnchor() { - thread = new Thread(this::run, ""); - thread.setDaemon(false); // important - } - - /** - * {@inheritDoc} - */ - @Override - public void start() { - thread.start(); - } - - /** - * {@inheritDoc} - */ - @Override - public void stop() { - thread.interrupt(); - } - - /** - * Runs and does nothing until interrupted. - */ - private void run() { - while (!Thread.currentThread().isInterrupted()) { - try { - SECONDS.sleep(Integer.MAX_VALUE); - } catch (final InterruptedException e) { - Thread.currentThread().interrupt(); - return; - } - } - } -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/TaskScheduler.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/TaskScheduler.java deleted file mode 100644 index c3f5d265d24..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/TaskScheduler.java +++ /dev/null @@ -1,289 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.schedulers; - -import org.hiero.wiring.framework.counters.ObjectCounter; -import org.hiero.wiring.framework.model.TraceableWiringModel; -import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerBuilder; -import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; -import org.hiero.wiring.framework.schedulers.internal.DefaultSquelcher; -import org.hiero.wiring.framework.schedulers.internal.Squelcher; -import org.hiero.wiring.framework.schedulers.internal.ThrowingSquelcher; -import org.hiero.wiring.framework.wires.input.BindableInputWire; -import org.hiero.wiring.framework.wires.input.InputWire; -import org.hiero.wiring.framework.wires.input.TaskSchedulerInput; -import org.hiero.wiring.framework.wires.output.OutputWire; -import org.hiero.wiring.framework.wires.output.StandardOutputWire; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.Objects; -import java.util.function.Consumer; -import java.util.function.Function; - -/** - * Schedules tasks for a component. - *

    - * The lifecycle of a task is as follows: - *

      - *
    1. Unscheduled: the task has not been passed to the scheduler yet (e.g. via {@link InputWire#put(Object)})
    2. - *
    3. Scheduled but not processed: the task has been passed to the scheduler but the corresponding handler has not - * yet returned (either because the handler has not yet been called or because the handler has been called but hasn't - * finished yet)
    4. - *
    5. Processed: the corresponding handle method for the task has been called and has returned.
    6. - *
    - * - * @param the output type of the primary output wire (use {@link Void} if no output is needed) - */ -public abstract class TaskScheduler extends TaskSchedulerInput { - - private final boolean flushEnabled; - private final TraceableWiringModel model; - private final String name; - private final TaskSchedulerType type; - private final StandardOutputWire primaryOutputWire; - private final boolean insertionIsBlocking; - - /** - * Handles squelching for this task scheduler. Will be a valid object whether or not squelching is enabled for this - * task scheduler. - */ - private final Squelcher squelcher; - - /** - * Constructor. - * - * @param model the wiring model containing this task scheduler - * @param name the name of the task scheduler - * @param type the type of task scheduler - * @param flushEnabled if true, then {@link #flush()} will be enabled, otherwise it will throw. - * @param squelchingEnabled if true, then squelching will be enabled, otherwise trying to squelch will throw. - * @param insertionIsBlocking when data is inserted into this task scheduler, will it block until capacity is - * available? - */ - protected TaskScheduler( - @NonNull final TraceableWiringModel model, - @NonNull final String name, - @NonNull final TaskSchedulerType type, - final boolean flushEnabled, - final boolean squelchingEnabled, - final boolean insertionIsBlocking) { - - this.model = Objects.requireNonNull(model); - this.name = Objects.requireNonNull(name); - this.type = Objects.requireNonNull(type); - this.flushEnabled = flushEnabled; - - if (squelchingEnabled) { - this.squelcher = new DefaultSquelcher(); - } else { - this.squelcher = new ThrowingSquelcher(); - } - - primaryOutputWire = buildPrimaryOutputWire(model, name); - this.insertionIsBlocking = insertionIsBlocking; - } - - /** - * Build an input wire for passing data to this task scheduler. In order to use this wire, a handler must be bound - * via {@link BindableInputWire#bind(Function)} {@link BindableInputWire#bindConsumer(Consumer)}. - * - * @param name the name of the input wire - * @param the type of data that is inserted via this input wire - * @return the input wire - */ - @NonNull - public BindableInputWire buildInputWire(@NonNull final String name) { - return new BindableInputWire<>(model, this, name); - } - - /** - * Build the primary output wire for this scheduler. - * - * @param model the wiring model that contains this scheduler - * @param name the name of this scheduler - * @return the primary output wire - */ - @NonNull - protected StandardOutputWire buildPrimaryOutputWire( - @NonNull final TraceableWiringModel model, @NonNull final String name) { - return new StandardOutputWire<>(model, name); - } - - /** - * Get the default output wire for this task scheduler. Sometimes referred to as the "primary" output wire. All data - * returned by handlers is passed ot this output wire. Calling this method more than once will always return the - * same object. - * - * @return the primary output wire - */ - @NonNull - public OutputWire getOutputWire() { - return primaryOutputWire; - } - - /** - * By default a component has a single output wire (i.e. the primary output wire). This method allows additional - * output wires to be created. - * - *

    - * Unlike primary wires, secondary output wires need to be passed to a component's constructor. It is considered a - * violation of convention to push data into a secondary output wire from any code that is not executing within this - * task scheduler. - * - * @param the type of data that is transmitted over this output wire - * @return the secondary output wire - */ - @NonNull - public StandardOutputWire buildSecondaryOutputWire() { - // Intentionally do not register this with the model. Connections using this output wire will be represented - // in the model in the same way as connections to the primary output wire. - return new StandardOutputWire<>(model, name); - } - - /** - * Get the name of this task scheduler. - * - * @return the name of this task scheduler - */ - @NonNull - public String getName() { - return name; - } - - /** - * Get the type of this task scheduler. - * - * @return the type of this task scheduler - */ - @NonNull - public TaskSchedulerType getType() { - return type; - } - - /** - * Get whether or not this task scheduler can block when data is inserted into it. - * - * @return true if this task scheduler can block when data is inserted into it, false otherwise - */ - public boolean isInsertionBlocking() { - return insertionIsBlocking; - } - - /** - * Cast this scheduler into whatever a variable is expecting. Sometimes the compiler gets confused with generics, - * and path of least resistance is to just cast to the proper data type. - * - *

    - * Warning: this will appease the compiler, but it is possible to cast a scheduler into a data type that will cause - * runtime exceptions. Use with appropriate caution. - * - * @param the type to cast to - * @return this, cast into whatever type is requested - */ - @NonNull - @SuppressWarnings("unchecked") - public final TaskScheduler cast() { - return (TaskScheduler) this; - } - - /** - * Get the number of unprocessed tasks. A task is considered to be unprocessed until the data has been passed to the - * handler method (i.e. the one given to {@link BindableInputWire#bind(Function)} or - * {@link BindableInputWire#bindConsumer(Consumer)}) and that handler method has returned. - *

    - * Returns {@link ObjectCounter#COUNT_UNDEFINED} if this task scheduler is not monitoring the number of unprocessed - * tasks. Schedulers do not track the number of unprocessed tasks by default. This method will always return - * {@link ObjectCounter#COUNT_UNDEFINED} unless one of the following is true: - *

      - *
    • {@link TaskSchedulerBuilder#withUnhandledTaskMetricEnabled(boolean)} is called with the value - * true
    • - *
    • {@link TaskSchedulerBuilder#withUnhandledTaskCapacity(long)} is passed a positive value
    • - *
    • {@link TaskSchedulerBuilder#withOnRamp(ObjectCounter)} is passed a counter that is not a no op counter
    • - *
    - */ - public abstract long getUnprocessedTaskCount(); - - /** - * Get this task scheduler's desired maximum desired capacity. If {@link TaskSchedulerBuilder#UNLIMITED_CAPACITY} is - * returned, then this task scheduler does not have a maximum capacity. - * - * @return the maximum desired capacity of this task scheduler - */ - public abstract long getCapacity(); - - /** - * Flush all data in the task scheduler. Blocks until all data currently in flight has been processed. - * - *

    - * Note: must be enabled by passing true to {@link TaskSchedulerBuilder#withFlushingEnabled(boolean)}. - * - *

    - * Warning: some implementations of flush may block indefinitely if new work is continuously added to the scheduler - * while flushing. Such implementations are guaranteed to finish flushing once new work is no longer being added. - * Some implementations do not have this restriction, and will return as soon as all of the in flight work has been - * processed, regardless of whether or not new work is being added. - * - * @throws UnsupportedOperationException if {@link TaskSchedulerBuilder#withFlushingEnabled(boolean)} was set to - * false (or was unset, default is false) - */ - public abstract void flush(); - - /** - * Throw an {@link UnsupportedOperationException} if flushing is not enabled. - */ - protected final void throwIfFlushDisabled() { - if (!flushEnabled) { - throw new UnsupportedOperationException("Flushing is not enabled for the task scheduler " + name); - } - } - - /** - * Start squelching, and continue doing so until {@link #stopSquelching()} is called. - * - * @throws UnsupportedOperationException if squelching is not supported by this scheduler - * @throws IllegalStateException if scheduler is already squelching - */ - public void startSquelching() { - squelcher.startSquelching(); - } - - /** - * Stop squelching. - * - * @throws UnsupportedOperationException if squelching is not supported by this scheduler - * @throws IllegalStateException if scheduler is not currently squelching - */ - public void stopSquelching() { - squelcher.stopSquelching(); - } - - /** - * Get whether or not this task scheduler is currently squelching. - * - * @return true if this task scheduler is currently squelching, false otherwise - */ - public final boolean currentlySquelching() { - return squelcher.shouldSquelch(); - } - - /** - * {@inheritDoc} - */ - @Override - protected void forward(@NonNull final OUT data) { - primaryOutputWire.forward(data); - } -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/builders/TaskSchedulerBuilder.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/builders/TaskSchedulerBuilder.java deleted file mode 100644 index e5aed604550..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/builders/TaskSchedulerBuilder.java +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.schedulers.builders; - -import org.hiero.wiring.framework.counters.ObjectCounter; -import org.hiero.wiring.framework.schedulers.TaskScheduler; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import java.lang.Thread.UncaughtExceptionHandler; -import java.time.Duration; -import java.util.concurrent.ForkJoinPool; -import java.util.function.ToLongFunction; - -/** - * A builder for {@link TaskScheduler}s. - * - * @param the output type of the primary output wire for this task scheduler (use {@link Void} for a scheduler - * with no output) - */ -public interface TaskSchedulerBuilder { - - long UNLIMITED_CAPACITY = -1; - - /** - * Configure this task scheduler with values from settings. - * - * @param configuration the configuration - * @return this - */ - @NonNull - TaskSchedulerBuilder configure(@NonNull TaskSchedulerConfiguration configuration); - - /** - * Set the type of task scheduler to build. Alters the semantics of the scheduler (i.e. this is not just an internal - * implementation detail). - * - * @param type the type of task scheduler to build - * @return this - */ - @NonNull - TaskSchedulerBuilder withType(@NonNull TaskSchedulerType type); - - /** - * Set the maximum number of permitted scheduled tasks. Default is 1. - * - * @param unhandledTaskCapacity the maximum number of permitted unhandled tasks - * @return this - */ - @NonNull - TaskSchedulerBuilder withUnhandledTaskCapacity(long unhandledTaskCapacity); - - /** - * Set whether the task scheduler should enable flushing. Default false. Flushing a scheduler with this disabled - * will cause the scheduler to throw an exception. Enabling flushing may add overhead. - * - * @param requireFlushCapability true if the wire should require flush capability, false otherwise - * @return this - */ - @NonNull - TaskSchedulerBuilder withFlushingEnabled(boolean requireFlushCapability); - - /** - * Set whether the task scheduler should enable squelching. Default false. Enabling squelching may add overhead. - *

    - * IMPORTANT: you must not enable squelching if the scheduler handles tasks that require special cleanup. If - * squelching is enabled and activated, all existing and incoming tasks will be unceremoniously dumped into the - * void! - * - * @param squelchingEnabled true if the scheduler should enable squelching, false otherwise. - * @return this - */ - @NonNull - TaskSchedulerBuilder withSquelchingEnabled(boolean squelchingEnabled); - - /** - * Specify an object counter that should be notified when data is added to the task scheduler. This is useful for - * implementing backpressure that spans multiple schedulers. - * - * @param onRamp the object counter that should be notified when data is added to the task scheduler - * @return this - */ - @NonNull - TaskSchedulerBuilder withOnRamp(@NonNull ObjectCounter onRamp); - - /** - * Specify an object counter that should be notified when data is removed from the task scheduler. This is useful - * for implementing backpressure that spans multiple schedulers. - * - * @param offRamp the object counter that should be notified when data is removed from the wire - * @return this - */ - @NonNull - TaskSchedulerBuilder withOffRamp(@NonNull ObjectCounter offRamp); - - /** - * If true then the framework will assume that back pressure is being applied via external mechanisms. - *

    - * This method does not change the runtime behavior of the wiring framework. But it does affect cyclical back - * pressure detection and automatically generated wiring diagrams. - * - * @param externalBackPressure true if back pressure is being applied externally, false otherwise - * @return this - */ - @NonNull - TaskSchedulerBuilder withExternalBackPressure(boolean externalBackPressure); - - /** - * If a method needs to block, this is the amount of time that is slept while waiting for the needed condition. - * - * @param backpressureSleepDuration the length of time to sleep when backpressure needs to be applied - * @return this - */ - @NonNull - TaskSchedulerBuilder withSleepDuration(@NonNull Duration backpressureSleepDuration); - - /** - * Set whether the unhandled task count metric should be enabled. Default false. - * - * @param enabled true if the unhandled task count metric should be enabled, false otherwise - * @return this - */ - @NonNull - TaskSchedulerBuilder withUnhandledTaskMetricEnabled(boolean enabled); - - /** - * Set whether the busy fraction metric should be enabled. Default false. - *

    - * Note: this metric is currently only compatible with non-concurrent task scheduler implementations. At a future - * time this metric may be updated to work with concurrent scheduler implementations. - * - * @param enabled true if the busy fraction metric should be enabled, false otherwise - * @return this - */ - @NonNull - TaskSchedulerBuilder withBusyFractionMetricsEnabled(boolean enabled); - - /** - * Provide a custom thread pool for this task scheduler. If none is provided then the common fork join pool will be - * used. - * - * @param pool the thread pool - * @return this - */ - @NonNull - TaskSchedulerBuilder withPool(@NonNull ForkJoinPool pool); - - /** - * Provide a custom uncaught exception handler for this task scheduler. If none is provided then the default - * uncaught exception handler will be used. The default handler will write a message to the log. - * - * @param uncaughtExceptionHandler the uncaught exception handler - * @return this - */ - @NonNull - TaskSchedulerBuilder withUncaughtExceptionHandler(@NonNull UncaughtExceptionHandler uncaughtExceptionHandler); - - /** - * Provide a hyperlink to documentation for this task scheduler. If none is provided then no hyperlink will be - * generated. Used only for the automatically generated wiring diagram. - * - * @param hyperlink the hyperlink to the documentation for this task scheduler - * @return this - */ - @NonNull - TaskSchedulerBuilder withHyperlink(@Nullable String hyperlink); - - /** - * Provide a function to count weight of a data object for component health monitoring. - * @param dataCounter the - * @return this - */ - @NonNull - TaskSchedulerBuilder withDataCounter(@NonNull ToLongFunction dataCounter); - - /** - * Build the task scheduler. - * - * @return the task scheduler - */ - @NonNull - TaskScheduler build(); -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/builders/TaskSchedulerConfigOption.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/builders/TaskSchedulerConfigOption.java deleted file mode 100644 index 45145d5e0e4..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/builders/TaskSchedulerConfigOption.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.schedulers.builders; - -/** - * Various configuration options for a task scheduler. Note that the task scheduler type uses values from - * {@link TaskSchedulerType}, and that the unhandled task capacity is represented as an integer value. - */ -public enum TaskSchedulerConfigOption { - /** - * If present, a metric will be created to show the number of unhandled tasks. - */ - UNHANDLED_TASK_METRIC, - /** - * If present, a metric will be created to show the fraction of time the scheduler is busy. - */ - BUSY_FRACTION_METRIC, - /** - * If present, the scheduler will be capable of being flushed. - */ - FLUSHABLE, - /** - * If present, the scheduler will be capable of squelching. - */ - SQUELCHABLE; - - /** - * This is not defined as an enum constant because it is used in a special way. To specify the capacity, - * use a string in the form "CAPACITY(1234)" where 1234 is the desired capacity. - */ - public static final String CAPACITY = "CAPACITY"; -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/builders/TaskSchedulerConfiguration.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/builders/TaskSchedulerConfiguration.java deleted file mode 100644 index 8966f3a6226..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/builders/TaskSchedulerConfiguration.java +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Copyright (C) 2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.schedulers.builders; - -import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerConfigOption.BUSY_FRACTION_METRIC; -import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerConfigOption.FLUSHABLE; -import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerConfigOption.SQUELCHABLE; -import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerConfigOption.UNHANDLED_TASK_METRIC; - -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; - -/** - * Configures a task scheduler. - * - * @param type the type of task scheduler, if null then {@link TaskSchedulerType#SEQUENTIAL} is - * used - * @param unhandledTaskCapacity the maximum number of unhandled tasks, or 0 if unbounded, if null then 0 is used - * @param unhandledTaskMetricEnabled whether the unhandled task count metric should be enabled, if null than false is - * used - * @param busyFractionMetricEnabled whether the busy fraction metric should be enabled, if null then false is used - * @param flushingEnabled whether flushing is enabled, if null then false is used - * @param squelchingEnabled whether squelching is enabled, if null then false is used - */ -public record TaskSchedulerConfiguration( - @Nullable TaskSchedulerType type, - @Nullable Long unhandledTaskCapacity, - @Nullable Boolean unhandledTaskMetricEnabled, - @Nullable Boolean busyFractionMetricEnabled, - @Nullable Boolean flushingEnabled, - @Nullable Boolean squelchingEnabled) { - - /** - * This configuration is for a no-op task scheduler. It is not necessary to use this constant for a no-op task - * scheduler, but it is provided for convenience. - */ - public static final TaskSchedulerConfiguration NO_OP_CONFIGURATION = - new TaskSchedulerConfiguration(TaskSchedulerType.NO_OP, 0L, false, false, false, false); - - /** - * This configuration is for a simple direct task scheduler. It is not necessary to use this constant for a direct - * task scheduler, but it is provided for convenience. - */ - public static final TaskSchedulerConfiguration DIRECT_CONFIGURATION = - new TaskSchedulerConfiguration(TaskSchedulerType.DIRECT, 0L, false, false, false, false); - - /** - * This configuration is for a thread-safe direct task scheduler. It is not necessary to use this constant for a - * thread-safe direct task scheduler, but it is provided for convenience. - */ - public static final TaskSchedulerConfiguration DIRECT_THREADSAFE_CONFIGURATION = - new TaskSchedulerConfiguration(TaskSchedulerType.DIRECT_THREADSAFE, 0L, false, false, false, false); - - /** - * Parse a string representation of a task scheduler configuration. - *

    - * Syntax is as follows: - *

      - *
    • - * Zero or one values from the {@link TaskSchedulerType} enum, specifies the type of the task scheduler. - * If not present then the default is used. - *
    • - *
    • - * Zero or one string of the form "CAPACITY(1234)", specifies the maximum number of unhandled tasks. - *
    • - *
    • - * Zero or more values from the {@link TaskSchedulerConfigOption} enum, specifies the configuration options. - * Sets a boolean configuration option to true if the value is present, and false if the value is prefixed - * with a "!". If not present then the default is used. - *
    • - *
    - * Example: "SEQUENTIAL CAPACITY(500) !FLUSHABLE UNHANDLED_TASK_METRIC" - *

    - * Note that default values are not specified within this class. Default values are the responsibility of the - * {@link TaskSchedulerBuilder} class. - * - * @param string the string to parse - * @return the parsed configuration - */ - @NonNull - public static TaskSchedulerConfiguration parse(@NonNull final String string) { - TaskSchedulerType type = null; - Long unhandledTaskCapacity = null; - Boolean unhandledTaskMetricEnabled = null; - Boolean busyFractionMetricEnabled = null; - Boolean flushingEnabled = null; - Boolean squelchingEnabled = null; - - final String[] parts = string.split(" "); - for (final String part : parts) { - final String strippedPart = part.strip(); - if (strippedPart.isEmpty()) { - continue; - } - - final TaskSchedulerType parsedType = tryToParseTaskSchedulerType(strippedPart); - if (parsedType != null) { - if (type != null) { - throw new IllegalArgumentException("Multiple task scheduler types specified: " + string); - } - type = parsedType; - continue; - } - - final Long parsedCapacity = tryToParseCapacity(strippedPart); - if (parsedCapacity != null) { - if (unhandledTaskCapacity != null) { - throw new IllegalArgumentException("Multiple capacities specified: " + string); - } - unhandledTaskCapacity = parsedCapacity; - continue; - } - - final Boolean parsedUnhandledTaskMetric = tryToParseOption(UNHANDLED_TASK_METRIC, strippedPart); - if (parsedUnhandledTaskMetric != null) { - if (unhandledTaskMetricEnabled != null) { - throw new IllegalArgumentException( - "Multiple unhandled task metric configurations specified: " + string); - } - unhandledTaskMetricEnabled = parsedUnhandledTaskMetric; - continue; - } - - final Boolean parsedBusyFractionMetric = tryToParseOption(BUSY_FRACTION_METRIC, strippedPart); - if (parsedBusyFractionMetric != null) { - if (busyFractionMetricEnabled != null) { - throw new IllegalArgumentException( - "Multiple busy fraction metric configurations specified: " + string); - } - busyFractionMetricEnabled = parsedBusyFractionMetric; - continue; - } - - final Boolean parsedFlushing = tryToParseOption(FLUSHABLE, strippedPart); - if (parsedFlushing != null) { - if (flushingEnabled != null) { - throw new IllegalArgumentException("Multiple flushing configurations specified: " + string); - } - flushingEnabled = parsedFlushing; - continue; - } - - final Boolean parsedSquelching = tryToParseOption(SQUELCHABLE, strippedPart); - if (parsedSquelching != null) { - if (squelchingEnabled != null) { - throw new IllegalArgumentException("Multiple squelching configurations specified: " + string); - } - squelchingEnabled = parsedSquelching; - continue; - } - - throw new IllegalArgumentException("Invalid task scheduler configuration: " + part); - } - - return new TaskSchedulerConfiguration( - type, - unhandledTaskCapacity, - unhandledTaskMetricEnabled, - busyFractionMetricEnabled, - flushingEnabled, - squelchingEnabled); - } - - /** - * Try to parse a string as a {@link TaskSchedulerType}. - * - * @param string the string to parse - * @return the parsed type, or null if the string is not a valid type - */ - @Nullable - private static TaskSchedulerType tryToParseTaskSchedulerType(@NonNull final String string) { - try { - return TaskSchedulerType.valueOf(string); - } catch (final IllegalArgumentException e) { - return null; - } - } - - /** - * Try to parse a string as a capacity. - * - * @param string the string to parse - * @return the parsed capacity, or null if the string is not a valid capacity - */ - @Nullable - private static Long tryToParseCapacity(@NonNull final String string) { - if (string.startsWith(TaskSchedulerConfigOption.CAPACITY)) { - - try { - // parse a string in the form "CAPACITY(1234)" - final int openParenIndex = string.indexOf('('); - final int closeParenIndex = string.indexOf(')'); - if (openParenIndex == -1 || closeParenIndex == -1) { - throw new IllegalArgumentException("Invalid capacity \"" + string + "\""); - } - final String capacityString = string.substring(openParenIndex + 1, closeParenIndex); - return Long.parseLong(capacityString); - } catch (final NumberFormatException e) { - throw new IllegalArgumentException("Invalid capacity \"" + string + "\"", e); - } - } - return null; - } - - /** - * Try to parse a string as a configuration option that is represented by an enum string and an optional "!". - * - * @param option the option to look for - * @param string the string to parse - * @return the parsed option, or null if the string is not a valid option - */ - @Nullable - private static Boolean tryToParseOption( - @NonNull final TaskSchedulerConfigOption option, @NonNull final String string) { - - if (string.equals(option.toString())) { - return true; - } else if (string.equals("!" + option)) { - return false; - } - return null; - } -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/builders/TaskSchedulerType.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/builders/TaskSchedulerType.java deleted file mode 100644 index 3e4e42cea75..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/builders/TaskSchedulerType.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.schedulers.builders; - -/** - * Various types of task schedulers. Pass one of these types to {@link TaskSchedulerBuilder#withType(TaskSchedulerType)} - * to create a task scheduler of the desired type. If unspecified, the default scheduler type is {@link #SEQUENTIAL}. - */ -public enum TaskSchedulerType { - /** - * Tasks are executed in a fork join pool one at a time in the order they were enqueued. There is a happens before - * relationship between each task. - */ - SEQUENTIAL, - /** - * Tasks are executed on a dedicated thread one at a time in the order they were enqueued. There is a happens before - * relationship between each task. This scheduler type has very similar semantics as {@link #SEQUENTIAL}, although - * the implementation and performance characteristics are not identical. - */ - SEQUENTIAL_THREAD, - /** - * Tasks are executed on a fork join pool. Tasks may be executed in parallel with each other. Ordering is not - * guaranteed. - */ - CONCURRENT, - /** - * Tasks are executed immediately on the caller's thread. There is no queue for tasks waiting to be handled (logical - * or otherwise). Useful for scenarios where tasks are extremely small and not worth the scheduling overhead. - *

    - * Only a single logical thread of execution is permitted to send data to a direct task scheduler. - * {@link #SEQUENTIAL} and {@link #SEQUENTIAL_THREAD} schedulers are permitted to send data to a direct task - * scheduler, but it is illegal for more than one of these schedulers to send data to the same direct task - * scheduler. {@link #CONCURRENT} task schedulers are forbidden from sending data to a direct task scheduler. It is - * legal for operations that are executed on the calling thread (e.g. filters, transformers, stateless/stateful - * direct schedulers) to call into a direct scheduler as long as the calling thread is not in a concurrent scheduler - * or originating from more than one sequential scheduler. - *

    - * To decide if a direct scheduler is wired in a legal way, the following algorithm is used: - *

      - *
    • Create a directed graph where vertices are schedulers and edges are wires between schedulers
    • - *
    • Starting from each vertex, walk over the graph in depth first order. Follow edges that lead to - * DIRECT or DIRECT_THREADSAFE vertices, but do not follow edges that lead into SEQUENTIAL, SEQUENTIAL_THREAD, - * or CONCURRENT vertices.
    • - *
    • If a DIRECT vertex is reachable starting from a CONCURRENT vertex, the wiring is illegal.
    • - *
    • For each vertex with type DIRECT, count the number of unique SEQUENTIAL or SEQUENTIAL_THREAD vertexes that - * it can be reached by. If that number exceeds 1, then the wiring is illegal.
    • - *
    - * - *

    - * These constraints are enforced by the framework. - */ - DIRECT, - /** - * Similar to {@link #DIRECT} except that work performed by this scheduler is required to be threadsafe. This means - * that it is safe to concurrently execute multiple instances of the same task, freeing it from the restrictions of - * {@link #DIRECT}. - * - *

    - * There is no enforcement mechanism in the framework to ensure that the task is actually threadsafe. It is advised - * that this scheduler type be used with caution, as improper use can lead to can lead to nasty race conditions. - */ - DIRECT_THREADSAFE, - /** - * A scheduler that does nothing. All wires into and out of this scheduler are effectively non-existent at runtime. - * Useful for testing and debugging, or for when the ability to toggle a scheduler on/off via configuration is - * desired. For a deeper dive into why this is a useful concept, see - * this explanation. - */ - NO_OP -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/builders/internal/AbstractTaskSchedulerBuilder.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/builders/internal/AbstractTaskSchedulerBuilder.java deleted file mode 100644 index 73a82bffcb1..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/builders/internal/AbstractTaskSchedulerBuilder.java +++ /dev/null @@ -1,355 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.schedulers.builders.internal; - -import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.DIRECT; -import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.DIRECT_THREADSAFE; -import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.NO_OP; -import static com.swirlds.logging.legacy.LogMarker.EXCEPTION; - -import com.swirlds.common.context.PlatformContext; -import org.hiero.wiring.framework.counters.BackpressureObjectCounter; -import org.hiero.wiring.framework.counters.MultiObjectCounter; -import org.hiero.wiring.framework.counters.NoOpObjectCounter; -import org.hiero.wiring.framework.counters.ObjectCounter; -import org.hiero.wiring.framework.counters.StandardObjectCounter; -import org.hiero.wiring.framework.model.TraceableWiringModel; -import org.hiero.wiring.framework.schedulers.TaskScheduler; -import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerBuilder; -import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerConfiguration; -import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import java.lang.Thread.UncaughtExceptionHandler; -import java.time.Duration; -import java.util.Objects; -import java.util.concurrent.ForkJoinPool; -import java.util.function.ToLongFunction; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -/** - * A builder for {@link TaskScheduler}s. - * - * @param the output type of the primary output wire for this task scheduler (use {@link Void} for a scheduler with - * no output) - */ -public abstract class AbstractTaskSchedulerBuilder implements TaskSchedulerBuilder { - - private static final Logger logger = LogManager.getLogger(AbstractTaskSchedulerBuilder.class); - - protected final TraceableWiringModel model; - - protected TaskSchedulerType type = TaskSchedulerType.SEQUENTIAL; - protected final String name; - protected long unhandledTaskCapacity = 1; - protected boolean flushingEnabled = false; - protected boolean squelchingEnabled = false; - protected boolean externalBackPressure = false; - protected ObjectCounter onRamp; - protected ObjectCounter offRamp; - protected ForkJoinPool pool; - protected UncaughtExceptionHandler uncaughtExceptionHandler; - protected String hyperlink; - protected ToLongFunction dataCounter = data -> 1L; - - protected boolean unhandledTaskMetricEnabled = false; - protected boolean busyFractionMetricEnabled = false; - - protected Duration sleepDuration = Duration.ofNanos(100); - - protected final PlatformContext platformContext; - - /** - * Constructor. - * - * @param platformContext the platform context - * @param model the wiring model - * @param name the name of the task scheduler. Used for metrics and debugging. Must be unique. Must only - * contain alphanumeric characters and underscores. - * @param defaultPool the default fork join pool, if none is provided then this pool will be used - */ - public AbstractTaskSchedulerBuilder( - @NonNull final PlatformContext platformContext, - @NonNull final TraceableWiringModel model, - @NonNull final String name, - @NonNull final ForkJoinPool defaultPool) { - - this.platformContext = Objects.requireNonNull(platformContext); - this.model = Objects.requireNonNull(model); - - // The reason why wire names have a restricted character set is because downstream consumers of metrics - // are very fussy about what characters are allowed in metric names. - if (!name.matches("^[a-zA-Z0-9_]*$")) { - throw new IllegalArgumentException("Illegal name: \"" + name - + "\". Task Schedulers name must only contain alphanumeric characters and underscores"); - } - if (name.isEmpty()) { - throw new IllegalArgumentException("TaskScheduler name must not be empty"); - } - this.name = name; - this.pool = Objects.requireNonNull(defaultPool); - } - - /** - * {@inheritDoc} - */ - @Override - @NonNull - public AbstractTaskSchedulerBuilder configure(@NonNull final TaskSchedulerConfiguration configuration) { - if (configuration.type() != null) { - withType(configuration.type()); - } - if (configuration.unhandledTaskCapacity() != null) { - withUnhandledTaskCapacity(configuration.unhandledTaskCapacity()); - } - if (configuration.unhandledTaskMetricEnabled() != null) { - withUnhandledTaskMetricEnabled(configuration.unhandledTaskMetricEnabled()); - } - if (configuration.busyFractionMetricEnabled() != null) { - withBusyFractionMetricsEnabled(configuration.busyFractionMetricEnabled()); - } - if (configuration.flushingEnabled() != null) { - withFlushingEnabled(configuration.flushingEnabled()); - } - if (configuration.squelchingEnabled() != null) { - withSquelchingEnabled(configuration.squelchingEnabled()); - } - return this; - } - - /** - * {@inheritDoc} - */ - @Override - @NonNull - public AbstractTaskSchedulerBuilder withType(@NonNull final TaskSchedulerType type) { - this.type = Objects.requireNonNull(type); - return this; - } - - /** - * {@inheritDoc} - */ - @Override - @NonNull - public AbstractTaskSchedulerBuilder withUnhandledTaskCapacity(final long unhandledTaskCapacity) { - this.unhandledTaskCapacity = unhandledTaskCapacity; - return this; - } - - /** - * {@inheritDoc} - */ - @Override - @NonNull - public AbstractTaskSchedulerBuilder withFlushingEnabled(final boolean requireFlushCapability) { - this.flushingEnabled = requireFlushCapability; - return this; - } - - /** - * {@inheritDoc} - */ - @Override - @NonNull - public AbstractTaskSchedulerBuilder withSquelchingEnabled(final boolean squelchingEnabled) { - this.squelchingEnabled = squelchingEnabled; - return this; - } - - /** - * {@inheritDoc} - */ - @Override - @NonNull - public AbstractTaskSchedulerBuilder withOnRamp(@NonNull final ObjectCounter onRamp) { - this.onRamp = Objects.requireNonNull(onRamp); - return this; - } - - /** - * {@inheritDoc} - */ - @Override - @NonNull - public AbstractTaskSchedulerBuilder withOffRamp(@NonNull final ObjectCounter offRamp) { - this.offRamp = Objects.requireNonNull(offRamp); - return this; - } - - /** - * {@inheritDoc} - */ - @Override - @NonNull - public AbstractTaskSchedulerBuilder withExternalBackPressure(final boolean externalBackPressure) { - this.externalBackPressure = externalBackPressure; - return this; - } - - /** - * {@inheritDoc} - */ - @Override - @NonNull - public AbstractTaskSchedulerBuilder withSleepDuration(@NonNull final Duration backpressureSleepDuration) { - if (backpressureSleepDuration.isNegative()) { - throw new IllegalArgumentException("Backpressure sleep duration must not be negative"); - } - this.sleepDuration = backpressureSleepDuration; - return this; - } - - /** - * {@inheritDoc} - */ - @Override - @NonNull - public AbstractTaskSchedulerBuilder withUnhandledTaskMetricEnabled(final boolean enabled) { - this.unhandledTaskMetricEnabled = enabled; - return this; - } - - /** - * {@inheritDoc} - */ - @Override - @NonNull - public AbstractTaskSchedulerBuilder withBusyFractionMetricsEnabled(final boolean enabled) { - this.busyFractionMetricEnabled = enabled; - return this; - } - - /** - * {@inheritDoc} - */ - @Override - @NonNull - public AbstractTaskSchedulerBuilder withPool(@NonNull final ForkJoinPool pool) { - this.pool = Objects.requireNonNull(pool); - return this; - } - - /** - * {@inheritDoc} - */ - @Override - @NonNull - public AbstractTaskSchedulerBuilder withUncaughtExceptionHandler( - @NonNull final UncaughtExceptionHandler uncaughtExceptionHandler) { - this.uncaughtExceptionHandler = Objects.requireNonNull(uncaughtExceptionHandler); - return this; - } - - /** - * {@inheritDoc} - */ - @Override - @NonNull - public AbstractTaskSchedulerBuilder withHyperlink(@Nullable final String hyperlink) { - this.hyperlink = hyperlink; - return this; - } - - @Override - @NonNull - public AbstractTaskSchedulerBuilder withDataCounter(@NonNull ToLongFunction counter) { - this.dataCounter = counter; - return this; - } - - /** - * Build an uncaught exception handler if one was not provided. - * - * @return the uncaught exception handler - */ - @NonNull - protected UncaughtExceptionHandler buildUncaughtExceptionHandler() { - if (uncaughtExceptionHandler != null) { - return uncaughtExceptionHandler; - } else { - return (thread, throwable) -> - logger.error(EXCEPTION.getMarker(), "Uncaught exception in scheduler {}", name, throwable); - } - } - - protected record Counters(@NonNull ObjectCounter onRamp, @NonNull ObjectCounter offRamp) {} - - /** - * Combine two counters into one. - * - * @param innerCounter the counter needed for internal implementation details, or null if not needed - * @param outerCounter the counter provided by the outer scope, or null if not provided - * @return the combined counter, or a no op counter if both are null - */ - @NonNull - protected static ObjectCounter combineCounters( - @Nullable final ObjectCounter innerCounter, @Nullable final ObjectCounter outerCounter) { - if (innerCounter == null) { - if (outerCounter == null) { - return NoOpObjectCounter.getInstance(); - } else { - return outerCounter; - } - } else { - if (outerCounter == null) { - return innerCounter; - } else { - return new MultiObjectCounter(innerCounter, outerCounter); - } - } - } - - /** - * Figure out which counters to use for this task scheduler (if any), constructing them if they need to be - * constructed. - */ - @NonNull - protected Counters buildCounters() { - if (type == NO_OP) { - return new Counters(NoOpObjectCounter.getInstance(), NoOpObjectCounter.getInstance()); - } - - final ObjectCounter innerCounter; - - // If we need to enforce a maximum capacity, we have no choice but to use a backpressure object counter. - // - // If we don't need to enforce a maximum capacity, we need to use a standard object counter if any - // of the following conditions are true: - // - we have unhandled task metrics enabled - // - flushing is enabled. This is because our flush implementation is not - // compatible with a no-op counter. - // - // In all other cases, better to use a no-op counter. Counters have overhead, and if we don't need one - // then we shouldn't use one. - - if (model.isBackpressureEnabled() - && unhandledTaskCapacity != UNLIMITED_CAPACITY - && type != DIRECT - && type != DIRECT_THREADSAFE) { - - innerCounter = new BackpressureObjectCounter(name, unhandledTaskCapacity, sleepDuration); - } else if (unhandledTaskMetricEnabled || flushingEnabled) { - innerCounter = new StandardObjectCounter(sleepDuration); - } else { - innerCounter = null; - } - - return new Counters(combineCounters(innerCounter, onRamp), combineCounters(innerCounter, offRamp)); - } -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/builders/internal/StandardTaskSchedulerBuilder.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/builders/internal/StandardTaskSchedulerBuilder.java deleted file mode 100644 index 7c160b15301..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/builders/internal/StandardTaskSchedulerBuilder.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.schedulers.builders.internal; - -import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.DIRECT_THREADSAFE; -import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.NO_OP; - -import com.swirlds.common.context.PlatformContext; -import com.swirlds.common.metrics.FunctionGauge; -import com.swirlds.common.metrics.extensions.FractionalTimer; -import com.swirlds.common.metrics.extensions.NoOpFractionalTimer; -import com.swirlds.common.metrics.extensions.StandardFractionalTimer; -import org.hiero.wiring.framework.model.StandardWiringModel; -import org.hiero.wiring.framework.schedulers.TaskScheduler; -import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; -import org.hiero.wiring.framework.schedulers.internal.ConcurrentTaskScheduler; -import org.hiero.wiring.framework.schedulers.internal.DirectTaskScheduler; -import org.hiero.wiring.framework.schedulers.internal.NoOpTaskScheduler; -import org.hiero.wiring.framework.schedulers.internal.SequentialTaskScheduler; -import org.hiero.wiring.framework.schedulers.internal.SequentialThreadTaskScheduler; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import java.util.Objects; -import java.util.concurrent.ForkJoinPool; -import java.util.function.Supplier; - -/** - * A builder for {@link TaskScheduler}s. - * - * @param the output type of the primary output wire for this task scheduler (use {@link Void} for a scheduler - * with no output) - */ -public class StandardTaskSchedulerBuilder extends AbstractTaskSchedulerBuilder { - - /** - * Constructor. - * - * @param platformContext the platform context - * @param model the wiring model - * @param name the name of the task scheduler. Used for metrics and debugging. Must be unique. Must only - * contain alphanumeric characters and underscores. - * @param defaultPool the default fork join pool, if none is provided then this pool will be used - */ - public StandardTaskSchedulerBuilder( - @NonNull final PlatformContext platformContext, - @NonNull final StandardWiringModel model, - @NonNull final String name, - @NonNull final ForkJoinPool defaultPool) { - - super(platformContext, model, name, defaultPool); - } - - /** - * Build a busy timer if enabled. - * - * @return the busy timer, or null if not enabled - */ - @NonNull - private FractionalTimer buildBusyTimer() { - if (!busyFractionMetricEnabled || type == NO_OP) { - return NoOpFractionalTimer.getInstance(); - } - if (type == TaskSchedulerType.CONCURRENT) { - throw new IllegalStateException("Busy fraction metric is not compatible with concurrent schedulers"); - } - return new StandardFractionalTimer(platformContext.getTime()); - } - - /** - * Register all configured metrics. - * - * @param longSupplier the counter that is used to track the number of unhandled tasks - * @param busyFractionTimer the timer that is used to track the fraction of the time that the underlying thread - * is busy - */ - private void registerMetrics( - @Nullable final Supplier longSupplier, @NonNull final FractionalTimer busyFractionTimer) { - - if (type == NO_OP) { - return; - } - - if (unhandledTaskMetricEnabled) { - Objects.requireNonNull(longSupplier); - - final FunctionGauge.Config config = new FunctionGauge.Config<>( - "platform", name + "_unhandled_task_count", Long.class, longSupplier) - .withDescription( - "The number of scheduled tasks that have not been fully handled for the scheduler " + name); - platformContext.getMetrics().getOrCreate(config); - } - - if (busyFractionMetricEnabled) { - busyFractionTimer.registerMetric( - platformContext.getMetrics(), - "platform", - name + "_busy_fraction", - "Fraction (out of 1.0) of time spent processing tasks for the task scheduler " + name); - } - } - - /** - * {@inheritDoc} - */ - @Override - @NonNull - public TaskScheduler build() { - final Counters counters = buildCounters(); - final FractionalTimer busyFractionTimer = buildBusyTimer(); - final boolean insertionIsBlocking = - ((unhandledTaskCapacity != UNLIMITED_CAPACITY) || externalBackPressure) && (type != NO_OP); - - final TaskScheduler scheduler = - switch (type) { - case CONCURRENT -> new ConcurrentTaskScheduler<>( - model, - name, - pool, - buildUncaughtExceptionHandler(), - counters.onRamp(), - counters.offRamp(), - unhandledTaskCapacity, - flushingEnabled, - squelchingEnabled, - insertionIsBlocking); - case SEQUENTIAL -> new SequentialTaskScheduler<>( - model, - name, - pool, - buildUncaughtExceptionHandler(), - counters.onRamp(), - counters.offRamp(), - busyFractionTimer, - unhandledTaskCapacity, - flushingEnabled, - squelchingEnabled, - insertionIsBlocking); - case SEQUENTIAL_THREAD -> new SequentialThreadTaskScheduler<>( - model, - name, - buildUncaughtExceptionHandler(), - counters.onRamp(), - counters.offRamp(), - dataCounter, - busyFractionTimer, - unhandledTaskCapacity, - flushingEnabled, - squelchingEnabled, - insertionIsBlocking); - case DIRECT, DIRECT_THREADSAFE -> new DirectTaskScheduler<>( - model, - name, - buildUncaughtExceptionHandler(), - counters.onRamp(), - counters.offRamp(), - squelchingEnabled, - busyFractionTimer, - type == DIRECT_THREADSAFE); - case NO_OP -> new NoOpTaskScheduler<>(model, name, type, flushingEnabled, squelchingEnabled); - }; - - if (type != NO_OP) { - model.registerScheduler(scheduler, hyperlink); - } - - registerMetrics(scheduler::getUnprocessedTaskCount, busyFractionTimer); - - return scheduler; - } -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/ConcurrentTask.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/ConcurrentTask.java deleted file mode 100644 index 90e8025d8b5..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/ConcurrentTask.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.schedulers.internal; - -import org.hiero.wiring.framework.counters.ObjectCounter; -import org.hiero.wiring.framework.tasks.AbstractTask; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import java.lang.Thread.UncaughtExceptionHandler; -import java.util.concurrent.ForkJoinPool; -import java.util.function.Consumer; - -/** - * A task in a {@link ConcurrentTaskScheduler}. - */ -class ConcurrentTask extends AbstractTask { - - private final Consumer handler; - private final Object data; - private final ObjectCounter offRamp; - private final UncaughtExceptionHandler uncaughtExceptionHandler; - - /** - * Constructor. The task is created with zero dependencies, but not started automatically. It's - * the caller responsibility to start the task using {@link #send()} method. - * - * @param pool the fork join pool that will execute this task - * @param offRamp an object counter that is decremented when this task is executed - * @param uncaughtExceptionHandler the handler for uncaught exceptions - * @param handler the method that will be called when this task is executed - * @param data the data to be passed to the consumer for this task - */ - ConcurrentTask( - @NonNull final ForkJoinPool pool, - @NonNull final ObjectCounter offRamp, - @NonNull final UncaughtExceptionHandler uncaughtExceptionHandler, - @NonNull final Consumer handler, - @Nullable final Object data) { - super(pool, 0); - this.handler = handler; - this.data = data; - this.offRamp = offRamp; - this.uncaughtExceptionHandler = uncaughtExceptionHandler; - } - - /** - * {@inheritDoc} - */ - @Override - protected boolean exec() { - try { - handler.accept(data); - } catch (final Throwable t) { - uncaughtExceptionHandler.uncaughtException(Thread.currentThread(), t); - } finally { - offRamp.offRamp(); - } - return true; - } -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/ConcurrentTaskScheduler.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/ConcurrentTaskScheduler.java deleted file mode 100644 index a5e2e670f33..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/ConcurrentTaskScheduler.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.schedulers.internal; - -import org.hiero.wiring.framework.counters.ObjectCounter; -import org.hiero.wiring.framework.model.TraceableWiringModel; -import org.hiero.wiring.framework.schedulers.TaskScheduler; -import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.lang.Thread.UncaughtExceptionHandler; -import java.util.Objects; -import java.util.concurrent.ForkJoinPool; -import java.util.function.Consumer; - -/** - * A {@link TaskScheduler} that permits parallel execution of tasks. - * - * @param the output type of the scheduler (use {@link Void} for a task scheduler with no output type) - */ -public class ConcurrentTaskScheduler extends TaskScheduler { - - private final ObjectCounter onRamp; - private final ObjectCounter offRamp; - private final UncaughtExceptionHandler uncaughtExceptionHandler; - private final ForkJoinPool pool; - private final long capacity; - - /** - * Constructor. - * - * @param model the wiring model containing this scheduler - * @param name the name of the scheduler - * @param pool the fork join pool that will execute tasks on this scheduler - * @param uncaughtExceptionHandler the handler for uncaught exceptions - * @param onRamp an object counter that is incremented when data is added to the scheduler - * @param offRamp an object counter that is decremented when data is removed from the scheduler - * @param capacity the maximum desired capacity for this scheduler - * @param flushEnabled if true, then {@link #flush()} will be enabled, otherwise it will throw. - * @param squelchingEnabled if true, then squelching will be enabled, otherwise trying to squelch will throw - * @param insertionIsBlocking when data is inserted into this scheduler, will it block until capacity is - * available? - */ - public ConcurrentTaskScheduler( - @NonNull final TraceableWiringModel model, - @NonNull final String name, - @NonNull final ForkJoinPool pool, - @NonNull final UncaughtExceptionHandler uncaughtExceptionHandler, - @NonNull final ObjectCounter onRamp, - @NonNull final ObjectCounter offRamp, - final long capacity, - final boolean flushEnabled, - final boolean squelchingEnabled, - final boolean insertionIsBlocking) { - - super(model, name, TaskSchedulerType.CONCURRENT, flushEnabled, squelchingEnabled, insertionIsBlocking); - - this.pool = Objects.requireNonNull(pool); - this.uncaughtExceptionHandler = Objects.requireNonNull(uncaughtExceptionHandler); - this.onRamp = Objects.requireNonNull(onRamp); - this.offRamp = Objects.requireNonNull(offRamp); - this.capacity = capacity; - } - - /** - * {@inheritDoc} - */ - @Override - protected void put(@NonNull final Consumer handler, @NonNull final Object data) { - onRamp.onRamp(); - new ConcurrentTask(pool, offRamp, uncaughtExceptionHandler, handler, data).send(); - } - - /** - * {@inheritDoc} - */ - @Override - protected boolean offer(@NonNull final Consumer handler, @NonNull final Object data) { - final boolean accepted = onRamp.attemptOnRamp(); - if (accepted) { - new ConcurrentTask(pool, offRamp, uncaughtExceptionHandler, handler, data).send(); - } - return accepted; - } - - /** - * {@inheritDoc} - */ - @Override - protected void inject(@NonNull final Consumer handler, @NonNull final Object data) { - onRamp.forceOnRamp(); - new ConcurrentTask(pool, offRamp, uncaughtExceptionHandler, handler, data).send(); - } - - /** - * {@inheritDoc} - */ - @Override - public long getUnprocessedTaskCount() { - return onRamp.getCount(); - } - - /** - * {@inheritDoc} - */ - @Override - public long getCapacity() { - return capacity; - } - - /** - * {@inheritDoc} - */ - @Override - public void flush() { - throwIfFlushDisabled(); - onRamp.waitUntilEmpty(); - } -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/DefaultSquelcher.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/DefaultSquelcher.java deleted file mode 100644 index 811daf27711..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/DefaultSquelcher.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.schedulers.internal; - -import java.util.concurrent.atomic.AtomicBoolean; - -/** - * A squelcher that actually supports squelching. - */ -public class DefaultSquelcher implements Squelcher { - /** - * Whether or not tasks should actively be squelched. - */ - private final AtomicBoolean squelchFlag = new AtomicBoolean(false); - - /** - * {@inheritDoc} - */ - @Override - public void startSquelching() { - if (!squelchFlag.compareAndSet(false, true)) { - throw new IllegalStateException("Scheduler is already squelching"); - } - } - - /** - * {@inheritDoc} - */ - @Override - public void stopSquelching() { - if (!squelchFlag.compareAndSet(true, false)) { - throw new IllegalStateException("Scheduler is not currently squelching"); - } - } - - /** - * {@inheritDoc} - */ - @Override - public boolean shouldSquelch() { - return squelchFlag.get(); - } -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/DirectTaskScheduler.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/DirectTaskScheduler.java deleted file mode 100644 index 9d377228e0c..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/DirectTaskScheduler.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.schedulers.internal; - -import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerBuilder.UNLIMITED_CAPACITY; - -import com.swirlds.common.metrics.extensions.FractionalTimer; -import org.hiero.wiring.framework.counters.ObjectCounter; -import org.hiero.wiring.framework.model.TraceableWiringModel; -import org.hiero.wiring.framework.schedulers.TaskScheduler; -import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.lang.Thread.UncaughtExceptionHandler; -import java.util.Objects; -import java.util.function.Consumer; - -/** - * A scheduler that performs work immediately on the caller's thread. - * - * @param the output type of the scheduler (use {@link Void} for a task scheduler with no output type) - */ -public class DirectTaskScheduler extends TaskScheduler { - - private final UncaughtExceptionHandler uncaughtExceptionHandler; - private final ObjectCounter onRamp; - private final ObjectCounter offRamp; - private final FractionalTimer busyTimer; - - /** - * Constructor. - * - * @param model the wiring model containing this task scheduler - * @param name the name of the task scheduler - * @param uncaughtExceptionHandler the uncaught exception handler - * @param onRamp an object counter that is incremented when data is added to the task scheduler - * @param offRamp an object counter that is decremented when data is removed from the task - * @param squelchingEnabled if true, then squelching will be enabled, otherwise trying to squelch will throw - * @param busyTimer a timer that tracks the amount of time the task scheduler is busy - * @param threadsafe true if the work scheduled by this object is threadsafe - */ - public DirectTaskScheduler( - @NonNull final TraceableWiringModel model, - @NonNull final String name, - @NonNull final UncaughtExceptionHandler uncaughtExceptionHandler, - @NonNull final ObjectCounter onRamp, - @NonNull final ObjectCounter offRamp, - final boolean squelchingEnabled, - @NonNull final FractionalTimer busyTimer, - final boolean threadsafe) { - super( - model, - name, - threadsafe ? TaskSchedulerType.DIRECT_THREADSAFE : TaskSchedulerType.DIRECT, - false, - squelchingEnabled, - true); - - this.uncaughtExceptionHandler = Objects.requireNonNull(uncaughtExceptionHandler); - this.onRamp = Objects.requireNonNull(onRamp); - this.offRamp = Objects.requireNonNull(offRamp); - this.busyTimer = Objects.requireNonNull(busyTimer); - } - - /** - * {@inheritDoc} - */ - @Override - public long getUnprocessedTaskCount() { - return onRamp.getCount(); - } - - /** - * {@inheritDoc} - */ - @Override - public long getCapacity() { - // Direct schedulers have no concept of capacity. - return UNLIMITED_CAPACITY; - } - - /** - * {@inheritDoc} - */ - @Override - public void flush() { - throw new UnsupportedOperationException("Direct task schedulers do not support flushing"); - } - - /** - * {@inheritDoc} - */ - @Override - protected void put(@NonNull final Consumer handler, @NonNull final Object data) { - onRamp.onRamp(); - handleAndOffRamp(handler, data); - } - - /** - * {@inheritDoc} - */ - @Override - protected boolean offer(@NonNull final Consumer handler, @NonNull final Object data) { - final boolean accepted = onRamp.attemptOnRamp(); - if (!accepted) { - return false; - } - handleAndOffRamp(handler, data); - return true; - } - - /** - * {@inheritDoc} - */ - @Override - protected void inject(@NonNull final Consumer handler, @NonNull final Object data) { - onRamp.forceOnRamp(); - handleAndOffRamp(handler, data); - } - - /** - * Helper method. Handles the data and then off ramps. - * - * @param handler the handler - * @param data the data - */ - private void handleAndOffRamp(@NonNull final Consumer handler, @NonNull final Object data) { - busyTimer.activate(); - try { - handler.accept(data); - } catch (final Throwable t) { - uncaughtExceptionHandler.uncaughtException(Thread.currentThread(), t); - } - busyTimer.deactivate(); - offRamp.offRamp(); - } -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/NoOpTaskScheduler.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/NoOpTaskScheduler.java deleted file mode 100644 index 7cf28994342..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/NoOpTaskScheduler.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (C) 2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.schedulers.internal; - -import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerBuilder.UNLIMITED_CAPACITY; - -import org.hiero.wiring.framework.model.TraceableWiringModel; -import org.hiero.wiring.framework.schedulers.TaskScheduler; -import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; -import org.hiero.wiring.framework.wires.input.BindableInputWire; -import org.hiero.wiring.framework.wires.input.NoOpInputWire; -import org.hiero.wiring.framework.wires.output.NoOpOutputWire; -import org.hiero.wiring.framework.wires.output.StandardOutputWire; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.Objects; -import java.util.function.Consumer; - -/** - * A no-op task scheduler that does nothing. - * - * @param the output type of the scheduler (use {@link Void} for a task scheduler with no output type). This is - * just to appease the compiler, as this scheduler never produces output. - */ -public class NoOpTaskScheduler extends TaskScheduler { - - private final TraceableWiringModel model; - - /** - * Constructor. - * - * @param model the wiring model containing this task scheduler - * @param name the name of the task scheduler - * @param type the type of task scheduler - * @param flushEnabled if true, then {@link #flush()} will be enabled, otherwise it will throw. - * @param squelchingEnabled if true, then squelching will be enabled, otherwise trying to squelch will throw. - */ - public NoOpTaskScheduler( - @NonNull final TraceableWiringModel model, - @NonNull final String name, - @NonNull final TaskSchedulerType type, - final boolean flushEnabled, - final boolean squelchingEnabled) { - super(model, name, type, flushEnabled, squelchingEnabled, false); - - this.model = Objects.requireNonNull(model); - } - - /** - * {@inheritDoc} - */ - @Override - public long getUnprocessedTaskCount() { - return 0; - } - - @Override - public long getCapacity() { - // No op schedulers have no concept of capacity - return UNLIMITED_CAPACITY; - } - - /** - * {@inheritDoc} - */ - @Override - public void flush() { - throwIfFlushDisabled(); - } - - /** - * {@inheritDoc} - */ - @Override - protected void put(@NonNull final Consumer handler, @NonNull final Object data) { - throw new UnsupportedOperationException( - "Data should have been discarded before being sent to this no-op scheduler"); - } - - /** - * {@inheritDoc} - */ - @Override - protected boolean offer(@NonNull final Consumer handler, @NonNull final Object data) { - throw new UnsupportedOperationException( - "Data should have been discarded before being sent to this no-op scheduler"); - } - - /** - * {@inheritDoc} - */ - @Override - protected void inject(@NonNull final Consumer handler, @NonNull final Object data) { - throw new UnsupportedOperationException( - "Data should have been discarded before being sent to this no-op scheduler"); - } - - /** - * {@inheritDoc} - */ - @NonNull - @Override - protected StandardOutputWire buildPrimaryOutputWire( - @NonNull final TraceableWiringModel model, @NonNull final String name) { - return new NoOpOutputWire<>(model, getName()); - } - - /** - * {@inheritDoc} - */ - @NonNull - @Override - public StandardOutputWire buildSecondaryOutputWire() { - return new NoOpOutputWire<>(model, getName()); - } - - /** - * {@inheritDoc} - */ - @NonNull - @Override - public BindableInputWire buildInputWire(@NonNull final String name) { - return new NoOpInputWire<>(model, this, name); - } -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/SequentialTask.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/SequentialTask.java deleted file mode 100644 index 156b5a9299f..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/SequentialTask.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.schedulers.internal; - -import com.swirlds.common.metrics.extensions.FractionalTimer; -import org.hiero.wiring.framework.counters.ObjectCounter; -import org.hiero.wiring.framework.tasks.AbstractTask; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import java.lang.Thread.UncaughtExceptionHandler; -import java.util.concurrent.ForkJoinPool; -import java.util.function.Consumer; - -/** - * A task in a {@link SequentialTaskScheduler}. - */ -class SequentialTask extends AbstractTask { - private Consumer handler; - private Object data; - private SequentialTask nextTask; - private final ObjectCounter offRamp; - private final FractionalTimer busyTimer; - private final UncaughtExceptionHandler uncaughtExceptionHandler; - - /** - * Constructor. - * - * @param pool the fork join pool that will execute tasks on this task scheduler - * @param offRamp an object counter that is decremented when data is removed from the task - * scheduler - * @param busyTimer a timer that tracks the amount of time the task scheduler is busy - * @param uncaughtExceptionHandler the uncaught exception handler - * @param firstTask true if this is the first task in the scheduler, false otherwise - */ - SequentialTask( - @NonNull final ForkJoinPool pool, - @NonNull final ObjectCounter offRamp, - @NonNull final FractionalTimer busyTimer, - @NonNull final UncaughtExceptionHandler uncaughtExceptionHandler, - final boolean firstTask) { - super(pool, firstTask ? 1 : 2); - this.offRamp = offRamp; - this.busyTimer = busyTimer; - this.uncaughtExceptionHandler = uncaughtExceptionHandler; - } - - /** - * Provide a reference to the next task and the data that will be processed during the handling of this task. - * - * @param nextTask the task that will execute after this task - * @param handler the method that will be called when this task is executed - * @param data the data to be passed to the consumer for this task - */ - void send( - @NonNull final SequentialTask nextTask, - @NonNull final Consumer handler, - @Nullable final Object data) { - this.nextTask = nextTask; - this.handler = handler; - this.data = data; - - // This method provides us with the data we intend to send to the consumer - // when this task is executed, thus resolving one of the two dependencies - // required for the task to be executed. This call will decrement the - // dependency count. If this causes the dependency count to reach 0 - // (i.e. if the previous task has already been executed), then this call - // will cause this task to be immediately eligible for execution. - send(); - } - - /** - * Execute this task. - */ - @Override - public boolean exec() { - busyTimer.activate(); - try { - handler.accept(data); - } catch (final Throwable t) { - uncaughtExceptionHandler.uncaughtException(Thread.currentThread(), t); - } finally { - offRamp.offRamp(); - busyTimer.deactivate(); - - // Reduce the dependency count of the next task. If the next task already has its data, then this - // method will cause the next task to be immediately eligible for execution. - nextTask.send(); - } - return true; - } -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/SequentialTaskScheduler.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/SequentialTaskScheduler.java deleted file mode 100644 index 5ef032d25d3..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/SequentialTaskScheduler.java +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.schedulers.internal; - -import com.swirlds.common.metrics.extensions.FractionalTimer; -import org.hiero.wiring.framework.counters.ObjectCounter; -import org.hiero.wiring.framework.model.TraceableWiringModel; -import org.hiero.wiring.framework.schedulers.TaskScheduler; -import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.lang.Thread.UncaughtExceptionHandler; -import java.util.Objects; -import java.util.concurrent.ForkJoinPool; -import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Consumer; - -/** - * A {@link TaskScheduler} that guarantees that tasks are executed sequentially in the order they are received. - * - * @param the output type of the scheduler (use {@link Void} for a task scheduler with no output type) - */ -public class SequentialTaskScheduler extends TaskScheduler { - /** - * The next task to be scheduled will be inserted into this placeholder task. When that happens, a new task will be - * created and inserted into this placeholder. - */ - private final AtomicReference nextTaskPlaceholder; - - private final ObjectCounter onRamp; - private final ObjectCounter offRamp; - private final FractionalTimer busyTimer; - private final UncaughtExceptionHandler uncaughtExceptionHandler; - private final ForkJoinPool pool; - private final long capacity; - - /** - * Constructor. - * - * @param model the wiring model containing this scheduler - * @param name the name of the task scheduler - * @param pool the fork join pool that will execute tasks on this scheduler - * @param uncaughtExceptionHandler the uncaught exception handler - * @param onRamp an object counter that is incremented when data is added to the task scheduler - * @param offRamp an object counter that is decremented when data is removed from the task - * scheduler - * @param busyTimer a timer that tracks the amount of time the scheduler is busy - * @param capacity the maximum desired capacity for this task scheduler - * @param flushEnabled if true, then {@link #flush()} will be enabled, otherwise it will throw. - * @param squelchingEnabled if true, then squelching will be enabled, otherwise trying to squelch will throw - * @param insertionIsBlocking when data is inserted into this task scheduler, will it block until capacity is - * available? - */ - public SequentialTaskScheduler( - @NonNull final TraceableWiringModel model, - @NonNull final String name, - @NonNull ForkJoinPool pool, - @NonNull final UncaughtExceptionHandler uncaughtExceptionHandler, - @NonNull final ObjectCounter onRamp, - @NonNull final ObjectCounter offRamp, - @NonNull final FractionalTimer busyTimer, - final long capacity, - final boolean flushEnabled, - final boolean squelchingEnabled, - final boolean insertionIsBlocking) { - - super(model, name, TaskSchedulerType.SEQUENTIAL, flushEnabled, squelchingEnabled, insertionIsBlocking); - - this.pool = Objects.requireNonNull(pool); - this.uncaughtExceptionHandler = Objects.requireNonNull(uncaughtExceptionHandler); - this.onRamp = Objects.requireNonNull(onRamp); - this.offRamp = Objects.requireNonNull(offRamp); - this.busyTimer = Objects.requireNonNull(busyTimer); - this.capacity = capacity; - - this.nextTaskPlaceholder = - new AtomicReference<>(new SequentialTask(pool, offRamp, busyTimer, uncaughtExceptionHandler, true)); - } - - /** - * {@inheritDoc} - */ - @Override - protected void put(@NonNull final Consumer handler, @NonNull final Object data) { - onRamp.onRamp(); - scheduleTask(handler, data); - } - - /** - * {@inheritDoc} - */ - @Override - protected boolean offer(@NonNull final Consumer handler, @NonNull final Object data) { - final boolean accepted = onRamp.attemptOnRamp(); - if (accepted) { - scheduleTask(handler, data); - } - return accepted; - } - - /** - * {@inheritDoc} - */ - @Override - protected void inject(@NonNull final Consumer handler, @NonNull final Object data) { - onRamp.forceOnRamp(); - scheduleTask(handler, data); - } - - /** - * Schedule a task to be handled. This should only be called after successfully on-ramping (one way or another). - * - * @param handler the method that will be called when this task is executed - * @param data the data to be passed to the consumer for this task - */ - private void scheduleTask(@NonNull final Consumer handler, @NonNull final Object data) { - // This method may be called by many threads, but actual execution is required to happen serially. This method - // organizes tasks into a linked list. Tasks in this linked list are executed one at a time in order. - // When execution of one task is completed, execution of the next task is scheduled on the pool. - - final SequentialTask nextTask = new SequentialTask(pool, offRamp, busyTimer, uncaughtExceptionHandler, false); - SequentialTask currentTask; - do { - currentTask = nextTaskPlaceholder.get(); - } while (!nextTaskPlaceholder.compareAndSet(currentTask, nextTask)); - currentTask.send(nextTask, handler, data); - } - - /** - * {@inheritDoc} - */ - @Override - public long getUnprocessedTaskCount() { - return onRamp.getCount(); - } - - /** - * {@inheritDoc} - */ - @Override - public long getCapacity() { - return capacity; - } - - /** - * {@inheritDoc} - */ - @Override - public void flush() { - throwIfFlushDisabled(); - onRamp.waitUntilEmpty(); - } -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/SequentialThreadTask.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/SequentialThreadTask.java deleted file mode 100644 index 04f14bce995..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/SequentialThreadTask.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.schedulers.internal; - -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.function.Consumer; - -/** - * A task that is performed by a {@link SequentialThreadTaskScheduler}. - * - * @param handler the handler to call - * @param data the data to pass to the handler - */ -record SequentialThreadTask(@NonNull Consumer handler, @NonNull Object data) { - - /** - * Handle the task. - */ - public void handle() { - handler.accept(data); - } -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/SequentialThreadTaskScheduler.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/SequentialThreadTaskScheduler.java deleted file mode 100644 index 9435efc242f..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/SequentialThreadTaskScheduler.java +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.schedulers.internal; - -import com.swirlds.base.state.Startable; -import com.swirlds.base.state.Stoppable; -import com.swirlds.common.metrics.extensions.FractionalTimer; -import org.hiero.wiring.framework.counters.ObjectCounter; -import org.hiero.wiring.framework.model.TraceableWiringModel; -import org.hiero.wiring.framework.schedulers.TaskScheduler; -import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.lang.Thread.UncaughtExceptionHandler; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.Consumer; -import java.util.function.ToLongFunction; - -/** - * A scheduler that performs work sequentially on a dedicated thread. This class has very similar semantics to - * {@link DirectTaskScheduler}, except that work is done on a thread instead of on a fork join pool. - * - * @param the type of the primary output wire - */ -public class SequentialThreadTaskScheduler extends TaskScheduler implements Startable, Stoppable { - - private final UncaughtExceptionHandler uncaughtExceptionHandler; - private final ObjectCounter onRamp; - private final ObjectCounter offRamp; - private final ToLongFunction dataCounter; - private final FractionalTimer busyTimer; - private final long capacity; - - private final BlockingQueue tasks = new LinkedBlockingQueue<>(); - - private static final int BUFFER_SIZE = 1024; - - private final AtomicBoolean alive = new AtomicBoolean(true); - - private final Thread thread; - - /** - * Constructor. - * - * @param model the wiring model containing this task scheduler - * @param name the name of the task scheduler - * @param uncaughtExceptionHandler the handler to call when an exception is thrown by a task - * @param onRamp the counter to increment when a task is added to the queue - * @param offRamp the counter to decrement when a task is removed from the queue - * @param dataCounter the function to weight input data objects for health monitoring - * @param busyTimer the timer to activate when a task is being handled - * @param capacity the maximum desired capacity for this task scheduler - * @param flushEnabled if true, then {@link #flush()} will be enabled, otherwise it will throw. - * @param squelchingEnabled if true, then squelching will be enabled, otherwise trying to squelch will throw - * @param insertionIsBlocking when data is inserted into this task scheduler, will it block until capacity is - * available? - */ - public SequentialThreadTaskScheduler( - @NonNull final TraceableWiringModel model, - @NonNull final String name, - @NonNull final UncaughtExceptionHandler uncaughtExceptionHandler, - @NonNull final ObjectCounter onRamp, - @NonNull final ObjectCounter offRamp, - @NonNull final ToLongFunction dataCounter, - @NonNull final FractionalTimer busyTimer, - final long capacity, - final boolean flushEnabled, - final boolean squelchingEnabled, - final boolean insertionIsBlocking) { - super(model, name, TaskSchedulerType.SEQUENTIAL_THREAD, flushEnabled, squelchingEnabled, insertionIsBlocking); - - this.uncaughtExceptionHandler = Objects.requireNonNull(uncaughtExceptionHandler); - this.onRamp = Objects.requireNonNull(onRamp); - this.offRamp = Objects.requireNonNull(offRamp); - this.dataCounter = dataCounter; - this.busyTimer = Objects.requireNonNull(busyTimer); - this.capacity = capacity; - - thread = new Thread(this::run, ""); - } - - /** - * {@inheritDoc} - */ - @Override - public long getUnprocessedTaskCount() { - return onRamp.getCount(); - } - - /** - * {@inheritDoc} - */ - @Override - public long getCapacity() { - return capacity; - } - - /** - * {@inheritDoc} - */ - @Override - public void flush() { - throwIfFlushDisabled(); - onRamp.waitUntilEmpty(); - } - - /** - * {@inheritDoc} - */ - @Override - protected void put(@NonNull final Consumer handler, @NonNull final Object data) { - onRamp.onRamp(dataCounter.applyAsLong(data)); - tasks.add(new SequentialThreadTask(handler, data)); - } - - /** - * {@inheritDoc} - */ - @Override - protected boolean offer(@NonNull final Consumer handler, @NonNull final Object data) { - final boolean accepted = onRamp.attemptOnRamp(dataCounter.applyAsLong(data)); - if (!accepted) { - return false; - } - tasks.add(new SequentialThreadTask(handler, data)); - return true; - } - - /** - * {@inheritDoc} - */ - @Override - protected void inject(@NonNull final Consumer handler, @NonNull final Object data) { - onRamp.forceOnRamp(dataCounter.applyAsLong(data)); - tasks.add(new SequentialThreadTask(handler, data)); - } - - /** - * {@inheritDoc} - */ - @Override - public void start() { - thread.start(); - } - - /** - * {@inheritDoc} - */ - @Override - public void stop() { - alive.set(false); - } - - /** - * Take work off of the queue and handle it. - */ - private void run() { - final List buffer = new ArrayList<>(BUFFER_SIZE); - - while (alive.get()) { - if (tasks.drainTo(buffer, BUFFER_SIZE) == 0) { - try { - final SequentialThreadTask task = tasks.take(); - buffer.add(task); - } catch (final InterruptedException e) { - Thread.currentThread().interrupt(); - return; - } - } - - busyTimer.activate(); - for (final SequentialThreadTask task : buffer) { - try { - task.handle(); - } catch (final Throwable t) { - uncaughtExceptionHandler.uncaughtException(thread, t); - } finally { - offRamp.offRamp(dataCounter.applyAsLong(task.data())); - } - } - busyTimer.deactivate(); - - buffer.clear(); - } - } -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/Squelcher.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/Squelcher.java deleted file mode 100644 index b46595d56e9..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/Squelcher.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.schedulers.internal; - -/** - * Manages whether or not tasks scheduled by a given task scheduler should be squelched. - *

    - * Squelching is a mechanism that allows a task scheduler to temporarily suppress the execution of tasks. When a - * scheduler is being squelched, any new tasks that are received are simply discarded. Any previously scheduled tasks - * are either cleared, or executed as a no-op. - */ -public interface Squelcher { - /** - * Start squelching, and continue doing so until {@link #stopSquelching()} is called. - * - * @throws UnsupportedOperationException if squelching is not supported by this scheduler - * @throws IllegalStateException if scheduler is already squelching - */ - void startSquelching(); - - /** - * Stop squelching. - * - * @throws UnsupportedOperationException if squelching is not supported by this scheduler - * @throws IllegalStateException if scheduler is not currently squelching - */ - void stopSquelching(); - - /** - * Get whether or not tasks created by the relevant scheduler should be squelched. - *

    - * If squelching isn't enabled, then this method will always return false. - * - * @return true if tasks should be squelched, false otherwise - */ - boolean shouldSquelch(); -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/ThrowingSquelcher.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/ThrowingSquelcher.java deleted file mode 100644 index 11deec5ddb9..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/schedulers/internal/ThrowingSquelcher.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.schedulers.internal; - -/** - * A squelcher object that does not support squelching. - */ -public class ThrowingSquelcher implements Squelcher { - /** - * {@inheritDoc} - * - * @throws UnsupportedOperationException always - */ - @Override - public void startSquelching() { - throw new UnsupportedOperationException("Squelching is not supported by this task scheduler"); - } - - /** - * {@inheritDoc} - * - * @throws UnsupportedOperationException always - */ - @Override - public void stopSquelching() { - throw new UnsupportedOperationException("Squelching is not supported by this task scheduler"); - } - - /** - * {@inheritDoc} - * - * @return false - */ - @Override - public boolean shouldSquelch() { - return false; - } -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/tasks/AbstractTask.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/tasks/AbstractTask.java deleted file mode 100644 index 2c66f81e3db..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/tasks/AbstractTask.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.tasks; - -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.concurrent.ForkJoinPool; -import java.util.concurrent.ForkJoinTask; -import java.util.concurrent.ForkJoinWorkerThread; -import java.util.concurrent.atomic.AtomicInteger; - -/** - * A unit of work that is processed by a task scheduler. - */ -public abstract class AbstractTask extends ForkJoinTask { - - /** - * Counts outstanding dependencies. When it reaches 0, the task is ready to run. - */ - private final AtomicInteger dependencyCount; - - /** - * The fork join pool that will execute this task. - */ - private final ForkJoinPool pool; - - /** - * Constructor. - * - * @param pool the fork join pool that will execute this task - * @param dependencyCount the number of dependencies that must be satisfied before this task is eligible for - * execution - */ - protected AbstractTask(@NonNull final ForkJoinPool pool, final int dependencyCount) { - this.pool = pool; - this.dependencyCount = dependencyCount > 0 ? new AtomicInteger(dependencyCount) : null; - } - - /** - * Unused. - */ - @Override - public final Void getRawResult() { - return null; - } - - /** - * Unused. - */ - @Override - protected final void setRawResult(Void value) {} - - /** - * If the task has no dependencies then execute it. If the task has dependencies, decrement the dependency count and - * execute it if the resulting number of dependencies is zero. - */ - public void send() { - if (dependencyCount == null || dependencyCount.decrementAndGet() == 0) { - if ((Thread.currentThread() instanceof ForkJoinWorkerThread t) && (t.getPool() == pool)) { - fork(); - } else { - pool.execute(this); - } - } - } - - /** - * Execute the work represented by this task. - * - * @return true if this task is known to have been completed normally - */ - @Override - protected abstract boolean exec(); -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/transformers/AdvancedTransformation.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/transformers/AdvancedTransformation.java deleted file mode 100644 index adeda559d8f..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/transformers/AdvancedTransformation.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.transformers; - -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import org.hiero.wiring.framework.wires.output.OutputWire; - -/** - * Executes a transformation for an advanced transformer as created by - * {@link OutputWire#buildAdvancedTransformer(AdvancedTransformation)}. - * - * @param the original wire output type - * @param the output type of the transformer - */ -public interface AdvancedTransformation { - - /** - * Given data that comes off of the original output wire, this method transforms it before it is passed to each - * input wire that is connected to this transformer. Called once per data element per listener. - * - * @param a a data element from the original output wire - * @return the transformed data element, or null if the data should not be forwarded - */ - @Nullable - B transform(@NonNull A a); - - /** - * Called on the original data element after it has been forwarded to all listeners. This method can do cleanup if - * necessary. Doing nothing is perfectly ok if the use case does not require cleanup. - * - * @param a the original data element - */ - void inputCleanup(@NonNull A a); - - /** - * Called on the transformed data element if it is rejected by a listener. This is possible if offer soldering is - * used and the destination declines to take the data. - * - * @param b the transformed data element - */ - void outputCleanup(@NonNull B b); - - /** - * @return the name of this transformer - */ - @NonNull - String getTransformerName(); - - /** - * Return the name of the input wire that feeds data into this transformer. - * - * @return the name of the input wire - */ - @NonNull - String getTransformerInputName(); -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/transformers/RoutableData.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/transformers/RoutableData.java deleted file mode 100644 index 76c792164fe..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/transformers/RoutableData.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.transformers; - -import edu.umd.cs.findbugs.annotations.NonNull; - -/** - * Data that can be routed to a specific address. - * - * @param address the address to route to (will be an enum value from ROUTER_TYPE) - * @param data the data - * @param the type of the enum that defines the addresses - */ -public record RoutableData>(@NonNull ROUTER_TYPE address, @NonNull Object data) {} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/transformers/WireFilter.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/transformers/WireFilter.java deleted file mode 100644 index dcb7e65a91b..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/transformers/WireFilter.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.transformers; - -import org.hiero.wiring.framework.model.WiringModel; -import org.hiero.wiring.framework.schedulers.TaskScheduler; -import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; -import org.hiero.wiring.framework.wires.input.BindableInputWire; -import org.hiero.wiring.framework.wires.input.InputWire; -import org.hiero.wiring.framework.wires.output.OutputWire; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.Objects; -import java.util.function.Predicate; - -/** - * Filters out data, allowing some objects to pass and blocking others. - * - * @param the type of data being filtered - */ -public class WireFilter { - - private final BindableInputWire inputWire; - private final OutputWire outputWire; - - /** - * Constructor. Immediately binds the transformation function to the input wire. - * - * @param model the wiring model containing this output channel - * @param filterName the name of the filter - * @param filterInputName the label for the input wire going into the filter - * @param predicate only data that causes this method to return true is forwarded. This method must be very - * fast. Putting large amounts of work into this transformer violates the intended usage - * pattern of the wiring framework and may result in very poor system performance. - */ - public WireFilter( - @NonNull final WiringModel model, - @NonNull final String filterName, - @NonNull final String filterInputName, - @NonNull final Predicate predicate) { - - Objects.requireNonNull(predicate); - - final TaskScheduler taskScheduler = model.schedulerBuilder(filterName) - .withType(TaskSchedulerType.DIRECT_THREADSAFE) - .build() - .cast(); - - inputWire = taskScheduler.buildInputWire(filterInputName); - inputWire.bind(t -> { - if (predicate.test(t)) { - return t; - } - return null; - }); - outputWire = taskScheduler.getOutputWire(); - } - - /** - * Constructor. - * - * @param model the wiring model containing this output channel - * @param filterName the name of the filter - * @param filterInputName the label for the input wire going into the filter - */ - public WireFilter( - @NonNull final WiringModel model, @NonNull final String filterName, @NonNull final String filterInputName) { - - final TaskScheduler taskScheduler = model.schedulerBuilder(filterName) - .withType(TaskSchedulerType.DIRECT_THREADSAFE) - .build() - .cast(); - - inputWire = taskScheduler.buildInputWire(filterInputName); - outputWire = taskScheduler.getOutputWire(); - } - - /** - * Get the input wire for this filter. - * - * @return the input wire - */ - @NonNull - public InputWire getInputWire() { - return inputWire; - } - - /** - * Get the output wire for this filter. - * - * @return the output wire - */ - @NonNull - public OutputWire getOutputWire() { - return outputWire; - } - - /** - * Bind a predicate to this filter. Should not be called if this object was constructed using - * {@link #WireFilter(WiringModel, String, String, Predicate)}. Must be called prior to use if this object was - * constructed using {@link #WireFilter(WiringModel, String, String)}. - * - * @param predicate the predicate to bind - */ - public void bind(@NonNull final Predicate predicate) { - inputWire.bind(t -> { - if (predicate.test(t)) { - return t; - } - return null; - }); - } -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/transformers/WireListSplitter.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/transformers/WireListSplitter.java deleted file mode 100644 index 17b38f243f2..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/transformers/WireListSplitter.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.transformers; - -import org.hiero.wiring.framework.model.WiringModel; -import org.hiero.wiring.framework.schedulers.TaskScheduler; -import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; -import org.hiero.wiring.framework.wires.input.BindableInputWire; -import org.hiero.wiring.framework.wires.input.InputWire; -import org.hiero.wiring.framework.wires.output.OutputWire; -import org.hiero.wiring.framework.wires.output.StandardOutputWire; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.List; - -/** - * Transforms a list of items to a sequence of individual items. Expects that there will not be any null values in the - * collection. - * - * @param the type of data in the list that is being split - */ -public class WireListSplitter { - - private final BindableInputWire, T> inputWire; - private final StandardOutputWire outputWire; - - /** - * Constructor. - * - * @param model the wiring model containing this output wire - * @param splitterName the name of the output channel - * @param splitterInputName the label for the input wire going into the splitter - */ - public WireListSplitter( - @NonNull final WiringModel model, - @NonNull final String splitterName, - @NonNull final String splitterInputName) { - final TaskScheduler taskScheduler = model.schedulerBuilder(splitterName) - .withType(TaskSchedulerType.DIRECT_THREADSAFE) - .build() - .cast(); - - inputWire = taskScheduler.buildInputWire(splitterInputName); - outputWire = (StandardOutputWire) taskScheduler.getOutputWire(); - - inputWire.bindConsumer(list -> { - for (final T t : list) { - outputWire.forward(t); - } - }); - } - - /** - * Get the input wire for this splitter. - * - * @return the input wire - */ - @NonNull - public InputWire> getInputWire() { - return inputWire; - } - - /** - * Get the output wire for this splitter. - * - * @return the output wire - */ - @NonNull - public OutputWire getOutputWire() { - return outputWire; - } -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/transformers/WireRouter.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/transformers/WireRouter.java deleted file mode 100644 index fcf1e81185b..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/transformers/WireRouter.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (C) 2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.transformers; - -import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.DIRECT_THREADSAFE; - -import org.hiero.wiring.framework.model.WiringModel; -import org.hiero.wiring.framework.schedulers.TaskScheduler; -import org.hiero.wiring.framework.wires.input.BindableInputWire; -import org.hiero.wiring.framework.wires.input.InputWire; -import org.hiero.wiring.framework.wires.output.OutputWire; -import org.hiero.wiring.framework.wires.output.StandardOutputWire; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.ArrayList; -import java.util.List; - -/** - * Create a wire router. A wire router takes a single input and splits data into multiple outputs with different - * addresses. When data is sent to a router, the address is also sent. The router then sends the data to the output wire - * at the specified address. - * - * @param an enum that describes the addresses where data can be routed. Each enum value corresponds to a - * different address where data can be routed. - */ -public class WireRouter> { - - private final BindableInputWire, Void> inputWire; - private final List> outputWires; - private final Class clazz; - - /** - * Constructor. - * - * @param model the wiring model containing this router - * @param routerName the name of the router - * @param routerInputName the label for the input wire going into the router - * @param clazz the class of the enum that describes the different addresses that data can be routed to. - */ - public WireRouter( - @NonNull final WiringModel model, - @NonNull final String routerName, - @NonNull final String routerInputName, - @NonNull final Class clazz) { - final TaskScheduler scheduler = model.schedulerBuilder(routerName) - .withType(DIRECT_THREADSAFE) - .build() - .cast(); - - outputWires = new ArrayList<>(clazz.getEnumConstants().length); - for (int index = 0; index < clazz.getEnumConstants().length; index++) { - final ROUTER_TYPE dataType = clazz.getEnumConstants()[index]; - if (dataType.ordinal() != index) { - throw new IllegalArgumentException("Enum values must be in order"); - } - - final StandardOutputWire outputWire = scheduler.buildSecondaryOutputWire(); - outputWires.add(outputWire); - } - - inputWire = scheduler.buildInputWire(routerInputName); - inputWire.bindConsumer(this::routeData); - this.clazz = clazz; - } - - /** - * Get the input wire. - * - * @return the input wire - */ - @NonNull - public InputWire> getInput() { - return inputWire; - } - - /** - * Get the output wire for a specific address. - * - * @param address the data type - * @param the type of data that the output wire carries - * @return the output wire - */ - @NonNull - @SuppressWarnings("unchecked") - public OutputWire getOutput(@NonNull final ROUTER_TYPE address) { - return (OutputWire) outputWires.get(address.ordinal()); - } - - /** - * Get the type of the enum that defines this router. - * - * @return the class of the enum - */ - @NonNull - public Class getRouterType() { - return clazz; - } - - /** - * Route data to the appropriate output wire. - * - * @param routableData the data to route - */ - private void routeData(@NonNull final RoutableData routableData) { - final ROUTER_TYPE dataType = routableData.address(); - final StandardOutputWire outputWire = outputWires.get(dataType.ordinal()); - outputWire.forward(routableData.data()); - } -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/transformers/WireTransformer.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/transformers/WireTransformer.java deleted file mode 100644 index b6b83a0ea15..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/transformers/WireTransformer.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.transformers; - -import org.hiero.wiring.framework.model.WiringModel; -import org.hiero.wiring.framework.schedulers.TaskScheduler; -import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; -import org.hiero.wiring.framework.wires.input.BindableInputWire; -import org.hiero.wiring.framework.wires.input.InputWire; -import org.hiero.wiring.framework.wires.output.OutputWire; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.Objects; -import java.util.function.Function; - -/** - * Transforms data on a wire from one type to another. - * - * @param the input type - * @param the output type - */ -public class WireTransformer { - - private final BindableInputWire inputWire; - private final OutputWire outputWire; - - /** - * Constructor. Immediately binds the transformation function to the input wire. - * - * @param model the wiring model containing this output channel - * @param transformerName the name of the transformer - * @param transformerInputName the label for the input wire going into the transformer - * @param transformer an object that transforms from type A to type B. If this method returns null then no - * data is forwarded. This method must be very fast. Putting large amounts of work into - * this transformer violates the intended usage pattern of the wiring framework and may - * result in very poor system performance. - */ - public WireTransformer( - @NonNull final WiringModel model, - @NonNull final String transformerName, - @NonNull final String transformerInputName, - @NonNull final Function transformer) { - Objects.requireNonNull(transformer); - - final TaskScheduler taskScheduler = model.schedulerBuilder(transformerName) - .withType(TaskSchedulerType.DIRECT_THREADSAFE) - .build() - .cast(); - - inputWire = taskScheduler.buildInputWire(transformerInputName); - inputWire.bind(transformer); - outputWire = taskScheduler.getOutputWire(); - } - - /** - * Constructor. Requires the input wire to be bound later. - * - * @param model the wiring model containing this output channel - * @param transformerName the name of the transformer - * @param transformerInputName the label for the input wire going into the transformer - */ - public WireTransformer( - @NonNull final WiringModel model, - @NonNull final String transformerName, - @NonNull final String transformerInputName) { - - final TaskScheduler taskScheduler = model.schedulerBuilder(transformerName) - .withType(TaskSchedulerType.DIRECT_THREADSAFE) - .build() - .cast(); - - inputWire = taskScheduler.buildInputWire(transformerInputName); - outputWire = taskScheduler.getOutputWire(); - } - - /** - * Get the input wire for this transformer. - * - * @return the input wire - */ - @NonNull - public InputWire getInputWire() { - return inputWire; - } - - /** - * Get the output wire for this transformer. - * - * @return the output wire - */ - @NonNull - public OutputWire getOutputWire() { - return outputWire; - } - - /** - * Bind the transformation function to the input wire. Do not call this if the transformation function was provided - * in the constructor. Must be called prior to use if the transformation function was not provided in the - * constructor. - * - * @param transformer the transformation function - */ - public void bind(@NonNull final Function transformer) { - inputWire.bind(transformer); - } -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/SolderType.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/SolderType.java deleted file mode 100644 index 9a3e2a2ab34..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/SolderType.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.wires; - -import org.hiero.wiring.framework.wires.input.InputWire; - -/** - * The type of solder connection between an output wire and an input wire. - */ -public enum SolderType { - /** - * When data is passed to the input wire, call {@link InputWire#put(Object)}. May block if the input wire has - * backpressure enabled and the input wire is full. - */ - PUT, - /** - * When data is passed to the input wire, call {@link InputWire#inject(Object)}. Ignores back pressure. - */ - INJECT, - /** - * When data is passed to the input wire, call {@link InputWire#offer(Object)}. If the input wire has backpressure - * enabled and the input wire is full, then the data will be dropped. - */ - OFFER -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/input/Bindable.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/input/Bindable.java deleted file mode 100644 index d16be99c50c..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/input/Bindable.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.wires.input; - -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.function.Consumer; -import java.util.function.Function; - -/** - * An object that can be bound to a handler. - * - * @param the type of data that enters - * @param the type of data that is permitted to be passed out (non-null values are forwarded to the primary output - * wire) - */ -public interface Bindable { - - /** - * Bind this object to a handler. For things that don't send data to the output wire. - * - * @param handler the handler to bind to this input wire - * @throws IllegalStateException if a handler is already bound and this method is called a second time - */ - void bindConsumer(@NonNull Consumer handler); - - /** - * Bind this object to a handler. - * - * @param handler the handler to bind to this input task scheduler, values returned are passed to the primary output - * wire of the associated scheduler. - * @throws IllegalStateException if a handler is already bound and this method is called a second time - */ - void bind(@NonNull final Function handler); -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/input/BindableInputWire.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/input/BindableInputWire.java deleted file mode 100644 index c7c9f5152de..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/input/BindableInputWire.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.wires.input; - -import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.NO_OP; - -import org.hiero.wiring.framework.model.TraceableWiringModel; -import org.hiero.wiring.framework.schedulers.TaskScheduler; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.Objects; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.function.Supplier; - -/** - * An input wire that can be bound to an implementation. - * - * @param the type of data that passes into the wire - * @param the type of the primary output wire for the scheduler that is associated with this object - */ -public class BindableInputWire extends InputWire implements Bindable { - - private final TaskSchedulerInput taskSchedulerInput; - private final String taskSchedulerName; - private final TraceableWiringModel model; - - /** - * Supplier for whether the task scheduler is currently squelching. - *

    - * As long as this supplier returns true, the handler will be executed as a no-op, and no data will be forwarded. - */ - private final Supplier currentlySquelching; - - /** - * True if this is a wire on a no-op scheduler. - */ - private final boolean noOp; - - /** - * Constructor. - * - * @param model the wiring model containing this input wire - * @param taskScheduler the scheduler to insert data into - * @param name the name of the input wire - */ - public BindableInputWire( - @NonNull final TraceableWiringModel model, - @NonNull final TaskScheduler taskScheduler, - @NonNull final String name) { - super(taskScheduler, name); - this.model = Objects.requireNonNull(model); - taskSchedulerInput = Objects.requireNonNull(taskScheduler); - taskSchedulerName = taskScheduler.getName(); - currentlySquelching = taskScheduler::currentlySquelching; - - noOp = taskScheduler.getType() == NO_OP; - - if (noOp) { - return; - } - model.registerInputWireCreation(taskSchedulerName, name); - } - - /** - * {@inheritDoc} - */ - @SuppressWarnings("unchecked") - public void bindConsumer(@NonNull final Consumer handler) { - Objects.requireNonNull(handler); - if (noOp) { - return; - } - setHandler(i -> { - if (currentlySquelching.get()) { - return; - } - - handler.accept((IN) i); - }); - model.registerInputWireBinding(taskSchedulerName, getName()); - } - - /** - * {@inheritDoc} - */ - @SuppressWarnings("unchecked") - public void bind(@NonNull final Function handler) { - Objects.requireNonNull(handler); - if (noOp) { - return; - } - setHandler(i -> { - if (currentlySquelching.get()) { - return; - } - - final OUT output = handler.apply((IN) i); - if (output != null) { - taskSchedulerInput.forward(output); - } - }); - model.registerInputWireBinding(taskSchedulerName, getName()); - } -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/input/InputWire.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/input/InputWire.java deleted file mode 100644 index a2a36c6be09..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/input/InputWire.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.wires.input; - -import org.hiero.wiring.framework.schedulers.TaskScheduler; -import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.Objects; -import java.util.function.Consumer; - -/** - * An object that can insert work to be handled by a {@link TaskScheduler}. - * - * @param the type of data that passes into the wire - */ -public abstract class InputWire { - - private final TaskSchedulerInput taskSchedulerInput; - private Consumer handler; - private final String name; - private final String taskSchedulerName; - private final TaskSchedulerType taskSchedulerType; - - /** - * Constructor. - * - * @param taskScheduler the scheduler to insert data into - * @param name the name of the input wire - */ - protected InputWire(@NonNull final TaskScheduler taskScheduler, @NonNull final String name) { - this.taskSchedulerInput = Objects.requireNonNull(taskScheduler); - this.name = Objects.requireNonNull(name); - this.taskSchedulerName = taskScheduler.getName(); - this.taskSchedulerType = taskScheduler.getType(); - } - - /** - * Get the name of this input wire. - * - * @return the name of this input wire - */ - @NonNull - public String getName() { - return name; - } - - /** - * Get the name of the task scheduler this input channel is bound to. - * - * @return the name of the wire this input channel is bound to - */ - @NonNull - public String getTaskSchedulerName() { - return taskSchedulerName; - } - - /** - * Get the type of the task scheduler that this input channel is bound to. - * - * @return the type of the task scheduler that this input channel is bound to - */ - @NonNull - public TaskSchedulerType getTaskSchedulerType() { - return taskSchedulerType; - } - - /** - * Add a task to the task scheduler. May block if back pressure is enabled. - * - * @param data the data to be processed by the task scheduler - */ - public void put(@NonNull final IN data) { - taskSchedulerInput.put(handler, data); - } - - /** - * Add a task to the task scheduler. If backpressure is enabled and there is not immediately capacity available, - * this method will not accept the data. - * - * @param data the data to be processed by the task scheduler - * @return true if the data was accepted, false otherwise - */ - public boolean offer(@NonNull final IN data) { - return taskSchedulerInput.offer(handler, data); - } - - /** - * Inject data into the task scheduler, doing so even if it causes the number of unprocessed tasks to exceed the - * capacity specified by configured back pressure. If backpressure is disabled, this operation is logically - * equivalent to {@link #put(Object)}. - * - * @param data the data to be processed by the task scheduler - */ - public void inject(@NonNull final IN data) { - taskSchedulerInput.inject(handler, data); - } - - /** - * Set the method that will handle data traveling over this wire. - * - * @param handler the method that will handle data traveling over this wire - */ - protected void setHandler(@NonNull final Consumer handler) { - if (this.handler != null) { - throw new IllegalStateException("Handler already bound"); - } - this.handler = Objects.requireNonNull(handler); - } -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/input/NoOpInputWire.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/input/NoOpInputWire.java deleted file mode 100644 index 849f014e418..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/input/NoOpInputWire.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (C) 2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.wires.input; - -import org.hiero.wiring.framework.model.TraceableWiringModel; -import org.hiero.wiring.framework.schedulers.TaskScheduler; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.function.Consumer; -import java.util.function.Function; - -/** - * An input wire that doesn't actually do anything. When asked to bind a handler, it does nothing. When asked to insert - * data, it does nothing. - * - * @param the type of data that passes into the wire - * @param the type of the primary output wire for the scheduler that is associated with this object - */ -public class NoOpInputWire extends BindableInputWire { - /** - * Constructor. - * - * @param model the wiring model containing this input wire - * @param taskScheduler the scheduler to insert data into - * @param name the name of the input wire - */ - public NoOpInputWire( - @NonNull final TraceableWiringModel model, - @NonNull final TaskScheduler taskScheduler, - @NonNull final String name) { - super(model, taskScheduler, name); - } - - /** - * {@inheritDoc} - */ - @Override - public void bindConsumer(@NonNull final Consumer handler) { - // intentional no-op - } - - /** - * {@inheritDoc} - */ - @Override - public void bind(@NonNull final Function handler) { - // intentional no-op - } - - /** - * {@inheritDoc} - */ - @Override - public void put(@NonNull final IN data) { - // intentional no-op - } - - /** - * {@inheritDoc} - */ - @Override - public boolean offer(@NonNull final IN data) { - return true; - } - - /** - * {@inheritDoc} - */ - @Override - public void inject(@NonNull final IN data) { - // intentional no-op - } -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/input/TaskSchedulerInput.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/input/TaskSchedulerInput.java deleted file mode 100644 index 6655ac16572..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/input/TaskSchedulerInput.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.wires.input; - -import org.hiero.wiring.framework.schedulers.TaskScheduler; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.function.Consumer; - -/** - * An object that knows how to add data to a {@link TaskScheduler} for processing, and how to forward data to a task - * scheduler's output. This class is defined inside the input wire package to prevent anything that isn't an input wire - * from accessing its methods. - */ -public abstract class TaskSchedulerInput { - - /** - * Add a task to the scheduler. May block if back pressure is enabled. - * - * @param handler handles the provided data - * @param data the data to be processed by the task scheduler - */ - protected abstract void put(@NonNull Consumer handler, @NonNull Object data); - - /** - * Add a task to the scheduler. If backpressure is enabled and there is not immediately capacity available, this - * method will not accept the data. - * - * @param handler handles the provided data - * @param data the data to be processed by the scheduler - * @return true if the data was accepted, false otherwise - */ - protected abstract boolean offer(@NonNull Consumer handler, @NonNull Object data); - - /** - * Inject data into the scheduler, doing so even if it causes the number of unprocessed tasks to exceed the capacity - * specified by configured back pressure. If backpressure is disabled, this operation is logically equivalent to - * {@link #put(Consumer, Object)}. - * - * @param handler handles the provided data - * @param data the data to be processed by the scheduler - */ - protected abstract void inject(@NonNull Consumer handler, @NonNull Object data); - - /** - * Pass data to this scheduler's primary output wire. - *

    - * This method is implemented here to allow classes in this package to call forward(), which otherwise would not be - * visible. - */ - protected abstract void forward(@NonNull final OUT data); -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/output/NoOpOutputWire.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/output/NoOpOutputWire.java deleted file mode 100644 index 40541d70f74..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/output/NoOpOutputWire.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (C) 2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.wires.output; - -import org.hiero.wiring.framework.model.TraceableWiringModel; -import org.hiero.wiring.framework.transformers.AdvancedTransformation; -import org.hiero.wiring.framework.wires.SolderType; -import org.hiero.wiring.framework.wires.input.InputWire; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.function.Predicate; - -/** - * An output wire that doesn't actually do anything. When asked to solder to another wire, it does nothing. When asked - * to build a transformer (or variations there upon) it produces no-op implementations. - * - * @param the type of data passed to the forwarding method - */ -public class NoOpOutputWire extends StandardOutputWire { - - /** - * Constructor. - * - * @param model the wiring model containing this output wire - * @param name the name of the output wire - */ - public NoOpOutputWire(@NonNull final TraceableWiringModel model, @NonNull final String name) { - super(model, name); - } - - /** - * {@inheritDoc} - */ - @Override - protected void addForwardingDestination(@NonNull final Consumer destination) { - // intentional no-op - } - - /** - * {@inheritDoc} - */ - @Override - public void forward(@NonNull final OUT data) { - // intentional no-op - } - - /** - * {@inheritDoc} - */ - @Override - public void solderTo(@NonNull final InputWire inputWire, @NonNull final SolderType solderType) { - // intentional no-op - } - - /** - * {@inheritDoc} - */ - @Override - public void solderTo( - @NonNull final String handlerName, - @NonNull final String inputWireLabel, - final @NonNull Consumer handler) { - // intentional no-op - } - - /** - * {@inheritDoc} - */ - @NonNull - @Override - public OutputWire buildFilter( - @NonNull final String filterName, - @NonNull final String filterInputName, - @NonNull final Predicate predicate) { - return new NoOpOutputWire<>(getModel(), filterName); - } - - /** - * {@inheritDoc} - */ - @NonNull - @Override - public OutputWire buildSplitter( - @NonNull final String splitterName, @NonNull final String splitterInputName) { - return new NoOpOutputWire<>(getModel(), splitterName); - } - - /** - * {@inheritDoc} - */ - @NonNull - @Override - public OutputWire buildTransformer( - @NonNull final String transformerName, - @NonNull final String transformerInputName, - @NonNull final Function transformer) { - return new NoOpOutputWire<>(getModel(), transformerName); - } - - /** - * {@inheritDoc} - */ - @NonNull - @Override - public OutputWire buildAdvancedTransformer( - @NonNull final AdvancedTransformation transformer) { - return new NoOpOutputWire<>(getModel(), transformer.getTransformerName()); - } -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/output/OutputWire.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/output/OutputWire.java deleted file mode 100644 index 183a025316c..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/output/OutputWire.java +++ /dev/null @@ -1,289 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.wires.output; - -import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.NO_OP; - -import org.hiero.wiring.framework.model.TraceableWiringModel; -import org.hiero.wiring.framework.schedulers.TaskScheduler; -import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; -import org.hiero.wiring.framework.transformers.AdvancedTransformation; -import org.hiero.wiring.framework.transformers.WireFilter; -import org.hiero.wiring.framework.transformers.WireListSplitter; -import org.hiero.wiring.framework.transformers.WireTransformer; -import org.hiero.wiring.framework.wires.SolderType; -import org.hiero.wiring.framework.wires.input.BindableInputWire; -import org.hiero.wiring.framework.wires.input.InputWire; -import org.hiero.wiring.framework.wires.output.internal.TransformingOutputWire; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.List; -import java.util.Objects; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.function.Predicate; - -/** - * Describes the output of a task scheduler. Can be soldered to wire inputs or lambdas. - * - * @param the output type of the object - */ -public abstract class OutputWire { - - private final TraceableWiringModel model; - private final String name; - - /** - * Constructor. - * - * @param model the wiring model containing this output wire - * @param name the name of the output wire - */ - public OutputWire(@NonNull final TraceableWiringModel model, @NonNull final String name) { - this.model = Objects.requireNonNull(model); - this.name = Objects.requireNonNull(name); - } - - /** - * Get the name of this output wire. If this object is a task scheduler, this is the same as the name of the task - * scheduler. - * - * @return the name - */ - @NonNull - public String getName() { - return name; - } - - /** - * Get the wiring model that contains this output wire. - * - * @return the wiring model - */ - @NonNull - protected TraceableWiringModel getModel() { - return model; - } - - /** - * Specify an input wire where output data should be passed. This forwarding operation respects back pressure. - * Equivalent to calling {@link #solderTo(InputWire, SolderType)} with {@link SolderType#PUT}. - * - *

    - * Soldering is the act of connecting two wires together, usually by melting a metal alloy between them. See - * wikipedia's entry on soldering. - * - *

    - * Forwarding should be fully configured prior to data being inserted into the system. Adding forwarding - * destinations after data has been inserted into the system is not thread safe and has undefined behavior. - * - * @param inputWire the input wire to forward output data to - */ - public void solderTo(@NonNull final InputWire inputWire) { - solderTo(inputWire, SolderType.PUT); - } - - /** - * A convenience method that should be used iff the order in which the {@code inputWires} are soldered is important. - * Using this method reduces the chance of inadvertent reordering when code is modified or reorganized. All - * invocations of this method should carefully document why the provided ordering is important. - *

    - * Since this method is specifically for input wires that require a certain order, at least two input wires must be - * provided. - * - * @param inputWires – an ordered list of the input wire to forward output data to - * @throws IllegalArgumentException if the size of {@code inputWires} is less than 2 - * @see #solderTo(InputWire) - */ - public void orderedSolderTo(@NonNull final List> inputWires) { - if (inputWires.size() < 2) { - throw new IllegalArgumentException("List must contain at least 2 input wires."); - } - inputWires.forEach(this::solderTo); - } - - /** - * Specify an input wire where output data should be passed. This forwarding operation respects back pressure. - * - *

    - * Soldering is the act of connecting two wires together, usually by melting a metal alloy between them. See - * wikipedia's entry on soldering. - * - *

    - * Forwarding should be fully configured prior to data being inserted into the system. Adding forwarding - * destinations after data has been inserted into the system is not thread safe and has undefined behavior. - * - * @param inputWire the input wire to forward output data to - * @param solderType the semantics of the soldering operation - */ - public void solderTo(@NonNull final InputWire inputWire, @NonNull final SolderType solderType) { - if (inputWire.getTaskSchedulerType() == NO_OP) { - return; - } - - model.registerEdge(name, inputWire.getTaskSchedulerName(), inputWire.getName(), solderType); - - switch (solderType) { - case PUT -> addForwardingDestination(inputWire::put); - case INJECT -> addForwardingDestination(inputWire::inject); - case OFFER -> addForwardingDestination(inputWire::offer); - default -> throw new IllegalArgumentException("Unknown solder type: " + solderType); - } - } - - /** - * Specify a consumer where output data should be forwarded. This method creates a direct task scheduler under the - * hood and forwards output data to it. - * - *

    - * Soldering is the act of connecting two wires together, usually by melting a metal alloy between them. See - * wikipedia's entry on soldering. - * - *

    - * Forwarding should be fully configured prior to data being inserted into the system. Adding forwarding - * destinations after data has been inserted into the system is not thread safe and has undefined behavior. - * - * @param handlerName the name of the consumer - * @param inputWireLabel the label for the input wire going into the consumer - * @param handler the consumer to forward output data to - */ - public void solderTo( - @NonNull final String handlerName, - @NonNull final String inputWireLabel, - @NonNull final Consumer handler) { - - final TaskScheduler directScheduler = model.schedulerBuilder(handlerName) - .withType(TaskSchedulerType.DIRECT) - .build() - .cast(); - - final BindableInputWire directSchedulerInputWire = directScheduler.buildInputWire(inputWireLabel); - directSchedulerInputWire.bindConsumer(handler); - - this.solderTo(directSchedulerInputWire); - } - - /** - * Build a {@link WireFilter}. The input wire to the filter is automatically soldered to this output wire (i.e. all - * data that comes out of the wire will be inserted into the filter). The output wire of the filter is returned by - * this method. - * - * @param filterName the name of the filter - * @param filterInputName the label for the input wire going into the filter - * @param predicate the predicate that filters the output of this wire - * @return the output wire of the filter - */ - @NonNull - public OutputWire buildFilter( - @NonNull final String filterName, - @NonNull final String filterInputName, - @NonNull final Predicate predicate) { - - Objects.requireNonNull(filterName); - Objects.requireNonNull(filterInputName); - Objects.requireNonNull(predicate); - - final WireFilter filter = new WireFilter<>(model, filterName, filterInputName, predicate); - solderTo(filter.getInputWire()); - return filter.getOutputWire(); - } - - /** - * Build a {@link WireListSplitter}. Creating a splitter for wires without a list output type will cause runtime - * exceptions. The input wire to the splitter is automatically soldered to this output wire (i.e. all data that - * comes out of the wire will be inserted into the splitter). The output wire of the splitter is returned by this - * method. - * - * @param the type of the list elements - * @return output wire of the splitter - */ - @SuppressWarnings("unchecked") - @NonNull - public OutputWire buildSplitter( - @NonNull final String splitterName, @NonNull final String splitterInputName) { - - Objects.requireNonNull(splitterName); - Objects.requireNonNull(splitterInputName); - - final WireListSplitter splitter = new WireListSplitter<>(model, splitterName, splitterInputName); - solderTo((InputWire) splitter.getInputWire()); - return splitter.getOutputWire(); - } - - /** - * Build a {@link WireTransformer}. The input wire to the transformer is automatically soldered to this output wire - * (i.e. all data that comes out of the wire will be inserted into the transformer). The output wire of the - * transformer is returned by this method. - * - * @param transformerName the name of the transformer - * @param transformerInputName the label for the input wire going into the transformer - * @param transformer the function that transforms the output of this wire into the output of the - * transformer. Called once per data item. Null data returned by this method is not - * forwarded. - * @param the output type of the transformer - * @return the output wire of the transformer - */ - @NonNull - public OutputWire buildTransformer( - @NonNull final String transformerName, - @NonNull final String transformerInputName, - @NonNull final Function transformer) { - - Objects.requireNonNull(transformerName); - Objects.requireNonNull(transformerInputName); - Objects.requireNonNull(transformer); - - final WireTransformer wireTransformer = - new WireTransformer<>(model, transformerName, transformerInputName, transformer); - solderTo(wireTransformer.getInputWire()); - return wireTransformer.getOutputWire(); - } - - /** - * Build a transformation wire with cleanup functionality. - *

    - * The input wire to the transformer is automatically soldered to this output wire (i.e. all data that comes out of - * the wire will be inserted into the transformer). The output wire of the transformer is returned by this method. - * Similar to {@link #buildTransformer(String, String, Function)}, but instead of the transformer method being - * called once per data item, it is called once per output per data item. - * - * @param transformer an object that manages the transformation - * @param the output type of the transformer - * @return the output wire of the transformer - */ - @NonNull - public OutputWire buildAdvancedTransformer( - @NonNull final AdvancedTransformation transformer) { - - final TransformingOutputWire outputWire = new TransformingOutputWire<>( - model, - transformer.getTransformerName(), - transformer::transform, - transformer::inputCleanup, - transformer::outputCleanup); - - solderTo(transformer.getTransformerName(), transformer.getTransformerInputName(), outputWire::forward); - - return outputWire; - } - - /** - * Creates a new forwarding destination. - * - * @param destination the destination to forward data to - */ - protected abstract void addForwardingDestination(@NonNull final Consumer destination); -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/output/StandardOutputWire.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/output/StandardOutputWire.java deleted file mode 100644 index 347ec7a9c1c..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/output/StandardOutputWire.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.wires.output; - -import static com.swirlds.logging.legacy.LogMarker.EXCEPTION; - -import org.hiero.wiring.framework.model.TraceableWiringModel; -import org.hiero.wiring.framework.wires.output.internal.ForwardingOutputWire; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.function.Consumer; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -/** - * An output wire that will take data and forward it to its outputs. Output type is the same as the input type. - * - * @param the type of data passed to the forwarding method - */ -public class StandardOutputWire extends ForwardingOutputWire { - - private static final Logger logger = LogManager.getLogger(StandardOutputWire.class); - - private final List> forwardingDestinations = new ArrayList<>(); - - /** - * Constructor. - * - * @param model the wiring model containing this output wire - * @param name the name of the output wire - */ - public StandardOutputWire(@NonNull final TraceableWiringModel model, @NonNull final String name) { - super(model, name); - } - - /** - * {@inheritDoc} - */ - @Override - protected void addForwardingDestination(@NonNull final Consumer destination) { - Objects.requireNonNull(destination); - forwardingDestinations.add(destination); - } - - /** - * {@inheritDoc} - */ - @Override - public void forward(@NonNull final OUT data) { - for (final Consumer destination : forwardingDestinations) { - try { - destination.accept(data); - } catch (final Exception e) { - logger.error( - EXCEPTION.getMarker(), - "Exception thrown on output wire {} while forwarding data {}", - getName(), - data, - e); - } - } - } -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/output/internal/ForwardingOutputWire.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/output/internal/ForwardingOutputWire.java deleted file mode 100644 index f8eebe9db22..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/output/internal/ForwardingOutputWire.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.wires.output.internal; - -import org.hiero.wiring.framework.model.TraceableWiringModel; -import org.hiero.wiring.framework.wires.output.OutputWire; -import edu.umd.cs.findbugs.annotations.NonNull; - -/** - * An output wire that will take data and forward it to its outputs. - * - * @param the type of data passed to the forwarding method - * @param the type of data forwarded to things soldered to this wire - */ -public abstract class ForwardingOutputWire extends OutputWire { - - /** - * Constructor. - * - * @param model the wiring model containing this output wire - * @param name the name of the output wire - */ - protected ForwardingOutputWire(@NonNull final TraceableWiringModel model, final @NonNull String name) { - super(model, name); - } - - /** - * Forward output data to any wires/consumers that are listening for it. - *

    - * Although it will technically work, it is a violation of convention to directly put data into this output wire - * except from within code being executed by the task scheduler that owns this output wire. Don't do it. - * - * @param data the output data to forward - */ - public abstract void forward(@NonNull final IN data); -} diff --git a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/output/internal/TransformingOutputWire.java b/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/output/internal/TransformingOutputWire.java deleted file mode 100644 index ab8cf59fe7f..00000000000 --- a/platform-sdk/swirlds-common/src/main/java/org/hiero/wiring/framework/wires/output/internal/TransformingOutputWire.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 org.hiero.wiring.framework.wires.output.internal; - -import static com.swirlds.logging.legacy.LogMarker.EXCEPTION; - -import org.hiero.wiring.framework.model.TraceableWiringModel; -import org.hiero.wiring.framework.wires.SolderType; -import org.hiero.wiring.framework.wires.input.InputWire; -import org.hiero.wiring.framework.wires.output.OutputWire; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.function.Consumer; -import java.util.function.Function; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -/** - * An output wire that transforms data that flows across it. For advanced use cases where - * {@link OutputWire#buildTransformer(String, String, Function)} semantics are insufficient. - * - * @param the type of data passed to the forwarding method - * @param the type of data forwarded to things soldered to this wire - */ -public class TransformingOutputWire extends ForwardingOutputWire { - - private static final Logger logger = LogManager.getLogger(TransformingOutputWire.class); - private final List> forwardingDestinations = new ArrayList<>(); - - private final Function transform; - private final Consumer inputCleanup; - private final Consumer outputCleanup; - - /** - * Constructor. - * - * @param model the wiring model containing this output wire - * @param name the name of the output wire - * @param transformer the function to transform the data from the input type to the output type. Is called once - * per output per data item. If this method returns null then the data is not forwarded. - * @param inputCleanup an optional method that is called on input data after the data is forwarded to all - * destinations. The original data is passed to this method. Ignored if null. - * @param outputCleanup an optional method that is called on output data if it is rejected by a destination. This is - * possible if offer soldering is used and the destination declines to take the data. - */ - public TransformingOutputWire( - @NonNull final TraceableWiringModel model, - @NonNull final String name, - @NonNull final Function transformer, - @Nullable final Consumer inputCleanup, - @Nullable final Consumer outputCleanup) { - super(model, name); - - this.transform = Objects.requireNonNull(transformer); - this.inputCleanup = inputCleanup == null ? (data) -> {} : inputCleanup; - this.outputCleanup = outputCleanup == null ? (data) -> {} : outputCleanup; - } - - /** - * {@inheritDoc} - */ - @Override - protected void addForwardingDestination(@NonNull final Consumer destination) { - Objects.requireNonNull(destination); - forwardingDestinations.add(destination); - } - - /** - * {@inheritDoc} - */ - @Override - public void forward(@NonNull final IN data) { - for (final Consumer destination : forwardingDestinations) { - try { - final OUT transformed = transform.apply(data); - if (transformed == null) { - // Do not forward null values. - return; - } - destination.accept(transformed); - } catch (final Exception e) { - logger.error( - EXCEPTION.getMarker(), - "Exception thrown on output wire {} while forwarding data {}", - getName(), - data, - e); - } - } - inputCleanup.accept(data); - } - - /** - * {@inheritDoc} - */ - @Override - public void solderTo(@NonNull final InputWire inputWire, @NonNull final SolderType solderType) { - getModel().registerEdge(getName(), inputWire.getTaskSchedulerName(), inputWire.getName(), solderType); - - switch (solderType) { - case PUT -> addForwardingDestination(inputWire::put); - case INJECT -> addForwardingDestination(inputWire::inject); - case OFFER -> addForwardingDestination(x -> { - if (!inputWire.offer(x)) { - outputCleanup.accept(x); - } - }); - default -> throw new IllegalArgumentException("Unknown solder type: " + solderType); - } - } -} diff --git a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/benchmark/WiringBenchmark.java b/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/benchmark/WiringBenchmark.java deleted file mode 100644 index 293d85b44d6..00000000000 --- a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/benchmark/WiringBenchmark.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 com.swirlds.common.wiring.benchmark; - -import static java.util.concurrent.ForkJoinPool.defaultForkJoinWorkerThreadFactory; -import static java.util.concurrent.TimeUnit.SECONDS; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import com.swirlds.common.context.PlatformContext; -import com.swirlds.common.test.fixtures.platform.TestPlatformContextBuilder; -import org.hiero.wiring.framework.counters.BackpressureObjectCounter; -import org.hiero.wiring.framework.counters.ObjectCounter; -import org.hiero.wiring.framework.model.WiringModel; -import org.hiero.wiring.framework.model.WiringModelBuilder; -import org.hiero.wiring.framework.schedulers.TaskScheduler; -import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; -import org.hiero.wiring.framework.wires.input.BindableInputWire; -import java.time.Duration; -import java.util.concurrent.ForkJoinPool; - -class WiringBenchmark { - - /* Data flow for this benchmark: - - gossip -> event verifier -> orphan buffer - ^ | - | | - --------------------------------- - - */ - - static void basicBenchmark() throws InterruptedException { - - // We will use this executor for starting all threads. Maybe we should only use it for temporary threads? - final ForkJoinPool executor = new ForkJoinPool( - Runtime.getRuntime().availableProcessors(), - defaultForkJoinWorkerThreadFactory, - (t, e) -> { - System.out.println("Uncaught exception in thread " + t.getName()); - e.printStackTrace(); - }, - true); - - final PlatformContext platformContext = - TestPlatformContextBuilder.create().build(); - final WiringModel model = WiringModelBuilder.create(platformContext).build(); - - // Ensures that we have no more than 10,000 events in the pipeline at any given time - final ObjectCounter backpressure = new BackpressureObjectCounter("backpressure", 10_000, Duration.ZERO); - - final TaskScheduler verificationTaskScheduler = model.schedulerBuilder("verification") - .withPool(executor) - .withType(TaskSchedulerType.CONCURRENT) - .withOnRamp(backpressure) - .withExternalBackPressure(true) - .build() - .cast(); - - final TaskScheduler orphanBufferTaskScheduler = model.schedulerBuilder("orphanBuffer") - .withPool(executor) - .withType(TaskSchedulerType.SEQUENTIAL) - .withExternalBackPressure(true) - .build() - .cast(); - - final TaskScheduler eventPoolTaskScheduler = model.schedulerBuilder("eventPool") - .withPool(executor) - .withType(TaskSchedulerType.SEQUENTIAL) - .withOffRamp(backpressure) - .withExternalBackPressure(true) - .build() - .cast(); - - final BindableInputWire eventsToOrphanBuffer = - orphanBufferTaskScheduler.buildInputWire("unordered events"); - - final BindableInputWire eventsToBeVerified = - verificationTaskScheduler.buildInputWire("unverified events"); - - final BindableInputWire eventsToInsertBackIntoEventPool = - eventPoolTaskScheduler.buildInputWire("verified events"); - - verificationTaskScheduler.getOutputWire().solderTo(eventsToOrphanBuffer); - orphanBufferTaskScheduler.getOutputWire().solderTo(eventsToInsertBackIntoEventPool); - - final WiringBenchmarkEventPool eventPool = new WiringBenchmarkEventPool(); - final WiringBenchmarkTopologicalEventSorter orphanBuffer = new WiringBenchmarkTopologicalEventSorter(); - final WiringBenchmarkEventVerifier verifier = new WiringBenchmarkEventVerifier(); - final WiringBenchmarkGossip gossip = new WiringBenchmarkGossip(executor, eventPool, eventsToBeVerified::put); - - eventsToOrphanBuffer.bind(orphanBuffer); - eventsToBeVerified.bind(verifier); - eventsToInsertBackIntoEventPool.bindConsumer(eventPool::checkin); - - // Create a user thread for running "gossip". It will continue to generate events until explicitly stopped. - System.out.println("Starting gossip"); - gossip.start(); - SECONDS.sleep(120); - gossip.stop(); - - // Validate that all events have been seen by orphanBuffer - final long timeout = System.currentTimeMillis() + 1000; - boolean success = false; - while (System.currentTimeMillis() < timeout) { - if (orphanBuffer.getCheckSum() == gossip.getCheckSum()) { - success = true; - break; - } - } - assertTrue(success); - } - - public static void main(String[] args) { - try { - basicBenchmark(); - } catch (final Throwable t) { - t.printStackTrace(); - } - } -} diff --git a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/benchmark/WiringBenchmarkEvent.java b/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/benchmark/WiringBenchmarkEvent.java deleted file mode 100644 index dcbbb9d1cbd..00000000000 --- a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/benchmark/WiringBenchmarkEvent.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 com.swirlds.common.wiring.benchmark; - -public final class WiringBenchmarkEvent { - private long number = -1; // We'll let the orphan buffer assign this, although I think consensus actually does - private final byte[] data = new byte[1024 * 32]; // Just gotta have some bytes. Whatever. - - public WiringBenchmarkEvent() {} - - void reset(long number) { - this.number = number; - } - - @Override - public String toString() { - return "Event {number=" + number + "}"; - } - - public long number() { - return number; - } -} diff --git a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/benchmark/WiringBenchmarkEventPool.java b/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/benchmark/WiringBenchmarkEventPool.java deleted file mode 100644 index c3096dbb477..00000000000 --- a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/benchmark/WiringBenchmarkEventPool.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 com.swirlds.common.wiring.benchmark; - -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.LinkedBlockingQueue; - -public final class WiringBenchmarkEventPool { - private final BlockingQueue pool = new LinkedBlockingQueue<>(); - - public WiringBenchmarkEventPool() {} - - @NonNull - public WiringBenchmarkEvent checkout(long number) { - WiringBenchmarkEvent event = pool.poll(); - if (event == null) { - event = new WiringBenchmarkEvent(); - } - event.reset(number); - return event; - } - - public void checkin(WiringBenchmarkEvent event) { - pool.add(event); - } -} diff --git a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/benchmark/WiringBenchmarkEventVerifier.java b/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/benchmark/WiringBenchmarkEventVerifier.java deleted file mode 100644 index 193a5274b79..00000000000 --- a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/benchmark/WiringBenchmarkEventVerifier.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 com.swirlds.common.wiring.benchmark; - -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.function.Function; - -public class WiringBenchmarkEventVerifier implements Function { - - public WiringBenchmarkEventVerifier() {} - - @Override - @NonNull - public WiringBenchmarkEvent apply(@NonNull final WiringBenchmarkEvent event) { - // Pretend like we did verification by sleeping for a few microseconds - busySleep(2000); - return event; - } - - public static void busySleep(long nanos) { - long elapsed; - final long startTime = System.nanoTime(); - do { - elapsed = System.nanoTime() - startTime; - } while (elapsed < nanos); - } -} diff --git a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/benchmark/WiringBenchmarkGossip.java b/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/benchmark/WiringBenchmarkGossip.java deleted file mode 100644 index 58d8d2222e5..00000000000 --- a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/benchmark/WiringBenchmarkGossip.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 com.swirlds.common.wiring.benchmark; - -import java.util.concurrent.Executor; -import java.util.concurrent.atomic.AtomicLong; -import java.util.function.Consumer; - -/** - * A quick and dirty simulation of gossip :-). It will generate events like crazy. - */ -public class WiringBenchmarkGossip { - private final Executor executor; - private final WiringBenchmarkEventPool eventPool; - private final Consumer toEventVerifier; - private final AtomicLong eventNumber = new AtomicLong(); - private volatile boolean stopped = false; - private volatile long checkSum; - - public WiringBenchmarkGossip( - Executor executor, WiringBenchmarkEventPool eventPool, Consumer toEventVerifier) { - this.executor = executor; - this.toEventVerifier = toEventVerifier; - this.eventPool = eventPool; - } - - public void start() { - eventNumber.set(0); - checkSum = 0; - executor.execute(this::generateEvents); - } - - private void generateEvents() { - while (!stopped) { - final var event = eventPool.checkout(eventNumber.getAndIncrement()); - toEventVerifier.accept(event); - } - long lastNumber = eventNumber.get(); - checkSum = lastNumber * (lastNumber + 1) / 2; - } - - public void stop() { - stopped = true; - } - - public long getCheckSum() { - return checkSum; - } -} diff --git a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/benchmark/WiringBenchmarkTopologicalEventSorter.java b/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/benchmark/WiringBenchmarkTopologicalEventSorter.java deleted file mode 100644 index ec6da1459c2..00000000000 --- a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/benchmark/WiringBenchmarkTopologicalEventSorter.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 com.swirlds.common.wiring.benchmark; - -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.function.Function; - -public class WiringBenchmarkTopologicalEventSorter implements Function { - private static final int PRINT_FREQUENCY = 10_000_000; - private long lastTimestamp; - private long checkSum; - - public WiringBenchmarkTopologicalEventSorter() { - this.checkSum = 0; - } - - @NonNull - @Override - public WiringBenchmarkEvent apply(@NonNull final WiringBenchmarkEvent event) { - final long number = event.number(); - checkSum += number + 1; // make 0 contribute to the sum - if (number % PRINT_FREQUENCY == 0) { - long curTimestamp = System.currentTimeMillis(); - if (number != 0) { - System.out.format( - "Handled %d events, TPS: %d%n", - number, PRINT_FREQUENCY * 1000L / (curTimestamp - lastTimestamp)); - } - lastTimestamp = curTimestamp; - } - return event; - } - - public long getCheckSum() { - return checkSum; - } -} diff --git a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/builders/TaskSchedulerConfigurationTests.java b/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/builders/TaskSchedulerConfigurationTests.java deleted file mode 100644 index 2e836529fc6..00000000000 --- a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/builders/TaskSchedulerConfigurationTests.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright (C) 2024 Hedera Hashgraph, LLC - * - * 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 com.swirlds.common.wiring.builders; - -import static com.swirlds.common.test.fixtures.RandomUtils.getRandomPrintSeed; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertThrows; - -import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerConfiguration; -import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; -import java.util.Random; -import org.junit.jupiter.api.Test; - -class TaskSchedulerConfigurationTests { - - @Test - void defaultValuesTest() { - final String configString = ""; - final TaskSchedulerConfiguration config = TaskSchedulerConfiguration.parse(configString); - - assertNull(config.type()); - assertNull(config.unhandledTaskCapacity()); - assertNull(config.unhandledTaskMetricEnabled()); - assertNull(config.busyFractionMetricEnabled()); - assertNull(config.flushingEnabled()); - assertNull(config.squelchingEnabled()); - } - - @Test - void randomValuesTest() { - final Random random = getRandomPrintSeed(); - - for (int i = 0; i < 100; i++) { - final StringBuilder configStringBuilder = new StringBuilder(); - - final TaskSchedulerType expectedTaskSchedulerType; - if (random.nextBoolean()) { - expectedTaskSchedulerType = - TaskSchedulerType.values()[random.nextInt(TaskSchedulerType.values().length)]; - configStringBuilder.append(expectedTaskSchedulerType).append(" "); - } else { - expectedTaskSchedulerType = null; - } - - final Long expectedUnhandledTaskCapacity; - if (random.nextBoolean()) { - expectedUnhandledTaskCapacity = random.nextLong(0, 100); - configStringBuilder - .append("CAPACITY(") - .append(expectedUnhandledTaskCapacity) - .append(") "); - } else { - expectedUnhandledTaskCapacity = null; - } - - final Boolean expectedUnhandledTaskMetricEnabled; - if (random.nextBoolean()) { - expectedUnhandledTaskMetricEnabled = random.nextBoolean(); - configStringBuilder.append( - expectedUnhandledTaskMetricEnabled ? "UNHANDLED_TASK_METRIC " : "!UNHANDLED_TASK_METRIC "); - } else { - expectedUnhandledTaskMetricEnabled = null; - } - - final Boolean expectedBusyFractionMetricEnabled; - if (random.nextBoolean()) { - expectedBusyFractionMetricEnabled = random.nextBoolean(); - configStringBuilder.append( - expectedBusyFractionMetricEnabled ? "BUSY_FRACTION_METRIC " : "!BUSY_FRACTION_METRIC "); - } else { - expectedBusyFractionMetricEnabled = null; - } - - final Boolean expectedFlushingEnabled; - if (random.nextBoolean()) { - expectedFlushingEnabled = random.nextBoolean(); - configStringBuilder.append(expectedFlushingEnabled ? "FLUSHABLE " : "!FLUSHABLE "); - } else { - expectedFlushingEnabled = null; - } - - final Boolean expectedSquelchingEnabled; - if (random.nextBoolean()) { - expectedSquelchingEnabled = random.nextBoolean(); - configStringBuilder.append(expectedSquelchingEnabled ? "SQUELCHABLE " : "!SQUELCHABLE "); - } else { - expectedSquelchingEnabled = null; - } - - final String configString = configStringBuilder.toString(); - - final TaskSchedulerConfiguration config = TaskSchedulerConfiguration.parse(configString); - - assertEquals(expectedTaskSchedulerType, config.type()); - assertEquals(expectedUnhandledTaskCapacity, config.unhandledTaskCapacity()); - assertEquals(expectedUnhandledTaskMetricEnabled, config.unhandledTaskMetricEnabled()); - assertEquals(expectedBusyFractionMetricEnabled, config.busyFractionMetricEnabled()); - assertEquals(expectedFlushingEnabled, config.flushingEnabled()); - assertEquals(expectedSquelchingEnabled, config.squelchingEnabled()); - } - } - - /** - * Test what happens if a configuration string contains multiple values for the same configuration option. - */ - @Test - void doubleConfigurationTest() { - assertThrows(IllegalArgumentException.class, () -> TaskSchedulerConfiguration.parse("DIRECT DIRECT")); - assertThrows(IllegalArgumentException.class, () -> TaskSchedulerConfiguration.parse("DIRECT SEQUENTIAL")); - assertThrows( - IllegalArgumentException.class, - () -> TaskSchedulerConfiguration.parse("CAPACITY(1234) CAPACITY(1234)")); - assertThrows( - IllegalArgumentException.class, - () -> TaskSchedulerConfiguration.parse("CAPACITY(1234) CAPACITY(5678)")); - assertThrows( - IllegalArgumentException.class, - () -> TaskSchedulerConfiguration.parse("UNHANDLED_TASK_METRIC UNHANDLED_TASK_METRIC")); - assertThrows( - IllegalArgumentException.class, - () -> TaskSchedulerConfiguration.parse("UNHANDLED_TASK_METRIC !UNHANDLED_TASK_METRIC")); - assertThrows( - IllegalArgumentException.class, - () -> TaskSchedulerConfiguration.parse("BUSY_FRACTION_METRIC BUSY_FRACTION_METRIC")); - assertThrows( - IllegalArgumentException.class, - () -> TaskSchedulerConfiguration.parse("BUSY_FRACTION_METRIC !BUSY_FRACTION_METRIC")); - assertThrows(IllegalArgumentException.class, () -> TaskSchedulerConfiguration.parse("FLUSHABLE !FLUSHABLE")); - assertThrows(IllegalArgumentException.class, () -> TaskSchedulerConfiguration.parse("FLUSHABLE FLUSHABLE")); - assertThrows( - IllegalArgumentException.class, () -> TaskSchedulerConfiguration.parse("SQUELCHABLE !SQUELCHABLE")); - assertThrows(IllegalArgumentException.class, () -> TaskSchedulerConfiguration.parse("SQUELCHABLE SQUELCHABLE")); - } - - @Test - void unmatchedFieldTest() { - assertThrows( - IllegalArgumentException.class, () -> TaskSchedulerConfiguration.parse("DIRECT CAPACITY(100) QWERTY")); - } -} diff --git a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/component/ComponentWiringRouterTests.java b/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/component/ComponentWiringRouterTests.java deleted file mode 100644 index 83c2453010d..00000000000 --- a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/component/ComponentWiringRouterTests.java +++ /dev/null @@ -1,311 +0,0 @@ -/* - * Copyright (C) 2024 Hedera Hashgraph, LLC - * - * 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 com.swirlds.common.wiring.component; - -import static com.swirlds.common.test.fixtures.RandomUtils.getRandomPrintSeed; -import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerConfiguration.DIRECT_CONFIGURATION; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - -import com.swirlds.common.context.PlatformContext; -import com.swirlds.common.test.fixtures.platform.TestPlatformContextBuilder; -import org.hiero.wiring.framework.component.ComponentWiring; -import org.hiero.wiring.framework.model.WiringModel; -import org.hiero.wiring.framework.model.WiringModelBuilder; -import org.hiero.wiring.framework.transformers.RoutableData; -import org.hiero.wiring.framework.wires.output.OutputWire; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.ArrayList; -import java.util.List; -import java.util.Random; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicLong; -import org.junit.jupiter.api.Test; - -class ComponentWiringRouterTests { - - private enum TestDataType { - FOO, // Long values - BAR, // Long values - BAZ; // Boolean values - - /** - * Create a new {@link RoutableData} object with the given data. - * - * @param data the data - * @return the new {@link RoutableData} object - */ - @NonNull - public RoutableData of(@NonNull final Object data) { - return new RoutableData<>(this, data); - } - } - - private enum TestDataType2 { - FOO, // Long values - BAR, // Long values - BAZ; // Boolean values - - /** - * Create a new {@link RoutableData} object with the given data. - * - * @param data the data - * @return the new {@link RoutableData} object - */ - @NonNull - public RoutableData of(@NonNull final Object data) { - return new RoutableData<>(this, data); - } - } - - private interface TestComponent { - @NonNull - RoutableData doWork(@NonNull Integer input); - } - - private static class TestComponentImpl implements TestComponent { - @NonNull - @Override - public RoutableData doWork(@NonNull final Integer input) { - if (input % 3 == 0) { - return TestDataType.FOO.of(input.longValue()); - } else if (input % 3 == 1) { - return TestDataType.BAR.of(input.longValue()); - } else { - return TestDataType.BAZ.of(input % 2 == 0); - } - } - } - - private interface TestListComponent { - @NonNull - List> doWork(@NonNull Integer input); - } - - private static class TestListComponentImpl implements TestListComponent { - @NonNull - @Override - public List> doWork(@NonNull final Integer input) { - - final List> output = new ArrayList<>(); - - if (input % 3 == 0) { - output.add(TestDataType.FOO.of(input.longValue())); - } else if (input % 3 == 1) { - output.add(TestDataType.BAR.of(input.longValue())); - } else { - output.add(TestDataType.BAZ.of(input % 2 == 0)); - } - - if (input % 2 == 0) { - output.add(TestDataType.FOO.of(input.longValue() / 2)); - } else { - output.add(TestDataType.BAR.of(input.longValue() / 2)); - } - - if (input % 5 == 0) { - output.add(TestDataType.FOO.of(input.longValue() / 5)); - } - - return output; - } - } - - @Test - void basicBehaviorTest() { - final Random random = getRandomPrintSeed(); - - final PlatformContext platformContext = - TestPlatformContextBuilder.create().build(); - final WiringModel model = WiringModelBuilder.create(platformContext).build(); - - final ComponentWiring> wiring = - new ComponentWiring<>(model, TestComponent.class, DIRECT_CONFIGURATION); - - wiring.bind(new TestComponentImpl()); - - final AtomicLong latestFoo = new AtomicLong(); - final AtomicLong latestBar = new AtomicLong(); - final AtomicBoolean latestBaz = new AtomicBoolean(); - - final OutputWire fooOutput = wiring.getRoutedOutput(TestDataType.FOO); - final OutputWire barOutput = wiring.getRoutedOutput(TestDataType.BAR); - final OutputWire bazOutput = wiring.getRoutedOutput(TestDataType.BAZ); - - fooOutput.solderTo("fooHandler", "fooInput", latestFoo::set); - barOutput.solderTo("barHandler", "barInput", latestBar::set); - bazOutput.solderTo("bazHandler", "bazInput", latestBaz::set); - - long expectedFoo = 0; - long expectedBar = 0; - boolean expectedBaz = false; - - // Intentional: we have to create all wires prior to starting the model - wiring.getInputWire(TestComponent::doWork); - - model.start(); - - for (int i = 0; i < 1000; i++) { - final int value = random.nextInt(); - if (value % 3 == 0) { - expectedFoo = value; - } else if (value % 3 == 1) { - expectedBar = value; - } else { - expectedBaz = value % 2 == 0; - } - wiring.getInputWire(TestComponent::doWork).put(value); - - assertEquals(expectedFoo, latestFoo.get()); - assertEquals(expectedBar, latestBar.get()); - assertEquals(expectedBaz, latestBaz.get()); - } - } - - @Test - void basicSplitBehaviorTest() { - final Random random = getRandomPrintSeed(); - - final PlatformContext platformContext = - TestPlatformContextBuilder.create().build(); - final WiringModel model = WiringModelBuilder.create(platformContext).build(); - - final ComponentWiring>> wiring = - new ComponentWiring<>(model, TestListComponent.class, DIRECT_CONFIGURATION); - - wiring.bind(new TestListComponentImpl()); - - final AtomicLong latestFoo = new AtomicLong(); - final AtomicLong latestBar = new AtomicLong(); - final AtomicBoolean latestBaz = new AtomicBoolean(); - - final OutputWire fooOutput = wiring.getSplitAndRoutedOutput(TestDataType.FOO); - final OutputWire barOutput = wiring.getSplitAndRoutedOutput(TestDataType.BAR); - final OutputWire bazOutput = wiring.getSplitAndRoutedOutput(TestDataType.BAZ); - - fooOutput.solderTo("fooHandler", "fooInput", latestFoo::getAndAdd); - barOutput.solderTo("barHandler", "barInput", latestBar::getAndAdd); - bazOutput.solderTo("bazHandler", "bazInput", latestBaz::set); - - long expectedFoo = 0; - long expectedBar = 0; - boolean expectedBaz = false; - - // Intentional: we have to create all wires prior to starting the model - wiring.getInputWire(TestListComponent::doWork); - - model.start(); - - for (int i = 0; i < 1000; i++) { - final int value = random.nextInt(); - - if (value % 3 == 0) { - expectedFoo += value; - } else if (value % 3 == 1) { - expectedBar += value; - } else { - expectedBaz = value % 2 == 0; - } - - if (value % 2 == 0) { - expectedFoo += value / 2; - } else { - expectedBar += value / 2; - } - - if (value % 5 == 0) { - expectedFoo += value / 5; - } - - wiring.getInputWire(TestListComponent::doWork).put(value); - - assertEquals(expectedFoo, latestFoo.get()); - assertEquals(expectedBar, latestBar.get()); - assertEquals(expectedBaz, latestBaz.get()); - } - } - - /** - * It is not allowed to create multiple routers with different enum types from the same component. - */ - @Test - void multipleRoutersForbiddenTest() { - final PlatformContext platformContext = - TestPlatformContextBuilder.create().build(); - final WiringModel model = WiringModelBuilder.create(platformContext).build(); - - final ComponentWiring> wiring = - new ComponentWiring<>(model, TestComponent.class, DIRECT_CONFIGURATION); - - wiring.getRoutedOutput(TestDataType.FOO); - - assertThrows(IllegalArgumentException.class, () -> wiring.getRoutedOutput(TestDataType2.FOO)); - } - - /** - * It is not allowed to create multiple routers with different enum types from the same component. - */ - @Test - void multipleSplitRoutersForbiddenTest() { - final PlatformContext platformContext = - TestPlatformContextBuilder.create().build(); - final WiringModel model = WiringModelBuilder.create(platformContext).build(); - - final ComponentWiring> wiring = - new ComponentWiring<>(model, TestListComponent.class, DIRECT_CONFIGURATION); - - wiring.getRoutedOutput(TestDataType.FOO); - - assertThrows(IllegalArgumentException.class, () -> wiring.getRoutedOutput(TestDataType2.FOO)); - } - - /** - * We shouldn't be able to create a router that uses unsplit data, followed by creating a router that uses split - * data. - */ - @Test - void unsplitThenSplitRoutersForbiddenTest() { - final PlatformContext platformContext = - TestPlatformContextBuilder.create().build(); - final WiringModel model = WiringModelBuilder.create(platformContext).build(); - - final ComponentWiring> wiring = - new ComponentWiring<>(model, TestComponent.class, DIRECT_CONFIGURATION); - - wiring.getRoutedOutput(TestDataType.FOO); - - assertThrows(IllegalStateException.class, () -> wiring.getSplitAndRoutedOutput(TestDataType2.FOO)); - } - - /** - * We shouldn't be able to create a router that uses split data, followed by creating a router that uses unsplit - * data. - */ - @Test - void splitThenUnsplitRoutersForbiddenTest() { - final PlatformContext platformContext = - TestPlatformContextBuilder.create().build(); - final WiringModel model = WiringModelBuilder.create(platformContext).build(); - - final ComponentWiring> wiring = - new ComponentWiring<>(model, TestListComponent.class, DIRECT_CONFIGURATION); - - wiring.getSplitAndRoutedOutput(TestDataType.FOO); - - assertThrows(IllegalStateException.class, () -> wiring.getRoutedOutput(TestDataType2.FOO)); - } -} diff --git a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/component/ComponentWiringTests.java b/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/component/ComponentWiringTests.java deleted file mode 100644 index f695c4745ed..00000000000 --- a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/component/ComponentWiringTests.java +++ /dev/null @@ -1,540 +0,0 @@ -/* - * Copyright (C) 2024 Hedera Hashgraph, LLC - * - * 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 com.swirlds.common.wiring.component; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertSame; -import static org.junit.jupiter.api.Assertions.assertThrows; - -import com.swirlds.common.context.PlatformContext; -import com.swirlds.common.test.fixtures.platform.TestPlatformContextBuilder; -import org.hiero.wiring.framework.component.ComponentWiring; -import org.hiero.wiring.framework.component.InputWireLabel; -import org.hiero.wiring.framework.component.SchedulerLabel; -import org.hiero.wiring.framework.model.WiringModel; -import org.hiero.wiring.framework.model.WiringModelBuilder; -import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerConfiguration; -import org.hiero.wiring.framework.wires.input.InputWire; -import org.hiero.wiring.framework.wires.output.OutputWire; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.atomic.AtomicLong; -import java.util.concurrent.atomic.AtomicReference; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.ValueSource; - -public class ComponentWiringTests { - - private interface FooBarBaz { - @NonNull - Long handleFoo(@NonNull Integer foo); - - @InputWireLabel("bar") - @NonNull - Long handleBar(@NonNull Boolean bar); - - void handleBaz(@NonNull String baz); - - @InputWireLabel("trigger") - @NonNull - Long triggerQux(); - - void triggerCorge(); - - @InputWireLabel("data to be transformed") - @SchedulerLabel("transformer") - @NonNull - default String transformer(@NonNull final Long baseOutput) { - handleBar(true); - return "" + baseOutput; - } - - @InputWireLabel("data to be filtered") - @SchedulerLabel("filter") - default Boolean filter(@NonNull final Long baseOutput) { - return baseOutput % 2 == 0; - } - } - - private static class FooBarBazImpl implements FooBarBaz { - private long runningValue = 0; - - @Override - @NonNull - public Long handleFoo(@NonNull final Integer foo) { - runningValue += foo; - return runningValue; - } - - @Override - @NonNull - public Long handleBar(@NonNull final Boolean bar) { - runningValue *= bar ? 1 : -1; - return runningValue; - } - - @Override - public void handleBaz(@NonNull final String baz) { - runningValue *= baz.hashCode(); - } - - @Override - @NonNull - public Long triggerQux() { - runningValue -= 1; - return runningValue; - } - - @Override - public void triggerCorge() { - runningValue *= 1.5; - } - - public long getRunningValue() { - return runningValue; - } - } - - @SchedulerLabel("actuallyCallThisSomethingDifferent") - private interface ComponentWithListOutput { - @NonNull - List handleInputA(@NonNull String s); - - @NonNull - List handleInputB(@NonNull Long l); - - @NonNull - default Boolean filter(@NonNull final String baseOutput) { - return baseOutput.hashCode() % 2 == 0; - } - - @NonNull - default String transformer(@NonNull final String baseOutput) { - return "(" + baseOutput + ")"; - } - } - - private static class ComponentWithListOutputImpl implements ComponentWithListOutput { - - @NonNull - @Override - public List handleInputA(@NonNull final String s) { - return List.of(s.split("")); - } - - @NonNull - @Override - public List handleInputB(@NonNull final Long l) { - final String s = l.toString(); - // return a list of characters - return List.of(s.split("")); - } - } - - /** - * The framework should not permit methods that aren't on the component to be wired. - */ - @Test - void methodNotOnComponentTest() { - final PlatformContext platformContext = - TestPlatformContextBuilder.create().build(); - - final WiringModel wiringModel = - WiringModelBuilder.create(platformContext).build(); - - final TaskSchedulerConfiguration schedulerConfiguration = TaskSchedulerConfiguration.parse("DIRECT"); - - final ComponentWiring fooBarBazWiring = - new ComponentWiring<>(wiringModel, FooBarBaz.class, schedulerConfiguration); - assertEquals("FooBarBaz", fooBarBazWiring.getSchedulerName()); - - assertThrows(IllegalArgumentException.class, () -> fooBarBazWiring.getInputWire((x, y) -> 0L)); - assertThrows(IllegalArgumentException.class, () -> fooBarBazWiring.getInputWire((x, y) -> {})); - assertThrows(IllegalArgumentException.class, () -> fooBarBazWiring.getInputWire((x) -> 1L)); - assertThrows(IllegalArgumentException.class, () -> fooBarBazWiring.getInputWire((x) -> {})); - assertThrows(IllegalArgumentException.class, () -> fooBarBazWiring.getTransformedOutput((x, y) -> 0L)); - } - - @ParameterizedTest - @ValueSource(ints = {0, 1, 2, 3}) - void simpleComponentTest(final int bindLocation) { - final PlatformContext platformContext = - TestPlatformContextBuilder.create().build(); - - final WiringModel wiringModel = - WiringModelBuilder.create(platformContext).build(); - - final TaskSchedulerConfiguration schedulerConfiguration = TaskSchedulerConfiguration.parse("DIRECT"); - - final ComponentWiring fooBarBazWiring = - new ComponentWiring<>(wiringModel, FooBarBaz.class, schedulerConfiguration); - assertEquals("FooBarBaz", fooBarBazWiring.getSchedulerName()); - - final FooBarBazImpl fooBarBazImpl = new FooBarBazImpl(); - - if (bindLocation == 0) { - fooBarBazWiring.bind(fooBarBazImpl); - } - - final InputWire fooInput = fooBarBazWiring.getInputWire(FooBarBaz::handleFoo); - assertEquals("handleFoo", fooInput.getName()); - final InputWire barInput = fooBarBazWiring.getInputWire(FooBarBaz::handleBar); - assertEquals("bar", barInput.getName()); - - if (bindLocation == 1) { - fooBarBazWiring.bind(fooBarBazImpl); - } - - final InputWire bazInput = fooBarBazWiring.getInputWire(FooBarBaz::handleBaz); - assertEquals("handleBaz", bazInput.getName()); - final InputWire triggerQux = fooBarBazWiring.getInputWire(FooBarBaz::triggerQux); - assertEquals("trigger", triggerQux.getName()); - final InputWire triggerCorge = fooBarBazWiring.getInputWire(FooBarBaz::triggerCorge); - assertEquals("triggerCorge", triggerCorge.getName()); - - final OutputWire output = fooBarBazWiring.getOutputWire(); - - if (bindLocation == 2) { - fooBarBazWiring.bind(fooBarBazImpl); - } - - final AtomicLong outputValue = new AtomicLong(); - output.solderTo("outputHandler", "output", outputValue::set); - - // Getting the same input wire multiple times should yield the same instance - assertSame(fooInput, fooBarBazWiring.getInputWire(FooBarBaz::handleFoo)); - assertSame(barInput, fooBarBazWiring.getInputWire(FooBarBaz::handleBar)); - assertSame(bazInput, fooBarBazWiring.getInputWire(FooBarBaz::handleBaz)); - assertSame(triggerQux, fooBarBazWiring.getInputWire(FooBarBaz::triggerQux)); - assertSame(triggerCorge, fooBarBazWiring.getInputWire(FooBarBaz::triggerCorge)); - - // Getting the output wire multiple times should yield the same instance - assertSame(output, fooBarBazWiring.getOutputWire()); - - if (bindLocation == 3) { - fooBarBazWiring.bind(fooBarBazImpl); - } - - long expectedRunningValue = 0; - for (int i = 0; i < 1000; i++) { - if (i % 5 == 0) { - expectedRunningValue += i; - fooInput.put(i); - assertEquals(expectedRunningValue, fooBarBazImpl.getRunningValue()); - assertEquals(expectedRunningValue, outputValue.get()); - } else if (i % 5 == 1) { - final boolean choice = i % 7 == 0; - expectedRunningValue *= choice ? 1 : -1; - barInput.put(choice); - assertEquals(expectedRunningValue, fooBarBazImpl.getRunningValue()); - assertEquals(expectedRunningValue, outputValue.get()); - } else if (i % 5 == 2) { - final String value = "value" + i; - expectedRunningValue *= value.hashCode(); - bazInput.put(value); - assertEquals(expectedRunningValue, fooBarBazImpl.getRunningValue()); - } else if (i % 5 == 3) { - expectedRunningValue -= 1; - triggerQux.put(null); - assertEquals(expectedRunningValue, fooBarBazImpl.getRunningValue()); - } else { - expectedRunningValue *= 1.5; - triggerCorge.put(null); - assertEquals(expectedRunningValue, fooBarBazImpl.getRunningValue()); - } - } - } - - @ParameterizedTest - @ValueSource(ints = {0, 1}) - void transformerTest(final int bindLocation) { - final PlatformContext platformContext = - TestPlatformContextBuilder.create().build(); - - final WiringModel wiringModel = - WiringModelBuilder.create(platformContext).build(); - - final TaskSchedulerConfiguration schedulerConfiguration = TaskSchedulerConfiguration.parse("DIRECT"); - - final FooBarBazImpl fooBarBazImpl = new FooBarBazImpl(); - - final ComponentWiring fooBarBazWiring = - new ComponentWiring<>(wiringModel, FooBarBaz.class, schedulerConfiguration); - assertEquals("FooBarBaz", fooBarBazWiring.getSchedulerName()); - - if (bindLocation == 0) { - fooBarBazWiring.bind(fooBarBazImpl); - } - - final InputWire fooInput = fooBarBazWiring.getInputWire(FooBarBaz::handleFoo); - final InputWire barInput = fooBarBazWiring.getInputWire(FooBarBaz::handleBar); - final InputWire bazInput = fooBarBazWiring.getInputWire(FooBarBaz::handleBaz); - final InputWire triggerQux = fooBarBazWiring.getInputWire(FooBarBaz::triggerQux); - final InputWire triggerCorge = fooBarBazWiring.getInputWire(FooBarBaz::triggerCorge); - - final OutputWire output = fooBarBazWiring.getTransformedOutput(FooBarBaz::transformer); - - // Getting the same transformer multiple times should yield the same instance - assertSame(output, fooBarBazWiring.getTransformedOutput(FooBarBaz::transformer)); - - if (bindLocation == 1) { - fooBarBazWiring.bind(fooBarBazImpl); - } - - final AtomicReference outputValue = new AtomicReference<>("0"); - output.solderTo("outputHandler", "output", outputValue::set); - - long expectedRunningValue = 0; - for (int i = 0; i < 1000; i++) { - if (i % 5 == 0) { - expectedRunningValue += i; - fooInput.put(i); - assertEquals(expectedRunningValue, fooBarBazImpl.getRunningValue()); - assertEquals("" + expectedRunningValue, outputValue.get()); - } else if (i % 5 == 1) { - final boolean choice = i % 7 == 0; - expectedRunningValue *= choice ? 1 : -1; - barInput.put(choice); - assertEquals(expectedRunningValue, fooBarBazImpl.getRunningValue()); - assertEquals("" + expectedRunningValue, outputValue.get()); - } else if (i % 5 == 2) { - final String value = "value" + i; - expectedRunningValue *= value.hashCode(); - bazInput.put(value); - assertEquals(expectedRunningValue, fooBarBazImpl.getRunningValue()); - } else if (i % 5 == 3) { - expectedRunningValue -= 1; - triggerQux.put(null); - assertEquals(expectedRunningValue, fooBarBazImpl.getRunningValue()); - assertEquals("" + expectedRunningValue, outputValue.get()); - } else { - expectedRunningValue *= 1.5; - triggerCorge.put(null); - assertEquals(expectedRunningValue, fooBarBazImpl.getRunningValue()); - } - } - } - - @ParameterizedTest - @ValueSource(ints = {0, 1}) - void filterTest(final int bindLocation) { - final PlatformContext platformContext = - TestPlatformContextBuilder.create().build(); - - final WiringModel wiringModel = - WiringModelBuilder.create(platformContext).build(); - - final TaskSchedulerConfiguration schedulerConfiguration = TaskSchedulerConfiguration.parse("DIRECT"); - - final FooBarBazImpl fooBarBazImpl = new FooBarBazImpl(); - - final ComponentWiring fooBarBazWiring = - new ComponentWiring<>(wiringModel, FooBarBaz.class, schedulerConfiguration); - assertEquals("FooBarBaz", fooBarBazWiring.getSchedulerName()); - - if (bindLocation == 0) { - fooBarBazWiring.bind(fooBarBazImpl); - } - - final InputWire fooInput = fooBarBazWiring.getInputWire(FooBarBaz::handleFoo); - final InputWire barInput = fooBarBazWiring.getInputWire(FooBarBaz::handleBar); - final InputWire bazInput = fooBarBazWiring.getInputWire(FooBarBaz::handleBaz); - final InputWire triggerQux = fooBarBazWiring.getInputWire(FooBarBaz::triggerQux); - final InputWire triggerCorge = fooBarBazWiring.getInputWire(FooBarBaz::triggerCorge); - - final OutputWire output = fooBarBazWiring.getFilteredOutput(FooBarBaz::filter); - - // Getting the same filter multiple times should yield the same instance - assertSame(output, fooBarBazWiring.getFilteredOutput(FooBarBaz::filter)); - - if (bindLocation == 1) { - fooBarBazWiring.bind(fooBarBazImpl); - } - - final AtomicReference outputValue = new AtomicReference<>(); - output.solderTo("outputHandler", "output", outputValue::set); - - long expectedRunningValue = 0; - for (int i = 0; i < 1000; i++) { - outputValue.set(null); - if (i % 5 == 0) { - expectedRunningValue += i; - fooInput.put(i); - assertEquals(expectedRunningValue, fooBarBazImpl.getRunningValue()); - final Long expectedValue = expectedRunningValue % 2 == 0 ? expectedRunningValue : null; - assertEquals(expectedValue, outputValue.get()); - } else if (i % 5 == 1) { - final boolean choice = i % 7 == 0; - expectedRunningValue *= choice ? 1 : -1; - barInput.put(choice); - final Long expectedValue = expectedRunningValue % 2 == 0 ? expectedRunningValue : null; - assertEquals(expectedValue, outputValue.get()); - } else if (i % 5 == 2) { - final String value = "value" + i; - expectedRunningValue *= value.hashCode(); - bazInput.put(value); - assertEquals(expectedRunningValue, fooBarBazImpl.getRunningValue()); - } else if (i % 5 == 3) { - expectedRunningValue -= 1; - triggerQux.put(null); - final Long expectedValue = expectedRunningValue % 2 == 0 ? expectedRunningValue : null; - assertEquals(expectedValue, outputValue.get()); - } else { - expectedRunningValue *= 1.5; - triggerCorge.put(null); - assertEquals(expectedRunningValue, fooBarBazImpl.getRunningValue()); - } - } - } - - @ParameterizedTest - @ValueSource(ints = {0, 1}) - void splitterTest(final int bindLocation) { - final PlatformContext platformContext = - TestPlatformContextBuilder.create().build(); - - final WiringModel wiringModel = - WiringModelBuilder.create(platformContext).build(); - - final TaskSchedulerConfiguration schedulerConfiguration = TaskSchedulerConfiguration.parse("DIRECT"); - - final ComponentWiring> componentWiring = - new ComponentWiring<>(wiringModel, ComponentWithListOutput.class, schedulerConfiguration); - assertEquals("actuallyCallThisSomethingDifferent", componentWiring.getSchedulerName()); - - if (bindLocation == 0) { - componentWiring.bind(new ComponentWithListOutputImpl()); - } - - final OutputWire splitOutput = componentWiring.getSplitOutput(); - assertSame(splitOutput, componentWiring.getSplitOutput()); - - final List outputData = new ArrayList<>(); - splitOutput.solderTo("addToOutputData", "split data", outputData::add); - - final List expectedOutputData = new ArrayList<>(); - - if (bindLocation == 1) { - componentWiring.bind(new ComponentWithListOutputImpl()); - } - - componentWiring.getInputWire(ComponentWithListOutput::handleInputA).put("hello world"); - expectedOutputData.addAll(List.of("h", "e", "l", "l", "o", " ", "w", "o", "r", "l", "d")); - - componentWiring.getInputWire(ComponentWithListOutput::handleInputB).put(123L); - expectedOutputData.addAll(List.of("1", "2", "3")); - - assertEquals(expectedOutputData, outputData); - } - - @ParameterizedTest - @ValueSource(ints = {0, 1}) - void filteredSplitterTest(final int bindLocation) { - final PlatformContext platformContext = - TestPlatformContextBuilder.create().build(); - - final WiringModel wiringModel = - WiringModelBuilder.create(platformContext).build(); - - final TaskSchedulerConfiguration schedulerConfiguration = TaskSchedulerConfiguration.parse("DIRECT"); - - final ComponentWiring> componentWiring = - new ComponentWiring<>(wiringModel, ComponentWithListOutput.class, schedulerConfiguration); - assertEquals("actuallyCallThisSomethingDifferent", componentWiring.getSchedulerName()); - - if (bindLocation == 0) { - componentWiring.bind(new ComponentWithListOutputImpl()); - } - - final OutputWire filteredOutput = - componentWiring.getSplitAndFilteredOutput(ComponentWithListOutput::filter); - assertSame(filteredOutput, componentWiring.getSplitAndFilteredOutput(ComponentWithListOutput::filter)); - - final List outputData = new ArrayList<>(); - filteredOutput.solderTo("addToOutputData", "split data", outputData::add); - - final List expectedOutputData = new ArrayList<>(); - - if (bindLocation == 1) { - componentWiring.bind(new ComponentWithListOutputImpl()); - } - - componentWiring.getInputWire(ComponentWithListOutput::handleInputA).put("hello world"); - for (final String s : "hello world".split("")) { - if (s.hashCode() % 2 == 0) { - expectedOutputData.add(s); - } - } - - componentWiring.getInputWire(ComponentWithListOutput::handleInputB).put(123L); - for (final String s : "123".split("")) { - if (s.hashCode() % 2 == 0) { - expectedOutputData.add(s); - } - } - - assertEquals(expectedOutputData, outputData); - } - - @ParameterizedTest - @ValueSource(ints = {0, 1}) - void transformedSplitterTest(final int bindLocation) { - final PlatformContext platformContext = - TestPlatformContextBuilder.create().build(); - - final WiringModel wiringModel = - WiringModelBuilder.create(platformContext).build(); - - final TaskSchedulerConfiguration schedulerConfiguration = TaskSchedulerConfiguration.parse("DIRECT"); - - final ComponentWiring> componentWiring = - new ComponentWiring<>(wiringModel, ComponentWithListOutput.class, schedulerConfiguration); - assertEquals("actuallyCallThisSomethingDifferent", componentWiring.getSchedulerName()); - - if (bindLocation == 0) { - componentWiring.bind(new ComponentWithListOutputImpl()); - } - - final OutputWire transformedOutput = - componentWiring.getSplitAndTransformedOutput(ComponentWithListOutput::transformer); - assertSame( - transformedOutput, componentWiring.getSplitAndTransformedOutput(ComponentWithListOutput::transformer)); - - final List outputData = new ArrayList<>(); - transformedOutput.solderTo("addToOutputData", "split data", outputData::add); - - final List expectedOutputData = new ArrayList<>(); - - if (bindLocation == 1) { - componentWiring.bind(new ComponentWithListOutputImpl()); - } - - componentWiring.getInputWire(ComponentWithListOutput::handleInputA).put("hello world"); - for (final String s : "hello world".split("")) { - expectedOutputData.add("(" + s + ")"); - } - - componentWiring.getInputWire(ComponentWithListOutput::handleInputB).put(123L); - for (final String s : "123".split("")) { - expectedOutputData.add("(" + s + ")"); - } - - assertEquals(expectedOutputData, outputData); - } -} diff --git a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/component/WiringComponentPerformanceTests.java b/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/component/WiringComponentPerformanceTests.java deleted file mode 100644 index 2a2f73711cb..00000000000 --- a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/component/WiringComponentPerformanceTests.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (C) 2024 Hedera Hashgraph, LLC - * - * 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 com.swirlds.common.wiring.component; - -import com.swirlds.common.test.fixtures.platform.TestPlatformContextBuilder; -import org.hiero.wiring.framework.component.ComponentWiring; -import org.hiero.wiring.framework.model.WiringModel; -import org.hiero.wiring.framework.model.WiringModelBuilder; -import org.hiero.wiring.framework.schedulers.TaskScheduler; -import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; -import org.hiero.wiring.framework.wires.input.BindableInputWire; -import org.hiero.wiring.framework.wires.input.InputWire; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.time.Duration; -import java.time.Instant; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; - -@Disabled // Do not merge with this class enabled -class WiringComponentPerformanceTests { - - private interface SimpleComponent { - void handleInput(@NonNull Long input); - } - - private static class SimpleComponentImpl implements SimpleComponent { - private long runningValue = 0; - - @Override - public void handleInput(@NonNull final Long input) { - runningValue += input; - } - - public long getRunningValue() { - return runningValue; - } - } - - @NonNull - private InputWire buildOldStyleComponent(@NonNull final SimpleComponent component) { - final WiringModel model = WiringModelBuilder.create( - TestPlatformContextBuilder.create().build()) - .build(); - - final TaskScheduler scheduler = model.schedulerBuilder("test") - .withType(TaskSchedulerType.DIRECT) - .build(); - - final BindableInputWire inputWire = scheduler.buildInputWire("input"); - inputWire.bindConsumer(component::handleInput); - - return inputWire; - } - - @NonNull - private InputWire buildAutomaticComponent(@NonNull final SimpleComponent component) { - - final WiringModel model = WiringModelBuilder.create( - TestPlatformContextBuilder.create().build()) - .build(); - - final TaskScheduler scheduler = model.schedulerBuilder("test") - .withType(TaskSchedulerType.DIRECT) - .build() - .cast(); - - final ComponentWiring componentWiring = - new ComponentWiring<>(model, SimpleComponent.class, scheduler); - final InputWire inputWire = componentWiring.getInputWire(SimpleComponent::handleInput); - componentWiring.bind(component); - - return inputWire; - } - - // When testing locally on my macbook (m1), the old style component took 0.76s to run 100,000,000 iterations, - // and the automatic component took 0.79s to run 100,000,000 iterations. - - @Test - void oldStylePerformanceTest() { - final long iterations = 100_000_000; - - final SimpleComponentImpl component = new SimpleComponentImpl(); - final InputWire inputWire = buildOldStyleComponent(component); - - final Instant start = Instant.now(); - - for (long i = 0; i < iterations; i++) { - inputWire.put(i); - } - - final Instant end = Instant.now(); - final Duration duration = Duration.between(start, end); - System.out.println("Time required: " + duration.toMillis() + "ms"); - - // Just in case the compiler wants to get cheeky and avoid doing computation - System.out.println("value = " + component.getRunningValue()); - } - - @Test - void automaticComponentPerformanceTest() { - final long iterations = 100_000_000; - - final SimpleComponentImpl component = new SimpleComponentImpl(); - final InputWire inputWire = buildAutomaticComponent(component); - - final Instant start = Instant.now(); - - for (long i = 0; i < iterations; i++) { - inputWire.put(i); - } - - final Instant end = Instant.now(); - final Duration duration = Duration.between(start, end); - System.out.println("Time required: " + duration.toMillis() + "ms"); - - // Just in case the compiler wants to get cheeky and avoid doing computation - System.out.println("value = " + component.getRunningValue()); - } -} diff --git a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/counters/BackpressureObjectCounterTests.java b/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/counters/BackpressureObjectCounterTests.java deleted file mode 100644 index 701fb201582..00000000000 --- a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/counters/BackpressureObjectCounterTests.java +++ /dev/null @@ -1,291 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 com.swirlds.common.wiring.counters; - -import static com.swirlds.common.test.fixtures.AssertionUtils.assertEventuallyEquals; -import static com.swirlds.common.test.fixtures.AssertionUtils.assertEventuallyTrue; -import static com.swirlds.common.test.fixtures.RandomUtils.getRandomPrintSeed; -import static com.swirlds.common.threading.manager.AdHocThreadManager.getStaticThreadManager; -import static java.util.concurrent.TimeUnit.MILLISECONDS; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import com.swirlds.common.threading.framework.config.ThreadConfiguration; -import java.time.Duration; -import java.util.Random; -import java.util.concurrent.ForkJoinPool; -import java.util.concurrent.ForkJoinPool.ManagedBlocker; -import java.util.concurrent.RejectedExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicReference; -import org.hiero.wiring.framework.counters.BackpressureObjectCounter; -import org.hiero.wiring.framework.counters.ObjectCounter; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.ValueSource; - -class BackpressureObjectCounterTests { - - /** - * Choose a capacity that is sufficiently high as to never trigger. Validate that the counting part of this - * implementation works as expected. - */ - @Test - void countWithHighCapacityTest() { - final Random random = getRandomPrintSeed(); - - final ObjectCounter counter = new BackpressureObjectCounter("test", 1_000_000_000, Duration.ofMillis(1)); - - int count = 0; - for (int i = 0; i < 1000; i++) { - - final boolean increment = count == 0 || random.nextBoolean(); - - if (increment) { - count++; - - // All of these methods are logically equivalent with current capacity. - final int choice = random.nextInt(3); - switch (choice) { - case 0 -> counter.onRamp(); - case 1 -> counter.attemptOnRamp(); - case 2 -> counter.forceOnRamp(); - default -> throw new IllegalStateException("Unexpected value: " + choice); - } - - } else { - count--; - counter.offRamp(); - } - - assertEquals(count, counter.getCount()); - } - } - - @ParameterizedTest - @ValueSource(ints = {0, 1}) - void onRampTest(final int sleepMillis) throws InterruptedException { - final Duration sleepDuration = Duration.ofMillis(sleepMillis); - - final ObjectCounter counter = new BackpressureObjectCounter("test", 10, sleepDuration); - - // Fill up the counter to capacity - for (int i = 0; i < 10; i++) { - counter.onRamp(); - } - - assertEquals(10, counter.getCount()); - - // Attempt to add one more, should block. - final AtomicBoolean added = new AtomicBoolean(false); - final AtomicReference interrupted = new AtomicReference<>(); - final Thread thread = new ThreadConfiguration(getStaticThreadManager()) - .setRunnable(() -> { - counter.onRamp(); - added.set(true); - - interrupted.set(Thread.currentThread().isInterrupted()); - }) - .build(true); - - assertEquals(10, counter.getCount()); - - // Sleep for a little while. Thread should be unable to on ramp another element. - // Count can briefly overflow to 11, but should quickly return to 10. - MILLISECONDS.sleep(50); - final long count1 = counter.getCount(); - assertTrue(count1 == 10 || count1 == 11, "unexpected count " + count1); - - // Interrupting the thread should not unblock us. - thread.interrupt(); - MILLISECONDS.sleep(50); - // Count can briefly overflow to 11, but should quickly return to 10. - final long count2 = counter.getCount(); - assertTrue(count2 == 10 || count2 == 11, "unexpected count " + count2); - - // Off ramp one element. Thread should become unblocked. - counter.offRamp(); - - assertEventuallyTrue(added::get, Duration.ofSeconds(10), "Thread should have been unblocked"); - - // even though the interrupt did not unblock the thread, the interrupt should not have been squelched. - assertEventuallyEquals(true, interrupted::get, Duration.ofSeconds(10), "Thread should have been interrupted"); - - assertEquals(10, counter.getCount()); - } - - @Test - void attemptOnRampTest() { - final ObjectCounter counter = new BackpressureObjectCounter("test", 10, Duration.ofMillis(1)); - - // Fill up the counter to capacity - for (int i = 0; i < 10; i++) { - assertTrue(counter.attemptOnRamp()); - } - - assertEquals(10, counter.getCount()); - - // Attempt to add one more, should block immediately fail and return false. - assertFalse(counter.attemptOnRamp()); - - assertEquals(10, counter.getCount()); - } - - @Test - void forceOnRampTest() { - final ObjectCounter counter = new BackpressureObjectCounter("test", 10, Duration.ofMillis(1)); - - // Fill up the counter to capacity - for (int i = 0; i < 10; i++) { - counter.forceOnRamp(); - } - - assertEquals(10, counter.getCount()); - - // Attempt to add one more, should work even though it violates capacity restrictions - counter.forceOnRamp(); - - assertEquals(11, counter.getCount()); - } - - @Test - void waitUntilEmptyTest() throws InterruptedException { - final ObjectCounter counter = new BackpressureObjectCounter("test", 1000, Duration.ofMillis(1)); - - for (int i = 0; i < 100; i++) { - counter.onRamp(); - } - - final AtomicBoolean empty = new AtomicBoolean(false); - final Thread thread = new ThreadConfiguration(getStaticThreadManager()) - .setRunnable(() -> { - counter.waitUntilEmpty(); - empty.set(true); - }) - .build(true); - - // Should be blocked. - MILLISECONDS.sleep(50); - assertFalse(empty.get()); - - // Draining most of the things from the counter should still block. - for (int i = 0; i < 90; i++) { - counter.offRamp(); - } - MILLISECONDS.sleep(50); - assertFalse(empty.get()); - - // Interrupting the thread should have no effect. - thread.interrupt(); - MILLISECONDS.sleep(50); - assertFalse(empty.get()); - - // Removing remaining things from the counter should unblock. - for (int i = 0; i < 10; i++) { - counter.offRamp(); - } - - assertEventuallyTrue(empty::get, Duration.ofSeconds(10), "Counter did not empty in time."); - } - - /** - * If the fork join pool runs out of threads, back pressure should handle the situation gracefully. - */ - @Test - void backpressureDoesntOverwhelmForkJoinPool() throws InterruptedException { - - final int maxPoolSize = 10; - final ForkJoinPool pool = new ForkJoinPool( - 5, - ForkJoinPool.defaultForkJoinWorkerThreadFactory, - null, - false, - 0, - maxPoolSize, - 1, - null, - 60, - TimeUnit.SECONDS); - - final AtomicBoolean blocked = new AtomicBoolean(true); - final ManagedBlocker dummyBlocker = new ManagedBlocker() { - @Override - public boolean block() throws InterruptedException { - MILLISECONDS.sleep(1); - return false; - } - - @Override - public boolean isReleasable() { - return !blocked.get(); - } - }; - - // Keep submitting managed blockers until the fork join pool taps out. - final AtomicBoolean poolIsSaturated = new AtomicBoolean(false); - for (int i = 0; i < maxPoolSize; i++) { - pool.submit(() -> { - int tries = 1000; - while (tries-- > 0) { - try { - ForkJoinPool.managedBlock(dummyBlocker); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } catch (final RejectedExecutionException ex) { - poolIsSaturated.set(true); - } - } - }); - } - - assertEventuallyTrue(poolIsSaturated::get, Duration.ofSeconds(10), "Fork join pool did not saturate in time."); - - // Now, see if a backpressure counter can block without throwing. - - final ObjectCounter counter = new BackpressureObjectCounter("test", 1, Duration.ofMillis(1)); - counter.onRamp(); - - final AtomicBoolean taskCompleted = new AtomicBoolean(false); - final AtomicBoolean exceptionThrown = new AtomicBoolean(false); - pool.submit(() -> { - - // This should block until we off ramp. - try { - counter.onRamp(); - } catch (final Throwable t) { - exceptionThrown.set(true); - return; - } - - taskCompleted.set(true); - }); - - // Sleep for a while, the task should not be able to complete. - MILLISECONDS.sleep(50); - assertFalse(taskCompleted.get()); - assertFalse(exceptionThrown.get()); - - // Unblock the counter, the task should complete. - counter.offRamp(); - assertEventuallyTrue(taskCompleted::get, Duration.ofSeconds(10), "Task did not complete in time."); - assertFalse(exceptionThrown.get()); - - pool.shutdown(); - } -} diff --git a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/counters/MultiObjectCounterTests.java b/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/counters/MultiObjectCounterTests.java deleted file mode 100644 index e35221e5f9f..00000000000 --- a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/counters/MultiObjectCounterTests.java +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 com.swirlds.common.wiring.counters; - -import static com.swirlds.common.test.fixtures.AssertionUtils.assertEventuallyTrue; -import static com.swirlds.common.test.fixtures.RandomUtils.getRandomPrintSeed; -import static com.swirlds.common.threading.manager.AdHocThreadManager.getStaticThreadManager; -import static java.util.concurrent.TimeUnit.MILLISECONDS; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; - -import com.swirlds.common.threading.framework.config.ThreadConfiguration; -import java.time.Duration; -import java.util.Random; -import java.util.concurrent.atomic.AtomicBoolean; -import org.hiero.wiring.framework.counters.BackpressureObjectCounter; -import org.hiero.wiring.framework.counters.MultiObjectCounter; -import org.hiero.wiring.framework.counters.ObjectCounter; -import org.hiero.wiring.framework.counters.StandardObjectCounter; -import org.junit.jupiter.api.Test; - -class MultiObjectCounterTests { - - @Test - void onRampOffRampTest() { - final Random random = getRandomPrintSeed(); - - final ObjectCounter counterA = new StandardObjectCounter(Duration.ofSeconds(1)); - final ObjectCounter counterB = new StandardObjectCounter(Duration.ofSeconds(1)); - final ObjectCounter counterC = new StandardObjectCounter(Duration.ofSeconds(1)); - - final MultiObjectCounter counter = new MultiObjectCounter(counterA, counterB, counterC); - - int expectedCount = 0; - for (int i = 0; i < 1000; i++) { - - if (expectedCount == 0 || random.nextDouble() < 0.75) { - counter.onRamp(); - expectedCount++; - } else { - counter.offRamp(); - expectedCount--; - } - - assertEquals(expectedCount, counter.getCount()); - assertEquals(expectedCount, counterA.getCount()); - assertEquals(expectedCount, counterB.getCount()); - assertEquals(expectedCount, counterC.getCount()); - } - } - - @Test - void attemptOnRampTest() { - final Random random = getRandomPrintSeed(); - - // When attempting an on ramp, only the first counter's capacity should be consulted. - - final ObjectCounter counterA = new BackpressureObjectCounter("test", 10, Duration.ofSeconds(1)); - final ObjectCounter counterB = new BackpressureObjectCounter("test", 5, Duration.ofSeconds(1)); - final ObjectCounter counterC = new StandardObjectCounter(Duration.ofSeconds(1)); - - final MultiObjectCounter counter = new MultiObjectCounter(counterA, counterB, counterC); - - int expectedCount = 0; - for (int i = 0; i < 1000; i++) { - if (expectedCount == 0 || random.nextDouble() < 0.75) { - if (counter.attemptOnRamp()) { - expectedCount++; - } - } else { - counter.offRamp(); - expectedCount--; - } - - assertEquals(expectedCount, counter.getCount()); - assertEquals(expectedCount, counterA.getCount()); - assertEquals(expectedCount, counterB.getCount()); - assertEquals(expectedCount, counterC.getCount()); - } - } - - @Test - void forceOnRampTest() { - final Random random = getRandomPrintSeed(); - - // When attempting an on ramp, only the first counter's capacity should be consulted. - - final ObjectCounter counterA = new BackpressureObjectCounter("test", 10, Duration.ofSeconds(1)); - final ObjectCounter counterB = new BackpressureObjectCounter("test", 5, Duration.ofSeconds(1)); - final ObjectCounter counterC = new StandardObjectCounter(Duration.ofSeconds(1)); - - final MultiObjectCounter counter = new MultiObjectCounter(counterA, counterB, counterC); - - int expectedCount = 0; - for (int i = 0; i < 1000; i++) { - if (expectedCount == 0 || random.nextDouble() < 0.75) { - counter.forceOnRamp(); - expectedCount++; - } else { - counter.offRamp(); - expectedCount--; - } - - assertEquals(expectedCount, counter.getCount()); - assertEquals(expectedCount, counterA.getCount()); - assertEquals(expectedCount, counterB.getCount()); - assertEquals(expectedCount, counterC.getCount()); - } - } - - @Test - void waitUntilEmptyTest() throws InterruptedException { - final ObjectCounter counterA = new BackpressureObjectCounter("test", 10, Duration.ofSeconds(1)); - final ObjectCounter counterB = new BackpressureObjectCounter("test", 5, Duration.ofSeconds(1)); - final ObjectCounter counterC = new StandardObjectCounter(Duration.ofSeconds(1)); - - final MultiObjectCounter counter = new MultiObjectCounter(counterA, counterB, counterC); - - for (int i = 0; i < 100; i++) { - counter.forceOnRamp(); - } - - counterB.forceOnRamp(); - - counterC.forceOnRamp(); - counterC.forceOnRamp(); - - final AtomicBoolean empty = new AtomicBoolean(false); - final Thread thread = new ThreadConfiguration(getStaticThreadManager()) - .setRunnable(() -> { - counter.waitUntilEmpty(); - empty.set(true); - }) - .build(true); - - // Should be blocked. - MILLISECONDS.sleep(50); - assertFalse(empty.get()); - - // Draining most of the things from the counter should still block. - for (int i = 0; i < 90; i++) { - counter.offRamp(); - } - MILLISECONDS.sleep(50); - assertFalse(empty.get()); - - // Interrupting the thread should have no effect. - thread.interrupt(); - MILLISECONDS.sleep(50); - assertFalse(empty.get()); - - // Remove enough things so that counterA is unblocked. - for (int i = 0; i < 10; i++) { - counter.offRamp(); - } - - MILLISECONDS.sleep(50); - assertFalse(empty.get()); - - // Reduce counter B to zero. - counterB.offRamp(); - - MILLISECONDS.sleep(50); - assertFalse(empty.get()); - - // Finally, remove all elements from counter C. - counterC.offRamp(); - counterC.offRamp(); - - assertEventuallyTrue(empty::get, Duration.ofSeconds(1), "Counter did not empty in time."); - } -} diff --git a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/counters/NoOpObjectCounterTests.java b/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/counters/NoOpObjectCounterTests.java deleted file mode 100644 index 0ac12065dd1..00000000000 --- a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/counters/NoOpObjectCounterTests.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 com.swirlds.common.wiring.counters; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import org.hiero.wiring.framework.counters.NoOpObjectCounter; -import org.junit.jupiter.api.Test; - -class NoOpObjectCounterTests { - - /** - * The most important part of the no-op implementation is that it doesn't throw exceptions. - */ - @Test - void noThrowingTest() { - final NoOpObjectCounter counter = NoOpObjectCounter.getInstance(); - - counter.onRamp(); - counter.attemptOnRamp(); - counter.forceOnRamp(); - counter.offRamp(); - counter.waitUntilEmpty(); - assertEquals(-1, counter.getCount()); - } -} diff --git a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/counters/StandardObjectCounterTests.java b/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/counters/StandardObjectCounterTests.java deleted file mode 100644 index a73a9b76a11..00000000000 --- a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/counters/StandardObjectCounterTests.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 com.swirlds.common.wiring.counters; - -import static com.swirlds.common.test.fixtures.AssertionUtils.assertEventuallyTrue; -import static com.swirlds.common.test.fixtures.RandomUtils.getRandomPrintSeed; -import static com.swirlds.common.threading.manager.AdHocThreadManager.getStaticThreadManager; -import static java.util.concurrent.TimeUnit.MILLISECONDS; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; - -import com.swirlds.common.threading.framework.config.ThreadConfiguration; -import java.time.Duration; -import java.util.Random; -import java.util.concurrent.atomic.AtomicBoolean; -import org.hiero.wiring.framework.counters.ObjectCounter; -import org.hiero.wiring.framework.counters.StandardObjectCounter; -import org.junit.jupiter.api.Test; - -class StandardObjectCounterTests { - - @Test - void basicOperationTest() { - final Random random = getRandomPrintSeed(); - - final ObjectCounter counter = new StandardObjectCounter(Duration.ofMillis(1)); - - int count = 0; - for (int i = 0; i < 1000; i++) { - - final boolean increment = count == 0 || random.nextBoolean(); - - if (increment) { - count++; - - // All of these methods are logically equivalent for this implementation. - final int choice = random.nextInt(3); - switch (choice) { - case 0 -> counter.onRamp(); - case 1 -> counter.attemptOnRamp(); - case 2 -> counter.forceOnRamp(); - default -> throw new IllegalStateException("Unexpected value: " + choice); - } - - } else { - count--; - counter.offRamp(); - } - - assertEquals(count, counter.getCount()); - } - } - - @Test - void waitUntilEmptyTest() throws InterruptedException { - final ObjectCounter counter = new StandardObjectCounter(Duration.ofMillis(1)); - - for (int i = 0; i < 100; i++) { - counter.onRamp(); - } - - final AtomicBoolean empty = new AtomicBoolean(false); - final Thread thread = new ThreadConfiguration(getStaticThreadManager()) - .setRunnable(() -> { - counter.waitUntilEmpty(); - empty.set(true); - }) - .build(true); - - // Should be blocked. - MILLISECONDS.sleep(50); - assertFalse(empty.get()); - - // Draining most of the things from the counter should still block. - for (int i = 0; i < 90; i++) { - counter.offRamp(); - } - MILLISECONDS.sleep(50); - assertFalse(empty.get()); - - // Interrupting the thread should have no effect. - thread.interrupt(); - MILLISECONDS.sleep(50); - assertFalse(empty.get()); - - // Removing remaining things from the counter should unblock. - for (int i = 0; i < 10; i++) { - counter.offRamp(); - } - - assertEventuallyTrue(empty::get, Duration.ofSeconds(1), "Counter did not empty in time."); - } -} diff --git a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/model/DeterministicHeartbeatSchedulerTests.java b/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/model/DeterministicHeartbeatSchedulerTests.java deleted file mode 100644 index ed18c8bd179..00000000000 --- a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/model/DeterministicHeartbeatSchedulerTests.java +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright (C) 2024 Hedera Hashgraph, LLC - * - * 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 com.swirlds.common.wiring.model; - -import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerBuilder.UNLIMITED_CAPACITY; -import static org.junit.jupiter.api.Assertions.assertEquals; - -import com.swirlds.base.test.fixtures.time.FakeTime; -import com.swirlds.common.context.PlatformContext; -import com.swirlds.common.test.fixtures.platform.TestPlatformContextBuilder; -import org.hiero.wiring.framework.model.DeterministicWiringModel; -import org.hiero.wiring.framework.model.WiringModelBuilder; -import org.hiero.wiring.framework.schedulers.TaskScheduler; -import org.hiero.wiring.framework.wires.input.BindableInputWire; -import java.time.Duration; -import java.time.Instant; -import java.util.concurrent.atomic.AtomicLong; -import org.junit.jupiter.api.Test; - -public class DeterministicHeartbeatSchedulerTests { - - @Test - void heartbeatByFrequencyTest() { - final FakeTime time = new FakeTime(); - final PlatformContext platformContext = - TestPlatformContextBuilder.create().withTime(time).build(); - final DeterministicWiringModel model = WiringModelBuilder.create(platformContext) - .withDeterministicModeEnabled(true) - .build(); - ; - - final TaskScheduler scheduler = - model.schedulerBuilder("test").build().cast(); - - final BindableInputWire heartbeatBindable = scheduler.buildInputWire("heartbeat"); - model.buildHeartbeatWire(100).solderTo(heartbeatBindable); - - final AtomicLong counter = new AtomicLong(0); - heartbeatBindable.bindConsumer((now) -> counter.incrementAndGet()); - - model.start(); - int milliseconds = 0; - while (milliseconds <= 1000) { - time.tick(Duration.ofMillis(1)); - milliseconds += 1; - model.tick(); - } - model.stop(); - - assertEquals(100, counter.get()); - } - - @Test - void heartbeatByPeriodTest() { - final FakeTime time = new FakeTime(); - final PlatformContext platformContext = - TestPlatformContextBuilder.create().withTime(time).build(); - final DeterministicWiringModel model = WiringModelBuilder.create(platformContext) - .withDeterministicModeEnabled(true) - .build(); - ; - - final TaskScheduler scheduler = - model.schedulerBuilder("test").build().cast(); - - final BindableInputWire heartbeatBindable = scheduler.buildInputWire("heartbeat"); - model.buildHeartbeatWire(Duration.ofMillis(10)).solderTo(heartbeatBindable); - - final AtomicLong counter = new AtomicLong(0); - heartbeatBindable.bindConsumer((now) -> counter.incrementAndGet()); - - model.start(); - int milliseconds = 0; - while (milliseconds <= 1000) { - time.tick(Duration.ofMillis(1)); - milliseconds += 1; - model.tick(); - } - model.stop(); - - assertEquals(100, counter.get()); - } - - @Test - void heartbeatsAtDifferentRates() { - final FakeTime time = new FakeTime(); - final PlatformContext platformContext = - TestPlatformContextBuilder.create().withTime(time).build(); - final DeterministicWiringModel model = WiringModelBuilder.create(platformContext) - .withDeterministicModeEnabled(true) - .build(); - ; - - final TaskScheduler scheduler = model.schedulerBuilder("test") - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .build() - .cast(); - - final BindableInputWire heartbeatBindableA = scheduler.buildInputWire("heartbeatA"); - final BindableInputWire heartbeatBindableB = scheduler.buildInputWire("heartbeatB"); - final BindableInputWire heartbeatBindableC = scheduler.buildInputWire("heartbeatC"); - final BindableInputWire heartbeatBindableD = scheduler.buildInputWire("heartbeatD"); - - model.buildHeartbeatWire(100).solderTo(heartbeatBindableA); - model.buildHeartbeatWire(Duration.ofMillis(5)).solderTo(heartbeatBindableB); - model.buildHeartbeatWire(Duration.ofMillis(50)).solderTo(heartbeatBindableC); - model.buildHeartbeatWire(Duration.ofMillis(50)).solderTo(heartbeatBindableD); - - final AtomicLong counterA = new AtomicLong(0); - heartbeatBindableA.bindConsumer((now) -> counterA.incrementAndGet()); - - final AtomicLong counterB = new AtomicLong(0); - heartbeatBindableB.bindConsumer((now) -> counterB.incrementAndGet()); - - final AtomicLong counterC = new AtomicLong(0); - heartbeatBindableC.bindConsumer((now) -> counterC.incrementAndGet()); - - final AtomicLong counterD = new AtomicLong(0); - heartbeatBindableD.bindConsumer((now) -> counterD.incrementAndGet()); - - model.start(); - int milliseconds = 0; - while (milliseconds <= 1000) { - time.tick(Duration.ofMillis(1)); - milliseconds += 1; - model.tick(); - } - model.stop(); - - assertEquals(100, counterA.get()); - assertEquals(200, counterB.get()); - assertEquals(20, counterC.get()); - assertEquals(20, counterD.get()); - } -} diff --git a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/model/DeterministicModelTests.java b/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/model/DeterministicModelTests.java deleted file mode 100644 index 2309094d71e..00000000000 --- a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/model/DeterministicModelTests.java +++ /dev/null @@ -1,573 +0,0 @@ -/* - * Copyright (C) 2024 Hedera Hashgraph, LLC - * - * 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 com.swirlds.common.wiring.model; - -import static com.swirlds.common.test.fixtures.RandomUtils.getRandomPrintSeed; -import static com.swirlds.common.test.fixtures.RandomUtils.randomInstant; -import static com.swirlds.common.utility.NonCryptographicHashing.hash32; -import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerBuilder.UNLIMITED_CAPACITY; -import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.CONCURRENT; -import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.DIRECT; -import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.DIRECT_THREADSAFE; -import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.NO_OP; -import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.SEQUENTIAL; -import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.SEQUENTIAL_THREAD; -import static java.util.concurrent.TimeUnit.MICROSECONDS; -import static java.util.concurrent.TimeUnit.MILLISECONDS; -import static org.assertj.core.api.Fail.fail; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import com.swirlds.base.test.fixtures.time.FakeTime; -import com.swirlds.common.context.PlatformContext; -import com.swirlds.common.test.fixtures.platform.TestPlatformContextBuilder; -import com.swirlds.common.utility.NonCryptographicHashing; -import org.hiero.wiring.framework.model.DeterministicWiringModel; -import org.hiero.wiring.framework.model.WiringModel; -import org.hiero.wiring.framework.model.WiringModelBuilder; -import org.hiero.wiring.framework.schedulers.TaskScheduler; -import org.hiero.wiring.framework.wires.input.BindableInputWire; -import org.hiero.wiring.framework.wires.input.InputWire; -import org.hiero.wiring.framework.wires.output.OutputWire; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.time.Duration; -import java.time.Instant; -import java.util.Random; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicLong; -import java.util.concurrent.locks.ReentrantLock; -import java.util.function.BooleanSupplier; -import java.util.function.Function; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.ValueSource; - -class DeterministicModelTests { - - /** - * Build a handler method for "components" in the wiring generated by generateWiringMesh(). The goal of these - * handlers is to be extremely race condition prone if executed in parallel or in different serial order. - * - * @param random a random number generator - * @param discardChance a chance out of 1 that an input is simply discarded - * @param lock grab and release this lock each time the handler is called. This is a quick and dirty - * mechanism we can use to check for quiescence in a thread safe manner. - * @return a new handler - */ - @NonNull - private static Function buildHandler( - @NonNull final Random random, final double discardChance, final ReentrantLock lock) { - - final AtomicLong innerValue = new AtomicLong(); - return input -> { - - // This is locked by the outside scope when we are attempting - // to determine if the system is in a quiescent state. - lock.lock(); - lock.unlock(); - - if (discardChance > 0 && (random.nextDouble() < discardChance)) { - // Discard this input - return null; - } - - final long newValue = NonCryptographicHashing.hash64(innerValue.get(), input, random.nextLong()); - innerValue.set(newValue); - - // Sleep half a millisecond, on average. - final long sleepMicros = Math.abs(newValue) % 1000; - try { - MICROSECONDS.sleep(sleepMicros); - } catch (final InterruptedException e) { - Thread.currentThread().interrupt(); - throw new RuntimeException(e); - } - - return newValue; - }; - } - - /** - * A test wiring mesh for testing deterministic behavior - * - * @param inputWire the input wire for the mesh - * @param outputValue contains the final result (when isQuiescent() returns true) - * @param isQuiescent returns true when there is no longer data flowing through the mesh - */ - private record WiringMesh( - @NonNull InputWire inputWire, - @NonNull AtomicLong outputValue, - @NonNull BooleanSupplier isQuiescent) {} - - /** - * Generates a wiring mesh that yields non-deterministic results when data is fed in using the standard wiring - * model. - * - * @param seed the seed to use for the random number generator - * @param wiringModel the wiring model to use - * @param enableHeartbeat whether to enable a heartbeat scheduler, useful for ensuring that the standard case is - * non-deterministic even without a heartbeat introducing artifacts from the wall clock - * @return the input wire to feed data into the mesh - */ - @NonNull - private static WiringMesh generateWiringMesh( - final long seed, @NonNull final WiringModel wiringModel, final boolean enableHeartbeat) { - - // - Data is fed into A - // - Data comes out of J - // - B is a concurrent scheduler - // - H and I are direct schedulers - // - K is a no op scheduler - // - All other schedulers are sequential or sequential thread - // - Scheduler D discards 60% of all input. This means that the probability of data cycling an infinite - // number of times in the loop asymptotically approaches 0 over time. - // - All other schedulers discard 1% of their input. - - /* - - A - | - v - B <---------- Heartbeat (5ms) - | - v - C - | - v - D -----> E K - ^ | ^ - | v | - G <----- F -----> H -----> I -----> J - - */ - - final Random random = new Random(seed); - - final ReentrantLock lock = new ReentrantLock(); - - final TaskScheduler schedulerA = wiringModel - .schedulerBuilder("A") - .withType(SEQUENTIAL) - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .withFlushingEnabled(true) - .build() - .cast(); - final BindableInputWire inA = schedulerA.buildInputWire("inA"); - inA.bind(buildHandler(random, 0.01, lock)); - final OutputWire outA = schedulerA.getOutputWire(); - - final TaskScheduler schedulerB = wiringModel - .schedulerBuilder("B") - .withType(CONCURRENT) - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .withFlushingEnabled(true) - .build() - .cast(); - final BindableInputWire inB = schedulerB.buildInputWire("inB"); - inB.bind(buildHandler(random, 0.01, lock)); - final BindableInputWire schedulerBHeartbeat = schedulerB.buildInputWire("heartbeatB"); - final Function heartbeatHandler = buildHandler(random, 0, lock); - schedulerBHeartbeat.bind(instant -> { - System.out.println(instant); - return heartbeatHandler.apply(instant.toEpochMilli()); - }); - final OutputWire outB = schedulerB.getOutputWire(); - - final TaskScheduler schedulerC = wiringModel - .schedulerBuilder("C") - .withType(SEQUENTIAL_THREAD) - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .withFlushingEnabled(true) - .build() - .cast(); - final BindableInputWire inC = schedulerC.buildInputWire("inC"); - inC.bind(buildHandler(random, 0.01, lock)); - final OutputWire outC = schedulerC.getOutputWire(); - - final TaskScheduler schedulerD = wiringModel - .schedulerBuilder("D") - .withType(SEQUENTIAL) - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .withFlushingEnabled(true) - .build() - .cast(); - final BindableInputWire inD = schedulerD.buildInputWire("inD"); - inD.bind(buildHandler(random, 0.6, lock)); // This must be >0.5 else risk infinite loop - final OutputWire outD = schedulerD.getOutputWire(); - - final TaskScheduler schedulerE = wiringModel - .schedulerBuilder("E") - .withType(SEQUENTIAL) - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .withFlushingEnabled(true) - .build() - .cast(); - final BindableInputWire inE = schedulerE.buildInputWire("inE"); - inE.bind(buildHandler(random, 0.01, lock)); - final OutputWire outE = schedulerE.getOutputWire(); - - final TaskScheduler schedulerF = wiringModel - .schedulerBuilder("F") - .withType(SEQUENTIAL) - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .withFlushingEnabled(true) - .build() - .cast(); - final BindableInputWire inF = schedulerF.buildInputWire("inF"); - inF.bind(buildHandler(random, 0.01, lock)); - final OutputWire outF = schedulerF.getOutputWire(); - - final TaskScheduler schedulerG = wiringModel - .schedulerBuilder("G") - .withType(SEQUENTIAL) - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .withFlushingEnabled(true) - .build() - .cast(); - final BindableInputWire inG = schedulerG.buildInputWire("inG"); - inG.bind(buildHandler(random, 0.01, lock)); - final OutputWire outG = schedulerG.getOutputWire(); - - final TaskScheduler schedulerH = wiringModel - .schedulerBuilder("H") - .withType(DIRECT) - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .withFlushingEnabled(true) - .build() - .cast(); - final BindableInputWire inH = schedulerH.buildInputWire("inH"); - inH.bind(buildHandler(random, 0.01, lock)); - final OutputWire outH = schedulerH.getOutputWire(); - - final TaskScheduler schedulerI = wiringModel - .schedulerBuilder("I") - .withType(DIRECT_THREADSAFE) - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .withFlushingEnabled(true) - .build() - .cast(); - final BindableInputWire inI = schedulerI.buildInputWire("inI"); - inI.bind(buildHandler(random, 0.01, lock)); - final OutputWire outI = schedulerI.getOutputWire(); - - final TaskScheduler schedulerJ = wiringModel - .schedulerBuilder("J") - .withType(SEQUENTIAL) - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .withFlushingEnabled(true) - .build() - .cast(); - final BindableInputWire inJ = schedulerJ.buildInputWire("inJ"); - inJ.bind(buildHandler(random, 0.01, lock)); - final OutputWire outJ = schedulerJ.getOutputWire(); - - final TaskScheduler schedulerK = wiringModel - .schedulerBuilder("K") - .withType(NO_OP) - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .withFlushingEnabled(true) - .build() - .cast(); - final BindableInputWire inK = schedulerK.buildInputWire("inK"); - inK.bind(buildHandler(random, 0.01, lock)); - - outA.solderTo(inB); - if (enableHeartbeat) { - wiringModel.buildHeartbeatWire(Duration.ofMillis(5)).solderTo(schedulerBHeartbeat); - } - outB.solderTo(inC); - outC.solderTo(inD); - outD.solderTo(inE); - outE.solderTo(inF); - outF.solderTo(inG); - outG.solderTo(inD); - outF.solderTo(inH); - outH.solderTo(inI); - outI.solderTo(inJ); - outI.solderTo(inK); - - // Write the final output to the atomic long provided - final AtomicLong outputValue = new AtomicLong(); - outJ.solderTo("finalOutput", "data", outputValue::set); - - final BooleanSupplier isQuiescent = () -> { - lock.lock(); - try { - return schedulerA.getUnprocessedTaskCount() == 0 - && schedulerB.getUnprocessedTaskCount() == 0 - && schedulerC.getUnprocessedTaskCount() == 0 - && schedulerD.getUnprocessedTaskCount() == 0 - && schedulerE.getUnprocessedTaskCount() == 0 - && schedulerF.getUnprocessedTaskCount() == 0 - && schedulerG.getUnprocessedTaskCount() == 0 - && schedulerH.getUnprocessedTaskCount() == 0 - && schedulerI.getUnprocessedTaskCount() == 0 - && schedulerJ.getUnprocessedTaskCount() == 0 - && schedulerK.getUnprocessedTaskCount() == 0; - } finally { - lock.unlock(); - } - }; - - wiringModel.start(); - - // Enable this and copy it into mermaid.live to visualize the wiring in this test - // final String diagram = wiringModel.generateWiringDiagram(List.of(), List.of(), List.of(), false); - // System.out.println(diagram); - - return new WiringMesh(inA, outputValue, isQuiescent); - } - - /** - * Feed a bunch of data into the mesh and return the value once all data has been processed. - * - * @param seed the seed to use for the random number generator - * @param mesh the wiring mesh to evaluate - * @param waitForNextCycle a runnable that will be called each time the mesh is checked for quiescence - */ - private static long evaluateMesh( - @NonNull final long seed, @NonNull final WiringMesh mesh, @NonNull final Runnable waitForNextCycle) { - - final Random random = new Random(seed); - - // Feed in data - for (long i = 0; i < 100; i++) { - final long next = random.nextLong(); - mesh.inputWire.put(next); - } - - int maxIterations = 20_000; - while (!mesh.isQuiescent.getAsBoolean()) { - waitForNextCycle.run(); - - maxIterations--; - assertTrue(maxIterations > 0, "mesh did not quiesce in time"); - } - - return mesh.outputValue.get(); - } - - /** - * The purpose of this test is to verify that the test setup is non-deterministic when using the standard wiring - * model. - */ - @ParameterizedTest - @ValueSource(booleans = {true, false}) - void verifyStandardNondeterminism(final boolean enableHeartbeat) { - final Random random = getRandomPrintSeed(); - final long meshSeed = random.nextLong(); - final long dataSeed = random.nextLong(); - - final PlatformContext platformContext = - TestPlatformContextBuilder.create().build(); - - final long value1 = evaluateMesh( - dataSeed, - generateWiringMesh( - meshSeed, WiringModelBuilder.create(platformContext).build(), enableHeartbeat), - () -> { - try { - MILLISECONDS.sleep(1); - } catch (final InterruptedException e) { - Thread.currentThread().interrupt(); - throw new RuntimeException(e); - } - }); - - final long value2 = evaluateMesh( - dataSeed, - generateWiringMesh( - meshSeed, WiringModelBuilder.create(platformContext).build(), enableHeartbeat), - () -> { - try { - MILLISECONDS.sleep(1); - } catch (final InterruptedException e) { - Thread.currentThread().interrupt(); - throw new RuntimeException(e); - } - }); - - assertNotEquals(value1, value2); - } - - @Test - void verifyDeterministicModel() { - final Random random = getRandomPrintSeed(); - final long meshSeed = random.nextLong(); - final long dataSeed = random.nextLong(); - - final FakeTime time = new FakeTime(randomInstant(random), Duration.ZERO); - final PlatformContext platformContext = - TestPlatformContextBuilder.create().withTime(time).build(); - - final DeterministicWiringModel deterministicWiringModel1 = WiringModelBuilder.create(platformContext) - .withDeterministicModeEnabled(true) - .build(); - final long value1 = - evaluateMesh(dataSeed, generateWiringMesh(meshSeed, deterministicWiringModel1, true), () -> { - time.tick(Duration.ofMillis(1)); - deterministicWiringModel1.tick(); - }); - - time.reset(); - final DeterministicWiringModel deterministicWiringModel2 = WiringModelBuilder.create(platformContext) - .withDeterministicModeEnabled(true) - .build(); - final long value2 = - evaluateMesh(dataSeed, generateWiringMesh(meshSeed, deterministicWiringModel2, true), () -> { - time.tick(Duration.ofMillis(1)); - deterministicWiringModel2.tick(); - }); - - assertEquals(value1, value2); - } - - /** - * Test a scenario where there is a circular data flow formed by wires. - *

    - * In this test, all data is passed from A to B to C to D. All data that is a multiple of 7 is passed from D to A as - * a negative value, but is not passed around the loop again. - * - *

    -     * A -------> B
    -     * ^          |
    -     * |          |
    -     * |          V
    -     * D <------- C
    -     * 
    - */ - @Test - void circularDataFlowTest() { - final PlatformContext platformContext = - TestPlatformContextBuilder.create().build(); - final DeterministicWiringModel model = WiringModelBuilder.create(platformContext) - .withDeterministicModeEnabled(true) - .build(); - - final AtomicInteger countA = new AtomicInteger(); - final AtomicInteger negativeCountA = new AtomicInteger(); - final AtomicInteger countB = new AtomicInteger(); - final AtomicInteger countC = new AtomicInteger(); - final AtomicInteger countD = new AtomicInteger(); - - final TaskScheduler taskSchedulerToA = model.schedulerBuilder("wireToA") - .withType(SEQUENTIAL) - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .build() - .cast(); - final TaskScheduler taskSchedulerToB = model.schedulerBuilder("wireToB") - .withType(SEQUENTIAL_THREAD) - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .build() - .cast(); - final TaskScheduler taskSchedulerToC = model.schedulerBuilder("wireToC") - .withType(CONCURRENT) - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .build() - .cast(); - final TaskScheduler taskSchedulerToD = model.schedulerBuilder("wireToD") - .withType(DIRECT) - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .build() - .cast(); - - final BindableInputWire channelToA = taskSchedulerToA.buildInputWire("channelToA"); - final BindableInputWire channelToB = taskSchedulerToB.buildInputWire("channelToB"); - final BindableInputWire channelToC = taskSchedulerToC.buildInputWire("channelToC"); - final BindableInputWire channelToD = taskSchedulerToD.buildInputWire("channelToD"); - - final Function handlerA = x -> { - if (x > 0) { - countA.set(hash32(x, countA.get())); - return x; - } else { - negativeCountA.set(hash32(x, negativeCountA.get())); - // negative values are values that have been passed around the loop - // Don't pass them on again or else we will get an infinite loop - return null; - } - }; - - final Function handlerB = x -> { - countB.set(hash32(x, countB.get())); - return x; - }; - - final Function handlerC = x -> { - countC.set(hash32(x, countC.get())); - return x; - }; - - final Function handlerD = x -> { - countD.set(hash32(x, countD.get())); - if (x % 7 == 0) { - return -x; - } else { - return null; - } - }; - - taskSchedulerToA.getOutputWire().solderTo(channelToB); - taskSchedulerToB.getOutputWire().solderTo(channelToC); - taskSchedulerToC.getOutputWire().solderTo(channelToD); - taskSchedulerToD.getOutputWire().solderTo(channelToA); - - channelToA.bind(handlerA); - channelToB.bind(handlerB); - channelToC.bind(handlerC); - channelToD.bind(handlerD); - - model.start(); - - int expectedCountA = 0; - int expectedNegativeCountA = 0; - int expectedCountB = 0; - int expectedCountC = 0; - int expectedCountD = 0; - - for (int i = 1; i < 1000; i++) { - channelToA.put(i); - - expectedCountA = hash32(i, expectedCountA); - expectedCountB = hash32(i, expectedCountB); - expectedCountC = hash32(i, expectedCountC); - expectedCountD = hash32(i, expectedCountD); - - if (i % 7 == 0) { - expectedNegativeCountA = hash32(-i, expectedNegativeCountA); - } - } - - int maxTicks = 10_000; - while (true) { - if (maxTicks-- == 0) { - fail("Model did not quiesce in time"); - } - model.tick(); - if (expectedCountA == countA.get() - && expectedNegativeCountA == negativeCountA.get() - && expectedCountB == countB.get() - && expectedCountC == countC.get() - && expectedCountD == countD.get()) { - break; - } - } - - model.stop(); - } -} diff --git a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/model/ModelTests.java b/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/model/ModelTests.java deleted file mode 100644 index 745c2d24508..00000000000 --- a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/model/ModelTests.java +++ /dev/null @@ -1,1765 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * 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 com.swirlds.common.wiring.model; - -import static com.swirlds.common.threading.framework.internal.AbstractQueueThreadConfiguration.UNLIMITED_CAPACITY; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import com.swirlds.common.test.fixtures.platform.TestPlatformContextBuilder; -import org.hiero.wiring.framework.model.WiringModel; -import org.hiero.wiring.framework.model.WiringModelBuilder; -import org.hiero.wiring.framework.schedulers.TaskScheduler; -import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; -import org.hiero.wiring.framework.wires.SolderType; -import org.hiero.wiring.framework.wires.input.BindableInputWire; -import org.hiero.wiring.framework.wires.input.InputWire; -import org.hiero.wiring.framework.wires.output.OutputWire; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.List; -import org.junit.jupiter.api.Test; - -class ModelTests { - - /** - * For debugging with a human in the loop. - */ - private static final boolean printMermaidDiagram = false; - - /** - * Validate the model. - * - * @param model the model to validate - * @param cycleExpected true if a cycle is expected, false otherwise - * @param illegalDirectSchedulerUseExpected true if illegal direct scheduler use is expected, false otherwise - */ - private static void validateModel( - @NonNull final WiringModel model, - final boolean cycleExpected, - final boolean illegalDirectSchedulerUseExpected) { - - final boolean cycleDetected = model.checkForCyclicalBackpressure(); - assertEquals(cycleExpected, cycleDetected); - - final boolean illegalDirectSchedulerUseDetected = model.checkForIllegalDirectSchedulerUsage(); - assertEquals(illegalDirectSchedulerUseExpected, illegalDirectSchedulerUseDetected); - - // Should not throw. - final String diagram = model.generateWiringDiagram(List.of(), List.of(), List.of(), false); - if (printMermaidDiagram) { - System.out.println(diagram); - } - } - - @Test - void emptyModelTest() { - final WiringModel model = WiringModelBuilder.create( - TestPlatformContextBuilder.create().build()) - .build(); - validateModel(model, false, false); - } - - @Test - void singleVertexTest() { - final WiringModel model = WiringModelBuilder.create( - TestPlatformContextBuilder.create().build()) - .build(); - - /* - - A - - */ - - final TaskScheduler taskSchedulerA = model.schedulerBuilder("A") - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .build() - .cast(); - - validateModel(model, false, false); - } - - @Test - void shortChainTest() { - final WiringModel model = WiringModelBuilder.create( - TestPlatformContextBuilder.create().build()) - .build(); - - /* - - A -> B -> C - - */ - - final TaskScheduler taskSchedulerA = - model.schedulerBuilder("A").withUnhandledTaskCapacity(1).build().cast(); - - final TaskScheduler taskSchedulerB = - model.schedulerBuilder("B").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputB = taskSchedulerB.buildInputWire("inputB"); - - final TaskScheduler taskSchedulerC = - model.schedulerBuilder("C").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputC = taskSchedulerC.buildInputWire("inputC"); - - taskSchedulerA.getOutputWire().solderTo(inputB); - taskSchedulerB.getOutputWire().solderTo(inputC); - - validateModel(model, false, false); - } - - @Test - void loopSizeOneTest() { - final WiringModel model = WiringModelBuilder.create( - TestPlatformContextBuilder.create().build()) - .build(); - - /* - - A --| - ^ | - |---| - - */ - - final TaskScheduler taskSchedulerA = - model.schedulerBuilder("A").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputA = taskSchedulerA.buildInputWire("inputA"); - - taskSchedulerA.getOutputWire().solderTo(inputA); - - validateModel(model, true, false); - } - - @Test - void loopSizeOneBrokenByInjectionTest() { - final WiringModel model = WiringModelBuilder.create( - TestPlatformContextBuilder.create().build()) - .build(); - - /* - - A --| - ^ | - |---| - - */ - - final TaskScheduler taskSchedulerA = - model.schedulerBuilder("A").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputA = taskSchedulerA.buildInputWire("inputA"); - - taskSchedulerA.getOutputWire().solderTo(inputA, SolderType.INJECT); - - validateModel(model, false, false); - } - - @Test - void loopSizeTwoTest() { - final WiringModel model = WiringModelBuilder.create( - TestPlatformContextBuilder.create().build()) - .build(); - - /* - - A -> B - ^ | - |----| - - */ - - final TaskScheduler taskSchedulerA = - model.schedulerBuilder("A").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputA = taskSchedulerA.buildInputWire("inputA"); - - final TaskScheduler taskSchedulerB = - model.schedulerBuilder("B").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputB = taskSchedulerB.buildInputWire("inputB"); - - taskSchedulerA.getOutputWire().solderTo(inputB); - taskSchedulerB.getOutputWire().solderTo(inputA); - - validateModel(model, true, false); - } - - @Test - void loopSizeTwoBrokenByInjectionTest() { - final WiringModel model = WiringModelBuilder.create( - TestPlatformContextBuilder.create().build()) - .build(); - - /* - - A -> B - ^ | - |----| - - */ - - final TaskScheduler taskSchedulerA = - model.schedulerBuilder("A").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputA = taskSchedulerA.buildInputWire("inputA"); - - final TaskScheduler taskSchedulerB = - model.schedulerBuilder("B").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputB = taskSchedulerB.buildInputWire("inputB"); - - taskSchedulerA.getOutputWire().solderTo(inputB); - taskSchedulerB.getOutputWire().solderTo(inputA, SolderType.INJECT); - - validateModel(model, false, false); - } - - @Test - void loopSizeTwoBrokenByMissingBoundTest() { - final WiringModel model = WiringModelBuilder.create( - TestPlatformContextBuilder.create().build()) - .build(); - - /* - - A -> B - ^ | - |----| - - */ - - final TaskScheduler taskSchedulerA = model.schedulerBuilder("A") - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .build() - .cast(); - final InputWire inputA = taskSchedulerA.buildInputWire("inputA"); - - final TaskScheduler taskSchedulerB = - model.schedulerBuilder("B").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputB = taskSchedulerB.buildInputWire("inputB"); - - taskSchedulerA.getOutputWire().solderTo(inputB); - taskSchedulerB.getOutputWire().solderTo(inputA); - - validateModel(model, false, false); - } - - @Test - void loopSizeThreeTest() { - final WiringModel model = WiringModelBuilder.create( - TestPlatformContextBuilder.create().build()) - .build(); - - /* - - A -> B -> C - ^ | - |---------| - - */ - - final TaskScheduler taskSchedulerA = - model.schedulerBuilder("A").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputA = taskSchedulerA.buildInputWire("inputA"); - - final TaskScheduler taskSchedulerB = - model.schedulerBuilder("B").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputB = taskSchedulerB.buildInputWire("inputB"); - - final TaskScheduler taskSchedulerC = - model.schedulerBuilder("C").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputC = taskSchedulerC.buildInputWire("inputC"); - - taskSchedulerA.getOutputWire().solderTo(inputB); - taskSchedulerB.getOutputWire().solderTo(inputC); - taskSchedulerC.getOutputWire().solderTo(inputA); - - validateModel(model, true, false); - } - - @Test - void loopSizeThreeBrokenByInjectionTest() { - final WiringModel model = WiringModelBuilder.create( - TestPlatformContextBuilder.create().build()) - .build(); - - /* - - A -> B -> C - ^ | - |---------| - - */ - - final TaskScheduler taskSchedulerA = - model.schedulerBuilder("A").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputA = taskSchedulerA.buildInputWire("inputA"); - - final TaskScheduler taskSchedulerB = - model.schedulerBuilder("B").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputB = taskSchedulerB.buildInputWire("inputB"); - - final TaskScheduler taskSchedulerC = - model.schedulerBuilder("C").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputC = taskSchedulerC.buildInputWire("inputC"); - - taskSchedulerA.getOutputWire().solderTo(inputB); - taskSchedulerB.getOutputWire().solderTo(inputC); - taskSchedulerC.getOutputWire().solderTo(inputA, SolderType.INJECT); - - validateModel(model, false, false); - } - - @Test - void loopSizeThreeBrokenByMissingBoundTest() { - final WiringModel model = WiringModelBuilder.create( - TestPlatformContextBuilder.create().build()) - .build(); - - /* - - A -> B -> C - ^ | - |---------| - - */ - - final TaskScheduler taskSchedulerA = - model.schedulerBuilder("A").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputA = taskSchedulerA.buildInputWire("inputA"); - - final TaskScheduler taskSchedulerB = - model.schedulerBuilder("B").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputB = taskSchedulerB.buildInputWire("inputB"); - - final TaskScheduler taskSchedulerC = model.schedulerBuilder("C") - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .build() - .cast(); - final InputWire inputC = taskSchedulerC.buildInputWire("inputC"); - - taskSchedulerA.getOutputWire().solderTo(inputB); - taskSchedulerB.getOutputWire().solderTo(inputC); - taskSchedulerC.getOutputWire().solderTo(inputA); - - validateModel(model, false, false); - } - - @Test - void loopSizeFourTest() { - final WiringModel model = WiringModelBuilder.create( - TestPlatformContextBuilder.create().build()) - .build(); - - /* - - A -----> B - ^ | - | v - D <----- C - - */ - - final TaskScheduler taskSchedulerA = - model.schedulerBuilder("A").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputA = taskSchedulerA.buildInputWire("inputA"); - - final TaskScheduler taskSchedulerB = - model.schedulerBuilder("B").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputB = taskSchedulerB.buildInputWire("inputB"); - - final TaskScheduler taskSchedulerC = - model.schedulerBuilder("C").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputC = taskSchedulerC.buildInputWire("inputC"); - - final TaskScheduler taskSchedulerD = - model.schedulerBuilder("D").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputD = taskSchedulerD.buildInputWire("inputD"); - - taskSchedulerA.getOutputWire().solderTo(inputB); - taskSchedulerB.getOutputWire().solderTo(inputC); - taskSchedulerC.getOutputWire().solderTo(inputD); - taskSchedulerD.getOutputWire().solderTo(inputA); - - validateModel(model, true, false); - } - - @Test - void loopSizeFourBrokenByInjectionTest() { - final WiringModel model = WiringModelBuilder.create( - TestPlatformContextBuilder.create().build()) - .build(); - - /* - - A -----> B - ^ | - | v - D <----- C - - */ - - final TaskScheduler taskSchedulerA = - model.schedulerBuilder("A").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputA = taskSchedulerA.buildInputWire("inputA"); - - final TaskScheduler taskSchedulerB = - model.schedulerBuilder("B").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputB = taskSchedulerB.buildInputWire("inputB"); - - final TaskScheduler taskSchedulerC = - model.schedulerBuilder("C").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputC = taskSchedulerC.buildInputWire("inputC"); - - final TaskScheduler taskSchedulerD = model.schedulerBuilder("D") - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .build() - .cast(); - final InputWire inputD = taskSchedulerD.buildInputWire("inputD"); - - taskSchedulerA.getOutputWire().solderTo(inputB); - taskSchedulerB.getOutputWire().solderTo(inputC); - taskSchedulerC.getOutputWire().solderTo(inputD); - taskSchedulerD.getOutputWire().solderTo(inputA, SolderType.INJECT); - - validateModel(model, false, false); - } - - @Test - void loopSizeFourBrokenByMissingBoundTest() { - final WiringModel model = WiringModelBuilder.create( - TestPlatformContextBuilder.create().build()) - .build(); - - /* - - A -----> B - ^ | - | v - D <----- C - - */ - - final TaskScheduler taskSchedulerA = - model.schedulerBuilder("A").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputA = taskSchedulerA.buildInputWire("inputA"); - - final TaskScheduler taskSchedulerB = - model.schedulerBuilder("B").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputB = taskSchedulerB.buildInputWire("inputB"); - - final TaskScheduler taskSchedulerC = - model.schedulerBuilder("C").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputC = taskSchedulerC.buildInputWire("inputC"); - - final TaskScheduler taskSchedulerD = - model.schedulerBuilder("D").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputD = taskSchedulerD.buildInputWire("inputD"); - - taskSchedulerA.getOutputWire().solderTo(inputB); - taskSchedulerB.getOutputWire().solderTo(inputC); - taskSchedulerC.getOutputWire().solderTo(inputD); - taskSchedulerD.getOutputWire().solderTo(inputA); - - validateModel(model, true, false); - } - - @Test - void loopSizeFourWithChainTest() { - final WiringModel model = WiringModelBuilder.create( - TestPlatformContextBuilder.create().build()) - .build(); - - /* - - A - | - v - B - | - v - C - | - v - D -----> E - ^ | - | v - G <----- F -----> H -----> I -----> J - - */ - - final TaskScheduler taskSchedulerA = - model.schedulerBuilder("A").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputA = taskSchedulerA.buildInputWire("inputA"); - - final TaskScheduler taskSchedulerB = - model.schedulerBuilder("B").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputB = taskSchedulerB.buildInputWire("inputB"); - - final TaskScheduler taskSchedulerC = - model.schedulerBuilder("C").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputC = taskSchedulerC.buildInputWire("inputC"); - - final TaskScheduler taskSchedulerD = - model.schedulerBuilder("D").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputD = taskSchedulerD.buildInputWire("inputD"); - - final TaskScheduler taskSchedulerE = - model.schedulerBuilder("E").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputE = taskSchedulerE.buildInputWire("inputE"); - - final TaskScheduler taskSchedulerF = - model.schedulerBuilder("F").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputF = taskSchedulerF.buildInputWire("inputF"); - - final TaskScheduler taskSchedulerG = - model.schedulerBuilder("G").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputG = taskSchedulerG.buildInputWire("inputG"); - - final TaskScheduler taskSchedulerH = - model.schedulerBuilder("H").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputH = taskSchedulerH.buildInputWire("inputH"); - - final TaskScheduler taskSchedulerI = - model.schedulerBuilder("I").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputI = taskSchedulerI.buildInputWire("inputI"); - - final TaskScheduler taskSchedulerJ = - model.schedulerBuilder("J").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputJ = taskSchedulerJ.buildInputWire("inputJ"); - - taskSchedulerA.getOutputWire().solderTo(inputB); - taskSchedulerB.getOutputWire().solderTo(inputC); - taskSchedulerC.getOutputWire().solderTo(inputD); - taskSchedulerD.getOutputWire().solderTo(inputE); - taskSchedulerE.getOutputWire().solderTo(inputF); - taskSchedulerF.getOutputWire().solderTo(inputG); - taskSchedulerG.getOutputWire().solderTo(inputD); - - taskSchedulerF.getOutputWire().solderTo(inputH); - taskSchedulerH.getOutputWire().solderTo(inputI); - taskSchedulerI.getOutputWire().solderTo(inputJ); - - validateModel(model, true, false); - } - - @Test - void loopSizeFourWithChainBrokenByInjectionTest() { - final WiringModel model = WiringModelBuilder.create( - TestPlatformContextBuilder.create().build()) - .build(); - - /* - - A - | - v - B - | - v - C - | - v - D -----> E - ^ | - | v - G <----- F -----> H -----> I -----> J - - */ - - final TaskScheduler taskSchedulerA = - model.schedulerBuilder("A").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputA = taskSchedulerA.buildInputWire("inputA"); - - final TaskScheduler taskSchedulerB = - model.schedulerBuilder("B").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputB = taskSchedulerB.buildInputWire("inputB"); - - final TaskScheduler taskSchedulerC = - model.schedulerBuilder("C").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputC = taskSchedulerC.buildInputWire("inputC"); - - final TaskScheduler taskSchedulerD = - model.schedulerBuilder("D").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputD = taskSchedulerD.buildInputWire("inputD"); - - final TaskScheduler taskSchedulerE = - model.schedulerBuilder("E").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputE = taskSchedulerE.buildInputWire("inputE"); - - final TaskScheduler taskSchedulerF = - model.schedulerBuilder("F").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputF = taskSchedulerF.buildInputWire("inputF"); - - final TaskScheduler taskSchedulerG = - model.schedulerBuilder("G").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputG = taskSchedulerG.buildInputWire("inputG"); - - final TaskScheduler taskSchedulerH = - model.schedulerBuilder("H").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputH = taskSchedulerH.buildInputWire("inputH"); - - final TaskScheduler taskSchedulerI = - model.schedulerBuilder("I").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputI = taskSchedulerI.buildInputWire("inputI"); - - final TaskScheduler taskSchedulerJ = - model.schedulerBuilder("J").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputJ = taskSchedulerJ.buildInputWire(""); - - taskSchedulerA.getOutputWire().solderTo(inputB); - taskSchedulerB.getOutputWire().solderTo(inputC); - taskSchedulerC.getOutputWire().solderTo(inputD); - taskSchedulerD.getOutputWire().solderTo(inputE); - taskSchedulerE.getOutputWire().solderTo(inputF); - taskSchedulerF.getOutputWire().solderTo(inputG); - taskSchedulerG.getOutputWire().solderTo(inputD, SolderType.INJECT); - - taskSchedulerF.getOutputWire().solderTo(inputH); - taskSchedulerH.getOutputWire().solderTo(inputI); - taskSchedulerI.getOutputWire().solderTo(inputJ); - - validateModel(model, false, false); - } - - @Test - void loopSizeFourWithChainBrokenByMissingBoundTest() { - final WiringModel model = WiringModelBuilder.create( - TestPlatformContextBuilder.create().build()) - .build(); - - /* - - A - | - v - B - | - v - C - | - v - D -----> E - ^ | - | v - G <----- F -----> H -----> I -----> J - - */ - - final TaskScheduler taskSchedulerA = - model.schedulerBuilder("A").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputA = taskSchedulerA.buildInputWire("inputA"); - - final TaskScheduler taskSchedulerB = - model.schedulerBuilder("B").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputB = taskSchedulerB.buildInputWire("inputB"); - - final TaskScheduler taskSchedulerC = - model.schedulerBuilder("C").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputC = taskSchedulerC.buildInputWire("inputC"); - - final TaskScheduler taskSchedulerD = model.schedulerBuilder("D") - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .build() - .cast(); - final InputWire inputD = taskSchedulerD.buildInputWire("inputD"); - - final TaskScheduler taskSchedulerE = - model.schedulerBuilder("E").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputE = taskSchedulerE.buildInputWire("inputE"); - - final TaskScheduler taskSchedulerF = - model.schedulerBuilder("F").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputF = taskSchedulerF.buildInputWire("inputF"); - - final TaskScheduler taskSchedulerG = - model.schedulerBuilder("G").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputG = taskSchedulerG.buildInputWire("inputG"); - - final TaskScheduler taskSchedulerH = - model.schedulerBuilder("H").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputH = taskSchedulerH.buildInputWire("inputH"); - - final TaskScheduler taskSchedulerI = - model.schedulerBuilder("I").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputI = taskSchedulerI.buildInputWire("inputI"); - - final TaskScheduler taskSchedulerJ = - model.schedulerBuilder("J").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputJ = taskSchedulerJ.buildInputWire("inputJ"); - - taskSchedulerA.getOutputWire().solderTo(inputB); - taskSchedulerB.getOutputWire().solderTo(inputC); - taskSchedulerC.getOutputWire().solderTo(inputD); - taskSchedulerD.getOutputWire().solderTo(inputE); - taskSchedulerE.getOutputWire().solderTo(inputF); - taskSchedulerF.getOutputWire().solderTo(inputG); - taskSchedulerG.getOutputWire().solderTo(inputD); - - taskSchedulerF.getOutputWire().solderTo(inputH); - taskSchedulerH.getOutputWire().solderTo(inputI); - taskSchedulerI.getOutputWire().solderTo(inputJ); - - validateModel(model, false, false); - } - - @Test - void multiLoopTest() { - final WiringModel model = WiringModelBuilder.create( - TestPlatformContextBuilder.create().build()) - .build(); - - /* - - A <---------------------------------| - | | - v | - B | - | | - v | - C | - | | - v | - D -----> E <---------------| | - ^ | | | - | v | | - G <----- F -----> H -----> I -----> J - - */ - - final TaskScheduler taskSchedulerA = - model.schedulerBuilder("A").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputA = taskSchedulerA.buildInputWire("inputA"); - - final TaskScheduler taskSchedulerB = - model.schedulerBuilder("B").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputB = taskSchedulerB.buildInputWire("inputB"); - - final TaskScheduler taskSchedulerC = - model.schedulerBuilder("C").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputC = taskSchedulerC.buildInputWire("inputC"); - - final TaskScheduler taskSchedulerD = - model.schedulerBuilder("D").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputD = taskSchedulerD.buildInputWire("inputD"); - - final TaskScheduler taskSchedulerE = - model.schedulerBuilder("E").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputE = taskSchedulerE.buildInputWire("inputE"); - - final TaskScheduler taskSchedulerF = - model.schedulerBuilder("F").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputF = taskSchedulerF.buildInputWire("inputF"); - - final TaskScheduler taskSchedulerG = - model.schedulerBuilder("G").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputG = taskSchedulerG.buildInputWire("inputG"); - - final TaskScheduler taskSchedulerH = - model.schedulerBuilder("H").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputH = taskSchedulerH.buildInputWire("inputH"); - - final TaskScheduler taskSchedulerI = - model.schedulerBuilder("I").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputI = taskSchedulerI.buildInputWire("inputI"); - - final TaskScheduler taskSchedulerJ = - model.schedulerBuilder("J").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputJ = taskSchedulerJ.buildInputWire("inputJ"); - - taskSchedulerA.getOutputWire().solderTo(inputB); - taskSchedulerB.getOutputWire().solderTo(inputC); - taskSchedulerC.getOutputWire().solderTo(inputD); - taskSchedulerD.getOutputWire().solderTo(inputE); - taskSchedulerE.getOutputWire().solderTo(inputF); - taskSchedulerF.getOutputWire().solderTo(inputG); - taskSchedulerG.getOutputWire().solderTo(inputD); - - taskSchedulerF.getOutputWire().solderTo(inputH); - taskSchedulerH.getOutputWire().solderTo(inputI); - taskSchedulerI.getOutputWire().solderTo(inputJ); - - taskSchedulerJ.getOutputWire().solderTo(inputA); - - taskSchedulerI.getOutputWire().solderTo(inputE); - - validateModel(model, true, false); - } - - @Test - void multiLoopBrokenByInjectionTest() { - final WiringModel model = WiringModelBuilder.create( - TestPlatformContextBuilder.create().build()) - .build(); - - /* - - A <---------------------------------| - | | - v | - B | - | | - v | - C | - | | - v | - D -----> E <---------------| | - ^ | | | - | v | | - G <----- F -----> H -----> I -----> J - - */ - - final TaskScheduler taskSchedulerA = - model.schedulerBuilder("A").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputA = taskSchedulerA.buildInputWire("inputA"); - - final TaskScheduler taskSchedulerB = - model.schedulerBuilder("B").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputB = taskSchedulerB.buildInputWire("inputB"); - - final TaskScheduler taskSchedulerC = - model.schedulerBuilder("C").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputC = taskSchedulerC.buildInputWire("inputC"); - - final TaskScheduler taskSchedulerD = - model.schedulerBuilder("D").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputD = taskSchedulerD.buildInputWire("inputD"); - - final TaskScheduler taskSchedulerE = - model.schedulerBuilder("E").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputE = taskSchedulerE.buildInputWire("inputE"); - - final TaskScheduler taskSchedulerF = - model.schedulerBuilder("F").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputF = taskSchedulerF.buildInputWire("inputF"); - - final TaskScheduler taskSchedulerG = - model.schedulerBuilder("G").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputG = taskSchedulerG.buildInputWire("inputG"); - - final TaskScheduler taskSchedulerH = - model.schedulerBuilder("H").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputH = taskSchedulerH.buildInputWire("inputH"); - - final TaskScheduler taskSchedulerI = - model.schedulerBuilder("I").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputI = taskSchedulerI.buildInputWire("inputI"); - - final TaskScheduler taskSchedulerJ = - model.schedulerBuilder("J").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputJ = taskSchedulerJ.buildInputWire("inputJ"); - - taskSchedulerA.getOutputWire().solderTo(inputB); - taskSchedulerB.getOutputWire().solderTo(inputC); - taskSchedulerC.getOutputWire().solderTo(inputD); - taskSchedulerD.getOutputWire().solderTo(inputE); - taskSchedulerE.getOutputWire().solderTo(inputF); - taskSchedulerF.getOutputWire().solderTo(inputG); - taskSchedulerG.getOutputWire().solderTo(inputD, SolderType.INJECT); - - taskSchedulerF.getOutputWire().solderTo(inputH); - taskSchedulerH.getOutputWire().solderTo(inputI); - taskSchedulerI.getOutputWire().solderTo(inputJ); - - taskSchedulerJ.getOutputWire().solderTo(inputA, SolderType.INJECT); - - taskSchedulerI.getOutputWire().solderTo(inputE, SolderType.INJECT); - - validateModel(model, false, false); - } - - @Test - void multiLoopBrokenByMissingBoundTest() { - final WiringModel model = WiringModelBuilder.create( - TestPlatformContextBuilder.create().build()) - .build(); - - /* - - A <---------------------------------| - | | - v | - B | - | | - v | - C | - | | - v | - D -----> E <---------------| | - ^ | | | - | v | | - G <----- F -----> H -----> I -----> J - - */ - - final TaskScheduler taskSchedulerA = - model.schedulerBuilder("A").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputA = taskSchedulerA.buildInputWire("inputA"); - - final TaskScheduler taskSchedulerB = - model.schedulerBuilder("B").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputB = taskSchedulerB.buildInputWire("inputB"); - - final TaskScheduler taskSchedulerC = - model.schedulerBuilder("C").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputC = taskSchedulerC.buildInputWire("inputC"); - - final TaskScheduler taskSchedulerD = - model.schedulerBuilder("D").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputD = taskSchedulerD.buildInputWire("inputD"); - - final TaskScheduler taskSchedulerE = model.schedulerBuilder("E") - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .build() - .cast(); - final InputWire inputE = taskSchedulerE.buildInputWire("inputE"); - - final TaskScheduler taskSchedulerF = - model.schedulerBuilder("F").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputF = taskSchedulerF.buildInputWire("inputF"); - - final TaskScheduler taskSchedulerG = - model.schedulerBuilder("G").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputG = taskSchedulerG.buildInputWire("inputG"); - - final TaskScheduler taskSchedulerH = - model.schedulerBuilder("H").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputH = taskSchedulerH.buildInputWire("inputH"); - - final TaskScheduler taskSchedulerI = - model.schedulerBuilder("I").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputI = taskSchedulerI.buildInputWire("inputI"); - - final TaskScheduler taskSchedulerJ = model.schedulerBuilder("J") - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .build() - .cast(); - final InputWire inputJ = taskSchedulerJ.buildInputWire("inputJ"); - - taskSchedulerA.getOutputWire().solderTo(inputB); - taskSchedulerB.getOutputWire().solderTo(inputC); - taskSchedulerC.getOutputWire().solderTo(inputD); - taskSchedulerD.getOutputWire().solderTo(inputE); - taskSchedulerE.getOutputWire().solderTo(inputF); - taskSchedulerF.getOutputWire().solderTo(inputG); - taskSchedulerG.getOutputWire().solderTo(inputD); - - taskSchedulerF.getOutputWire().solderTo(inputH); - taskSchedulerH.getOutputWire().solderTo(inputI); - taskSchedulerI.getOutputWire().solderTo(inputJ); - - taskSchedulerJ.getOutputWire().solderTo(inputA); - - taskSchedulerI.getOutputWire().solderTo(inputE); - - validateModel(model, false, false); - } - - @Test - void filterInCycleTest() { - final WiringModel model = WiringModelBuilder.create( - TestPlatformContextBuilder.create().build()) - .build(); - - /* - - A - | - v - B - | - v - C - | - v - D -----> E - ^ | - | v - G <----- F -----> H -----> I -----> J - - Connection D -> E uses a filter - - */ - - final TaskScheduler taskSchedulerA = - model.schedulerBuilder("A").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputA = taskSchedulerA.buildInputWire("inputA"); - - final TaskScheduler taskSchedulerB = - model.schedulerBuilder("B").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputB = taskSchedulerB.buildInputWire("inputB"); - - final TaskScheduler taskSchedulerC = - model.schedulerBuilder("C").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputC = taskSchedulerC.buildInputWire("inputC"); - - final TaskScheduler taskSchedulerD = - model.schedulerBuilder("D").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputD = taskSchedulerD.buildInputWire("inputD"); - - final TaskScheduler taskSchedulerE = - model.schedulerBuilder("E").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputE = taskSchedulerE.buildInputWire("inputE"); - - final TaskScheduler taskSchedulerF = - model.schedulerBuilder("F").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputF = taskSchedulerF.buildInputWire("inputF"); - - final TaskScheduler taskSchedulerG = - model.schedulerBuilder("G").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputG = taskSchedulerG.buildInputWire("inputG"); - - final TaskScheduler taskSchedulerH = - model.schedulerBuilder("H").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputH = taskSchedulerH.buildInputWire("inputH"); - - final TaskScheduler taskSchedulerI = - model.schedulerBuilder("I").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputI = taskSchedulerI.buildInputWire("inputI"); - - final TaskScheduler taskSchedulerJ = - model.schedulerBuilder("J").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputJ = taskSchedulerJ.buildInputWire(""); - - taskSchedulerA.getOutputWire().solderTo(inputB); - taskSchedulerB.getOutputWire().solderTo(inputC); - taskSchedulerC.getOutputWire().solderTo(inputD); - taskSchedulerD - .getOutputWire() - .buildFilter("onlyEven", "onlyEvenInput", x -> x % 2 == 0) - .solderTo(inputE); - taskSchedulerE.getOutputWire().solderTo(inputF); - taskSchedulerF.getOutputWire().solderTo(inputG); - taskSchedulerG.getOutputWire().solderTo(inputD); - - taskSchedulerF.getOutputWire().solderTo(inputH); - taskSchedulerH.getOutputWire().solderTo(inputI); - taskSchedulerI.getOutputWire().solderTo(inputJ); - - validateModel(model, true, false); - } - - @Test - void transformerInCycleTest() { - final WiringModel model = WiringModelBuilder.create( - TestPlatformContextBuilder.create().build()) - .build(); - - /* - - A - | - v - B - | - v - C - | - v - D -----> E - ^ | - | v - G <----- F -----> H -----> I -----> J - - Connection D -> E uses a transformer - - */ - - final TaskScheduler taskSchedulerA = - model.schedulerBuilder("A").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputA = taskSchedulerA.buildInputWire("inputA"); - - final TaskScheduler taskSchedulerB = - model.schedulerBuilder("B").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputB = taskSchedulerB.buildInputWire("inputB"); - - final TaskScheduler taskSchedulerC = - model.schedulerBuilder("C").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputC = taskSchedulerC.buildInputWire("inputC"); - - final TaskScheduler taskSchedulerD = - model.schedulerBuilder("D").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputD = taskSchedulerD.buildInputWire("inputD"); - - final TaskScheduler taskSchedulerE = - model.schedulerBuilder("E").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputE = taskSchedulerE.buildInputWire("inputE"); - - final TaskScheduler taskSchedulerF = - model.schedulerBuilder("F").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputF = taskSchedulerF.buildInputWire("inputF"); - - final TaskScheduler taskSchedulerG = - model.schedulerBuilder("G").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputG = taskSchedulerG.buildInputWire("inputG"); - - final TaskScheduler taskSchedulerH = - model.schedulerBuilder("H").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputH = taskSchedulerH.buildInputWire("inputH"); - - final TaskScheduler taskSchedulerI = - model.schedulerBuilder("I").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputI = taskSchedulerI.buildInputWire("inputI"); - - final TaskScheduler taskSchedulerJ = - model.schedulerBuilder("J").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputJ = taskSchedulerJ.buildInputWire(""); - - taskSchedulerA.getOutputWire().solderTo(inputB); - taskSchedulerB.getOutputWire().solderTo(inputC); - taskSchedulerC.getOutputWire().solderTo(inputD); - taskSchedulerD - .getOutputWire() - .buildTransformer("inverter", "inverterInput", x -> -x) - .solderTo(inputE); - taskSchedulerE.getOutputWire().solderTo(inputF); - taskSchedulerF.getOutputWire().solderTo(inputG); - taskSchedulerG.getOutputWire().solderTo(inputD); - - taskSchedulerF.getOutputWire().solderTo(inputH); - taskSchedulerH.getOutputWire().solderTo(inputI); - taskSchedulerI.getOutputWire().solderTo(inputJ); - - validateModel(model, true, false); - } - - @Test - void splitterInCycleTest() { - final WiringModel model = WiringModelBuilder.create( - TestPlatformContextBuilder.create().build()) - .build(); - - /* - - A - | - v - B - | - v - C - | - v - D -----> E - ^ | - | v - G <----- F -----> H -----> I -----> J - - Connection D -> E uses a splitter - - */ - - final TaskScheduler taskSchedulerA = - model.schedulerBuilder("A").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputA = taskSchedulerA.buildInputWire("inputA"); - - final TaskScheduler taskSchedulerB = - model.schedulerBuilder("B").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputB = taskSchedulerB.buildInputWire("inputB"); - - final TaskScheduler taskSchedulerC = - model.schedulerBuilder("C").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputC = taskSchedulerC.buildInputWire("inputC"); - - final TaskScheduler> taskSchedulerD = - model.schedulerBuilder("D").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputD = taskSchedulerD.buildInputWire("inputD"); - - final TaskScheduler taskSchedulerE = - model.schedulerBuilder("E").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputE = taskSchedulerE.buildInputWire("inputE"); - - final TaskScheduler taskSchedulerF = - model.schedulerBuilder("F").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputF = taskSchedulerF.buildInputWire("inputF"); - - final TaskScheduler taskSchedulerG = - model.schedulerBuilder("G").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputG = taskSchedulerG.buildInputWire("inputG"); - - final TaskScheduler taskSchedulerH = - model.schedulerBuilder("H").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputH = taskSchedulerH.buildInputWire("inputH"); - - final TaskScheduler taskSchedulerI = - model.schedulerBuilder("I").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputI = taskSchedulerI.buildInputWire("inputI"); - - final TaskScheduler taskSchedulerJ = - model.schedulerBuilder("J").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputJ = taskSchedulerJ.buildInputWire(""); - - taskSchedulerA.getOutputWire().solderTo(inputB); - taskSchedulerB.getOutputWire().solderTo(inputC); - taskSchedulerC.getOutputWire().solderTo(inputD); - final OutputWire splitter = taskSchedulerD.getOutputWire().buildSplitter("splitter", "splitterInput"); - splitter.solderTo(inputE); - taskSchedulerE.getOutputWire().solderTo(inputF); - taskSchedulerF.getOutputWire().solderTo(inputG); - taskSchedulerG.getOutputWire().solderTo(inputD); - - taskSchedulerF.getOutputWire().solderTo(inputH); - taskSchedulerH.getOutputWire().solderTo(inputI); - taskSchedulerI.getOutputWire().solderTo(inputJ); - - validateModel(model, true, false); - } - - @Test - void multipleOutputCycleTest() { - final WiringModel model = WiringModelBuilder.create( - TestPlatformContextBuilder.create().build()) - .build(); - - /* - - A <---------------------------------| - | | - v | - B | - | | - v | - C | - | | - v | - D -----> E <---------------| | - ^ | | | - | v | | - G <----- F -----> H -----> I -----> J - | ^ - | | - |--------| - - I has secondary output channels - - */ - - final TaskScheduler taskSchedulerA = - model.schedulerBuilder("A").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputA = taskSchedulerA.buildInputWire("inputA"); - - final TaskScheduler taskSchedulerB = - model.schedulerBuilder("B").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputB = taskSchedulerB.buildInputWire("inputB"); - - final TaskScheduler taskSchedulerC = - model.schedulerBuilder("C").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputC = taskSchedulerC.buildInputWire("inputC"); - - final TaskScheduler taskSchedulerD = - model.schedulerBuilder("D").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputD = taskSchedulerD.buildInputWire("inputD"); - - final TaskScheduler taskSchedulerE = - model.schedulerBuilder("E").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputE = taskSchedulerE.buildInputWire("inputE"); - - final TaskScheduler taskSchedulerF = - model.schedulerBuilder("F").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputF = taskSchedulerF.buildInputWire("inputF"); - - final TaskScheduler taskSchedulerG = - model.schedulerBuilder("G").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputG = taskSchedulerG.buildInputWire("inputG"); - - final TaskScheduler taskSchedulerH = - model.schedulerBuilder("H").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputH = taskSchedulerH.buildInputWire("inputH"); - - final TaskScheduler taskSchedulerI = - model.schedulerBuilder("I").withUnhandledTaskCapacity(1).build().cast(); - final OutputWire secondaryOutputI = taskSchedulerI.buildSecondaryOutputWire(); - final OutputWire tertiaryOutputI = taskSchedulerI.buildSecondaryOutputWire(); - final InputWire inputI = taskSchedulerI.buildInputWire("inputI"); - - final TaskScheduler taskSchedulerJ = - model.schedulerBuilder("J").withUnhandledTaskCapacity(1).build().cast(); - final InputWire inputJ = taskSchedulerJ.buildInputWire("inputJ"); - final InputWire inputJ2 = taskSchedulerJ.buildInputWire("inputJ2"); - - taskSchedulerA.getOutputWire().solderTo(inputB); - taskSchedulerB.getOutputWire().solderTo(inputC); - taskSchedulerC.getOutputWire().solderTo(inputD); - taskSchedulerD.getOutputWire().solderTo(inputE); - taskSchedulerE.getOutputWire().solderTo(inputF); - taskSchedulerF.getOutputWire().solderTo(inputG); - taskSchedulerG.getOutputWire().solderTo(inputD); - - taskSchedulerF.getOutputWire().solderTo(inputH); - taskSchedulerH.getOutputWire().solderTo(inputI); - taskSchedulerI.getOutputWire().solderTo(inputJ); - - taskSchedulerJ.getOutputWire().solderTo(inputA); - - secondaryOutputI.solderTo(inputE); - tertiaryOutputI.solderTo(inputJ2); - - validateModel(model, true, false); - } - - /** - * We should detect when a concurrent scheduler access a direct scheduler. - */ - @Test - void concurrentAccessingDirectTest() { - final WiringModel model = WiringModelBuilder.create( - TestPlatformContextBuilder.create().build()) - .build(); - - /* - - A - | - v - B - | - v - C - | - v - D -----> E - ^ | - | v - G <----- F -----> H -----> I -----> J - - D = CONCURRENT - E = DIRECT - - */ - - final TaskScheduler taskSchedulerA = model.schedulerBuilder("A") - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .build() - .cast(); - final InputWire inputA = taskSchedulerA.buildInputWire("inputA"); - - final TaskScheduler taskSchedulerB = model.schedulerBuilder("B") - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .build() - .cast(); - final InputWire inputB = taskSchedulerB.buildInputWire("inputB"); - - final TaskScheduler taskSchedulerC = model.schedulerBuilder("C") - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .build() - .cast(); - final InputWire inputC = taskSchedulerC.buildInputWire("inputC"); - - final TaskScheduler taskSchedulerD = model.schedulerBuilder("D") - .withType(TaskSchedulerType.CONCURRENT) - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .build() - .cast(); - final InputWire inputD = taskSchedulerD.buildInputWire("inputD"); - - final TaskScheduler taskSchedulerE = model.schedulerBuilder("E") - .withType(TaskSchedulerType.DIRECT) - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .build() - .cast(); - final InputWire inputE = taskSchedulerE.buildInputWire("inputE"); - - final TaskScheduler taskSchedulerF = model.schedulerBuilder("F") - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .build() - .cast(); - final InputWire inputF = taskSchedulerF.buildInputWire("inputF"); - - final TaskScheduler taskSchedulerG = model.schedulerBuilder("G") - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .build() - .cast(); - final InputWire inputG = taskSchedulerG.buildInputWire("inputG"); - - final TaskScheduler taskSchedulerH = model.schedulerBuilder("H") - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .build() - .cast(); - final InputWire inputH = taskSchedulerH.buildInputWire("inputH"); - - final TaskScheduler taskSchedulerI = model.schedulerBuilder("I") - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .build() - .cast(); - final InputWire inputI = taskSchedulerI.buildInputWire("inputI"); - - final TaskScheduler taskSchedulerJ = model.schedulerBuilder("J") - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .build() - .cast(); - final InputWire inputJ = taskSchedulerJ.buildInputWire("inputJ"); - - taskSchedulerA.getOutputWire().solderTo(inputB); - taskSchedulerB.getOutputWire().solderTo(inputC); - taskSchedulerC.getOutputWire().solderTo(inputD); - taskSchedulerD.getOutputWire().solderTo(inputE); - taskSchedulerE.getOutputWire().solderTo(inputF); - taskSchedulerF.getOutputWire().solderTo(inputG); - taskSchedulerG.getOutputWire().solderTo(inputD); - - taskSchedulerF.getOutputWire().solderTo(inputH); - taskSchedulerH.getOutputWire().solderTo(inputI); - taskSchedulerI.getOutputWire().solderTo(inputJ); - - validateModel(model, false, true); - } - - /** - * We should detect when a concurrent scheduler access a direct scheduler. - */ - @Test - void concurrentAccessingMultipleDirectTest() { - final WiringModel model = WiringModelBuilder.create( - TestPlatformContextBuilder.create().build()) - .build(); - - /* - - A - | - v - B - | - v - C - | - v - D -----> E - ^ | - | v - G <----- F -----> H -----> I -----> J - - D = CONCURRENT - E = DIRECT - F = DIRECT - - */ - - final TaskScheduler taskSchedulerA = model.schedulerBuilder("A") - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .build() - .cast(); - final InputWire inputA = taskSchedulerA.buildInputWire("inputA"); - - final TaskScheduler taskSchedulerB = model.schedulerBuilder("B") - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .build() - .cast(); - final InputWire inputB = taskSchedulerB.buildInputWire("inputB"); - - final TaskScheduler taskSchedulerC = model.schedulerBuilder("C") - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .build() - .cast(); - final InputWire inputC = taskSchedulerC.buildInputWire("inputC"); - - final TaskScheduler taskSchedulerD = model.schedulerBuilder("D") - .withType(TaskSchedulerType.CONCURRENT) - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .build() - .cast(); - final InputWire inputD = taskSchedulerD.buildInputWire("inputD"); - - final TaskScheduler taskSchedulerE = model.schedulerBuilder("E") - .withType(TaskSchedulerType.DIRECT) - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .build() - .cast(); - final InputWire inputE = taskSchedulerE.buildInputWire("inputE"); - - final TaskScheduler taskSchedulerF = model.schedulerBuilder("F") - .withType(TaskSchedulerType.DIRECT) - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .build() - .cast(); - final InputWire inputF = taskSchedulerF.buildInputWire("inputF"); - - final TaskScheduler taskSchedulerG = model.schedulerBuilder("G") - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .build() - .cast(); - final InputWire inputG = taskSchedulerG.buildInputWire("inputG"); - - final TaskScheduler taskSchedulerH = model.schedulerBuilder("H") - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .build() - .cast(); - final InputWire inputH = taskSchedulerH.buildInputWire("inputH"); - - final TaskScheduler taskSchedulerI = model.schedulerBuilder("I") - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .build() - .cast(); - final InputWire inputI = taskSchedulerI.buildInputWire("inputI"); - - final TaskScheduler taskSchedulerJ = model.schedulerBuilder("J") - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .build() - .cast(); - final InputWire inputJ = taskSchedulerJ.buildInputWire("inputJ"); - - taskSchedulerA.getOutputWire().solderTo(inputB); - taskSchedulerB.getOutputWire().solderTo(inputC); - taskSchedulerC.getOutputWire().solderTo(inputD); - taskSchedulerD.getOutputWire().solderTo(inputE); - taskSchedulerE.getOutputWire().solderTo(inputF); - taskSchedulerF.getOutputWire().solderTo(inputG); - taskSchedulerG.getOutputWire().solderTo(inputD); - - taskSchedulerF.getOutputWire().solderTo(inputH); - taskSchedulerH.getOutputWire().solderTo(inputI); - taskSchedulerI.getOutputWire().solderTo(inputJ); - - validateModel(model, false, true); - } - - /** - * We should detect when a concurrent scheduler access a direct scheduler through proxies (i.e. the concurrent - * scheduler calls into a DIRECT_THREADSAFE scheduler which calls into a DIRECT scheduler). - */ - @Test - void concurrentAccessingDirectThroughProxyTest() { - final WiringModel model = WiringModelBuilder.create( - TestPlatformContextBuilder.create().build()) - .build(); - - /* - - A - | - v - B - | - v - C - | - v - D -----> E - ^ | - | v - G <----- F -----> H -----> I -----> J - - D = CONCURRENT - E = DIRECT_THREADSAFE - F = DIRECT_THREADSAFE - G = DIRECT - - */ - - final TaskScheduler taskSchedulerA = model.schedulerBuilder("A") - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .build() - .cast(); - final InputWire inputA = taskSchedulerA.buildInputWire("inputA"); - - final TaskScheduler taskSchedulerB = model.schedulerBuilder("B") - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .build() - .cast(); - final InputWire inputB = taskSchedulerB.buildInputWire("inputB"); - - final TaskScheduler taskSchedulerC = - model.schedulerBuilder("C").build().cast(); - final InputWire inputC = taskSchedulerC.buildInputWire("inputC"); - - final TaskScheduler taskSchedulerD = model.schedulerBuilder("D") - .withType(TaskSchedulerType.CONCURRENT) - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .build() - .cast(); - final InputWire inputD = taskSchedulerD.buildInputWire("inputD"); - - final TaskScheduler taskSchedulerE = model.schedulerBuilder("E") - .withType(TaskSchedulerType.DIRECT_THREADSAFE) - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .build() - .cast(); - final InputWire inputE = taskSchedulerE.buildInputWire("inputE"); - - final TaskScheduler taskSchedulerF = model.schedulerBuilder("F") - .withType(TaskSchedulerType.DIRECT_THREADSAFE) - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .build() - .cast(); - final InputWire inputF = taskSchedulerF.buildInputWire("inputF"); - - final TaskScheduler taskSchedulerG = model.schedulerBuilder("G") - .withType(TaskSchedulerType.DIRECT) - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .build() - .cast(); - final InputWire inputG = taskSchedulerG.buildInputWire("inputG"); - - final TaskScheduler taskSchedulerH = model.schedulerBuilder("H") - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .build() - .cast(); - final InputWire inputH = taskSchedulerH.buildInputWire("inputH"); - - final TaskScheduler taskSchedulerI = model.schedulerBuilder("I") - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .build() - .cast(); - final InputWire inputI = taskSchedulerI.buildInputWire("inputI"); - - final TaskScheduler taskSchedulerJ = model.schedulerBuilder("J") - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .build() - .cast(); - final InputWire inputJ = taskSchedulerJ.buildInputWire("inputJ"); - - taskSchedulerA.getOutputWire().solderTo(inputB); - taskSchedulerB.getOutputWire().solderTo(inputC); - taskSchedulerC.getOutputWire().solderTo(inputD); - taskSchedulerD.getOutputWire().solderTo(inputE); - taskSchedulerE.getOutputWire().solderTo(inputF); - taskSchedulerF.getOutputWire().solderTo(inputG); - taskSchedulerG.getOutputWire().solderTo(inputD); - - taskSchedulerF.getOutputWire().solderTo(inputH); - taskSchedulerH.getOutputWire().solderTo(inputI); - taskSchedulerI.getOutputWire().solderTo(inputJ); - - validateModel(model, false, true); - } - - /** - * We should detect when multiple sequential schedulers call into a scheduler. - */ - @Test - void multipleSequentialSchedulerTest() { - final WiringModel model = WiringModelBuilder.create( - TestPlatformContextBuilder.create().build()) - .build(); - - /* - - A - | - v - B - | - v - C - | - v - D -----> E - ^ | - | v - G <----- F -----> H -----> I -----> J - - B = SEQUENTIAL_THREAD - C = DIRECT_THREADSAFE - D = DIRECT - - */ - - final TaskScheduler taskSchedulerA = - model.schedulerBuilder("A").build().cast(); - final InputWire inputA = taskSchedulerA.buildInputWire("inputA"); - - final TaskScheduler taskSchedulerB = model.schedulerBuilder("B") - .withType(TaskSchedulerType.SEQUENTIAL_THREAD) - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .build() - .cast(); - final InputWire inputB = taskSchedulerB.buildInputWire("inputB"); - - final TaskScheduler taskSchedulerC = model.schedulerBuilder("C") - .withType(TaskSchedulerType.DIRECT_THREADSAFE) - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .build() - .cast(); - final InputWire inputC = taskSchedulerC.buildInputWire("inputC"); - - final TaskScheduler taskSchedulerD = model.schedulerBuilder("D") - .withType(TaskSchedulerType.DIRECT) - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .build() - .cast(); - final InputWire inputD = taskSchedulerD.buildInputWire("inputD"); - - final TaskScheduler taskSchedulerE = model.schedulerBuilder("E") - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .build() - .cast(); - final InputWire inputE = taskSchedulerE.buildInputWire("inputE"); - - final TaskScheduler taskSchedulerF = model.schedulerBuilder("F") - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .build() - .cast(); - final InputWire inputF = taskSchedulerF.buildInputWire("inputF"); - - final TaskScheduler taskSchedulerG = model.schedulerBuilder("G") - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .build() - .cast(); - final InputWire inputG = taskSchedulerG.buildInputWire("inputG"); - - final TaskScheduler taskSchedulerH = model.schedulerBuilder("H") - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .build() - .cast(); - final InputWire inputH = taskSchedulerH.buildInputWire("inputH"); - - final TaskScheduler taskSchedulerI = model.schedulerBuilder("I") - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .build() - .cast(); - final InputWire inputI = taskSchedulerI.buildInputWire("inputI"); - - final TaskScheduler taskSchedulerJ = model.schedulerBuilder("J") - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .build() - .cast(); - final InputWire inputJ = taskSchedulerJ.buildInputWire("inputJ"); - - taskSchedulerA.getOutputWire().solderTo(inputB); - taskSchedulerB.getOutputWire().solderTo(inputC); - taskSchedulerC.getOutputWire().solderTo(inputD); - taskSchedulerD.getOutputWire().solderTo(inputE); - taskSchedulerE.getOutputWire().solderTo(inputF); - taskSchedulerF.getOutputWire().solderTo(inputG); - taskSchedulerG.getOutputWire().solderTo(inputD); - - taskSchedulerF.getOutputWire().solderTo(inputH); - taskSchedulerH.getOutputWire().solderTo(inputI); - taskSchedulerI.getOutputWire().solderTo(inputJ); - - validateModel(model, false, true); - } - - @Test - void unboundInputWireTest() { - final WiringModel model = WiringModelBuilder.create( - TestPlatformContextBuilder.create().build()) - .build(); - - final TaskScheduler taskSchedulerA = model.schedulerBuilder("A") - .withUnhandledTaskCapacity(UNLIMITED_CAPACITY) - .build() - .cast(); - final BindableInputWire inputA = taskSchedulerA.buildInputWire("inputA"); - - assertTrue(model.checkForUnboundInputWires()); - - inputA.bindConsumer(x -> {}); - - model.start(); - assertFalse(model.checkForUnboundInputWires()); - model.stop(); - } -} diff --git a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/model/internal/monitor/HealthMonitorTests.java b/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/model/internal/monitor/HealthMonitorTests.java deleted file mode 100644 index ed32ac498cb..00000000000 --- a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/model/internal/monitor/HealthMonitorTests.java +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Copyright (C) 2024 Hedera Hashgraph, LLC - * - * 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 com.swirlds.common.wiring.model.internal.monitor; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import com.swirlds.base.test.fixtures.time.FakeTime; -import com.swirlds.common.context.PlatformContext; -import com.swirlds.common.test.fixtures.Randotron; -import com.swirlds.common.test.fixtures.platform.TestPlatformContextBuilder; -import com.swirlds.common.utility.CompareTo; -import org.hiero.wiring.framework.model.internal.monitor.HealthMonitor; -import org.hiero.wiring.framework.schedulers.TaskScheduler; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.time.Duration; -import java.time.Instant; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.atomic.AtomicBoolean; -import org.junit.jupiter.api.Test; - -class HealthMonitorTests { - - /** - * Build a mock task scheduler. - * - * @param healthy when the value of this atomic boolean is true, the task scheduler is healthy; otherwise, it is - * unhealthy. - * @return a mock task scheduler - */ - @NonNull - private static TaskScheduler buildMockScheduler(final AtomicBoolean healthy) { - final TaskScheduler taskScheduler = mock(TaskScheduler.class); - when(taskScheduler.getCapacity()).thenReturn(10L); - when(taskScheduler.getUnprocessedTaskCount()).thenAnswer(invocation -> healthy.get() ? 5L : 15L); - return taskScheduler; - } - - @Test - void healthyBehaviorTest() { - final Randotron randotron = Randotron.create(); - - final int schedulerCount = randotron.nextInt(10, 20); - - final List> schedulers = new ArrayList<>(); - - for (int i = 0; i < schedulerCount; i++) { - final AtomicBoolean healthy = new AtomicBoolean(true); - final TaskScheduler scheduler = buildMockScheduler(healthy); - schedulers.add(scheduler); - } - - final Instant startTime = randotron.nextInstant(); - final FakeTime time = new FakeTime(startTime, Duration.ZERO); - final PlatformContext platformContext = - TestPlatformContextBuilder.create().withTime(time).build(); - - final HealthMonitor healthMonitor = - new HealthMonitor(platformContext, schedulers, Duration.ofSeconds(5), Duration.ofDays(10000)); - - final Instant endTime = startTime.plus(Duration.ofSeconds(10)); - while (time.now().isBefore(endTime)) { - assertNull(healthMonitor.checkSystemHealth(time.now())); - time.tick(Duration.ofMinutes(randotron.nextInt(1, 1000))); - assertEquals(Duration.ZERO, healthMonitor.getUnhealthyDuration()); - } - } - - @Test - void oneUnhealthySchedulerTest() { - final Randotron randotron = Randotron.create(); - - final int schedulerCount = randotron.nextInt(10, 20); - - final List> schedulers = new ArrayList<>(); - final List schedulerHealths = new ArrayList<>(); - - for (int i = 0; i < schedulerCount; i++) { - final AtomicBoolean healthy = new AtomicBoolean(true); - final TaskScheduler scheduler = buildMockScheduler(healthy); - schedulers.add(scheduler); - schedulerHealths.add(healthy); - } - - final Instant startTime = randotron.nextInstant(); - final FakeTime time = new FakeTime(startTime, Duration.ZERO); - final PlatformContext platformContext = - TestPlatformContextBuilder.create().withTime(time).build(); - - final HealthMonitor healthMonitor = - new HealthMonitor(platformContext, schedulers, Duration.ofSeconds(5), Duration.ofDays(10000)); - - final Instant phase1EndTime = startTime.plus(Duration.ofSeconds(10)); - while (time.now().isBefore(phase1EndTime)) { - assertNull(healthMonitor.checkSystemHealth(time.now())); - time.tick(Duration.ofMillis(randotron.nextInt(1, 1000))); - assertEquals(Duration.ZERO, healthMonitor.getUnhealthyDuration()); - } - - final Instant unhealthyStartTime = time.now(); - final int unhealthyIndex = randotron.nextInt(0, schedulerCount); - schedulerHealths.get(unhealthyIndex).set(false); - - final Instant phase2EndTime = time.now().plus(Duration.ofSeconds(10)); - while (time.now().isBefore(phase2EndTime)) { - final Duration unhealthyTime = Duration.between(unhealthyStartTime, time.now()); - - final Duration healthReport = healthMonitor.checkSystemHealth(time.now()); - if (CompareTo.isGreaterThan(unhealthyTime, Duration.ZERO)) { - assertEquals(unhealthyTime, healthReport); - } else { - assertNull(healthReport); - } - time.tick(Duration.ofMillis(randotron.nextInt(1, 1000))); - assertEquals(unhealthyTime, healthMonitor.getUnhealthyDuration()); - } - - // Make the scheduler healthy again. We should see a single report of 0s, followed by nulls. - schedulerHealths.get(unhealthyIndex).set(true); - assertEquals(Duration.ZERO, healthMonitor.checkSystemHealth(time.now())); - - final Instant phase3EndTime = time.now().plus(Duration.ofSeconds(10)); - while (time.now().isBefore(phase3EndTime)) { - assertNull(healthMonitor.checkSystemHealth(time.now())); - time.tick(Duration.ofMillis(randotron.nextInt(1, 1000))); - assertEquals(Duration.ZERO, healthMonitor.getUnhealthyDuration()); - } - } - - @Test - void multipleUnhealthySchedulersTest() { - final Randotron randotron = Randotron.create(); - - final int schedulerCount = randotron.nextInt(10, 20); - - final List> schedulers = new ArrayList<>(); - final List schedulerHealths = new ArrayList<>(); - - for (int i = 0; i < schedulerCount; i++) { - final AtomicBoolean healthy = new AtomicBoolean(true); - final TaskScheduler scheduler = buildMockScheduler(healthy); - schedulers.add(scheduler); - schedulerHealths.add(healthy); - } - - final Instant startTime = randotron.nextInstant(); - final FakeTime time = new FakeTime(startTime, Duration.ZERO); - final PlatformContext platformContext = - TestPlatformContextBuilder.create().withTime(time).build(); - - final HealthMonitor healthMonitor = - new HealthMonitor(platformContext, schedulers, Duration.ofSeconds(5), Duration.ofDays(10000)); - - final Instant phase1EndTime = startTime.plus(Duration.ofSeconds(10)); - while (time.now().isBefore(phase1EndTime)) { - assertNull(healthMonitor.checkSystemHealth(time.now())); - time.tick(Duration.ofMillis(randotron.nextInt(1, 1000))); - assertEquals(Duration.ZERO, healthMonitor.getUnhealthyDuration()); - } - - final Instant unhealthyStartTimeA = time.now(); - final int unhealthyIndexA = randotron.nextInt(0, schedulerCount); - schedulerHealths.get(unhealthyIndexA).set(false); - - final Instant phase2EndTime = time.now().plus(Duration.ofSeconds(10)); - while (time.now().isBefore(phase2EndTime)) { - final Duration unhealthyTime = Duration.between(unhealthyStartTimeA, time.now()); - - final Duration healthReport = healthMonitor.checkSystemHealth(time.now()); - if (CompareTo.isGreaterThan(unhealthyTime, Duration.ZERO)) { - assertEquals(unhealthyTime, healthReport); - } else { - assertNull(healthReport); - } - time.tick(Duration.ofMillis(randotron.nextInt(1, 1000))); - assertEquals(unhealthyTime, healthMonitor.getUnhealthyDuration()); - } - - // Make another scheduler unhealthy. It should be overshadowed by the first unhealthy scheduler. - final Instant unhealthyStartTimeB = time.now(); - final int unhealthyIndexB = (unhealthyIndexA + 1) % schedulerCount; - schedulerHealths.get(unhealthyIndexB).set(false); - - final Instant phase3EndTime = time.now().plus(Duration.ofSeconds(10)); - while (time.now().isBefore(phase3EndTime)) { - final Duration unhealthyTime = Duration.between(unhealthyStartTimeA, time.now()); - - final Duration healthReport = healthMonitor.checkSystemHealth(time.now()); - assertEquals(unhealthyTime, healthReport); - - time.tick(Duration.ofMillis(randotron.nextInt(1, 1000))); - assertEquals(unhealthyTime, healthMonitor.getUnhealthyDuration()); - } - - // Make the first scheduler healthy again. This will allow us to see the unhealthy time of the second scheduler. - schedulerHealths.get(unhealthyIndexA).set(true); - - final Instant phase4EndTime = time.now().plus(Duration.ofSeconds(10)); - while (time.now().isBefore(phase4EndTime)) { - final Duration unhealthyTime = Duration.between(unhealthyStartTimeB, time.now()); - - final Duration healthReport = healthMonitor.checkSystemHealth(time.now()); - assertEquals(unhealthyTime, healthReport); - - time.tick(Duration.ofMillis(randotron.nextInt(1, 1000))); - assertEquals(unhealthyTime, healthMonitor.getUnhealthyDuration()); - } - - // Make the second scheduler healthy again. System should return to normal. - schedulerHealths.get(unhealthyIndexB).set(true); - assertEquals(Duration.ZERO, healthMonitor.checkSystemHealth(time.now())); - - final Instant phase5EndTime = time.now().plus(Duration.ofSeconds(10)); - while (time.now().isBefore(phase5EndTime)) { - assertNull(healthMonitor.checkSystemHealth(time.now())); - time.tick(Duration.ofMillis(randotron.nextInt(1, 1000))); - assertEquals(Duration.ZERO, healthMonitor.getUnhealthyDuration()); - } - } -} diff --git a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/schedulers/NoOpTaskSchedulerTests.java b/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/schedulers/NoOpTaskSchedulerTests.java deleted file mode 100644 index f7ba74a6697..00000000000 --- a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/schedulers/NoOpTaskSchedulerTests.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (C) 2024 Hedera Hashgraph, LLC - * - * 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 com.swirlds.common.wiring.schedulers; - -import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.NO_OP; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import com.swirlds.common.context.PlatformContext; -import com.swirlds.common.test.fixtures.platform.TestPlatformContextBuilder; -import org.hiero.wiring.framework.model.WiringModel; -import org.hiero.wiring.framework.model.WiringModelBuilder; -import org.hiero.wiring.framework.schedulers.TaskScheduler; -import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; -import org.hiero.wiring.framework.wires.SolderType; -import org.hiero.wiring.framework.wires.input.BindableInputWire; -import org.hiero.wiring.framework.wires.output.OutputWire; -import java.util.List; -import java.util.concurrent.atomic.AtomicBoolean; -import org.junit.jupiter.api.Test; - -class NoOpTaskSchedulerTests { - - @Test - void nothingHappensTest() { - final PlatformContext platformContext = - TestPlatformContextBuilder.create().build(); - final WiringModel model = WiringModelBuilder.create(platformContext).build(); - - final TaskScheduler> realFakeScheduler = - model.schedulerBuilder("A").withType(NO_OP).build().cast(); - - final AtomicBoolean shouldAlwaysBeFalse = new AtomicBoolean(false); - - final BindableInputWire> inA = realFakeScheduler.buildInputWire("inA"); - inA.bindConsumer((value) -> shouldAlwaysBeFalse.set(true)); - - final BindableInputWire> inB = realFakeScheduler.buildInputWire("inB"); - inB.bind((value) -> { - shouldAlwaysBeFalse.set(true); - return List.of(1, 2, 3); - }); - - final OutputWire> transformer = realFakeScheduler - .getOutputWire() - .buildTransformer("transformer", "transformer input", (value) -> { - shouldAlwaysBeFalse.set(true); - return List.of(1, 2, 3); - }); - - final OutputWire> filter = realFakeScheduler - .getOutputWire() - .buildFilter("filter", "filter input", (value) -> { - shouldAlwaysBeFalse.set(true); - return true; - }); - - final OutputWire splitter = - realFakeScheduler.getOutputWire().buildSplitter("splitter", "splitter input"); - splitter.solderTo("handler", "handler input", value -> shouldAlwaysBeFalse.set(true)); - - // Solder the fake scheduler to a real one. No data should be passed. - final TaskScheduler realScheduler = model.schedulerBuilder("B") - .withType(TaskSchedulerType.DIRECT) - .build() - .cast(); - - final BindableInputWire, Void> realInA = realScheduler.buildInputWire("realInA"); - realInA.bindConsumer((value) -> shouldAlwaysBeFalse.set(true)); - realFakeScheduler.getOutputWire().solderTo(realInA, SolderType.PUT); - realFakeScheduler.getOutputWire().solderTo(realInA, SolderType.OFFER); - realFakeScheduler.getOutputWire().solderTo(realInA, SolderType.INJECT); - transformer.solderTo(realInA, SolderType.PUT); - transformer.solderTo(realInA, SolderType.OFFER); - transformer.solderTo(realInA, SolderType.INJECT); - filter.solderTo(realInA, SolderType.PUT); - filter.solderTo(realInA, SolderType.OFFER); - filter.solderTo(realInA, SolderType.INJECT); - - final BindableInputWire realInB = realScheduler.buildInputWire("realInB"); - realInB.bindConsumer((value) -> shouldAlwaysBeFalse.set(true)); - splitter.solderTo(realInB, SolderType.PUT); - splitter.solderTo(realInB, SolderType.OFFER); - splitter.solderTo(realInB, SolderType.INJECT); - - inA.put(1); - assertTrue(inA.offer(1)); - inA.inject(1); - - inB.put(1); - assertTrue(inB.offer(1)); - inB.inject(1); - - assertFalse(shouldAlwaysBeFalse.get()); - assertEquals(0, realFakeScheduler.getUnprocessedTaskCount()); - } -} diff --git a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/transformers/WireRouterTests.java b/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/transformers/WireRouterTests.java deleted file mode 100644 index 7851cae95cf..00000000000 --- a/platform-sdk/swirlds-common/src/test/java/com/swirlds/common/wiring/transformers/WireRouterTests.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (C) 2024 Hedera Hashgraph, LLC - * - * 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 com.swirlds.common.wiring.transformers; - -import static com.swirlds.common.test.fixtures.RandomUtils.getRandomPrintSeed; -import static org.junit.jupiter.api.Assertions.assertEquals; - -import com.swirlds.common.context.PlatformContext; -import com.swirlds.common.test.fixtures.platform.TestPlatformContextBuilder; -import org.hiero.wiring.framework.model.WiringModel; -import org.hiero.wiring.framework.model.WiringModelBuilder; -import org.hiero.wiring.framework.transformers.RoutableData; -import org.hiero.wiring.framework.transformers.WireRouter; -import org.hiero.wiring.framework.wires.output.OutputWire; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.Random; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicLong; -import org.junit.jupiter.api.Test; - -class WireRouterTests { - - private enum TestDataType { - FOO, // Long values - BAR, // Long values - BAZ; // Boolean values - - /** - * Create a new {@link RoutableData} object with the given data. - * - * @param data the data - * @return the new {@link RoutableData} object - */ - @NonNull - public RoutableData of(@NonNull final Object data) { - return new RoutableData<>(this, data); - } - } - - @Test - void basicBehaviorTest() { - final Random random = getRandomPrintSeed(); - - final PlatformContext platformContext = - TestPlatformContextBuilder.create().build(); - final WiringModel model = WiringModelBuilder.create(platformContext).build(); - - final WireRouter router = new WireRouter<>(model, "router", "router input", TestDataType.class); - - final AtomicLong latestFoo = new AtomicLong(); - final AtomicLong latestBar = new AtomicLong(); - final AtomicBoolean latestBaz = new AtomicBoolean(); - - final OutputWire fooOutput = router.getOutput(TestDataType.FOO); - final OutputWire barOutput = router.getOutput(TestDataType.BAR); - final OutputWire bazOutput = router.getOutput(TestDataType.BAZ); - - fooOutput.solderTo("fooHandler", "fooInput", latestFoo::set); - barOutput.solderTo("barHandler", "barInput", latestBar::set); - bazOutput.solderTo("bazHandler", "bazInput", latestBaz::set); - - long expectedFoo = 0; - long expectedBar = 0; - boolean expectedBaz = false; - - for (int i = 0; i < 1000; i++) { - final double choice = random.nextDouble(); - if (choice < 1.0 / 3.0) { - expectedFoo = random.nextLong(); - router.getInput().put(TestDataType.FOO.of(expectedFoo)); - } else if (choice < 2.0 / 3.0) { - expectedBar = random.nextLong(); - router.getInput().put(TestDataType.BAR.of(expectedBar)); - } else { - expectedBaz = random.nextBoolean(); - router.getInput().put(TestDataType.BAZ.of(expectedBaz)); - } - assertEquals(expectedFoo, latestFoo.get()); - assertEquals(expectedBar, latestBar.get()); - assertEquals(expectedBaz, latestBaz.get()); - } - } -} diff --git a/platform-sdk/swirlds-merkledb/src/main/java/com/swirlds/merkledb/files/hashmap/HalfDiskHashMap.java b/platform-sdk/swirlds-merkledb/src/main/java/com/swirlds/merkledb/files/hashmap/HalfDiskHashMap.java index 34b6713203d..20a6f2fbb9a 100644 --- a/platform-sdk/swirlds-merkledb/src/main/java/com/swirlds/merkledb/files/hashmap/HalfDiskHashMap.java +++ b/platform-sdk/swirlds-merkledb/src/main/java/com/swirlds/merkledb/files/hashmap/HalfDiskHashMap.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021-2024 Hedera Hashgraph, LLC + * Copyright (C) 2021-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,7 +22,6 @@ import com.hedera.pbj.runtime.io.buffer.BufferedData; import com.hedera.pbj.runtime.io.buffer.Bytes; -import org.hiero.wiring.framework.tasks.AbstractTask; import com.swirlds.config.api.Configuration; import com.swirlds.merkledb.FileStatisticAware; import com.swirlds.merkledb.Snapshotable; @@ -51,6 +50,7 @@ import org.apache.logging.log4j.Logger; import org.eclipse.collections.api.tuple.primitive.IntObjectPair; import org.eclipse.collections.impl.map.mutable.primitive.IntObjectHashMap; +import org.hiero.wiring.framework.tasks.AbstractTask; /** * This is a hash map implementation where the bucket index is in RAM and the buckets are on disk. diff --git a/platform-sdk/swirlds-merkledb/src/main/java/module-info.java b/platform-sdk/swirlds-merkledb/src/main/java/module-info.java index 6505d8e3445..869208f6e65 100644 --- a/platform-sdk/swirlds-merkledb/src/main/java/module-info.java +++ b/platform-sdk/swirlds-merkledb/src/main/java/module-info.java @@ -1,18 +1,17 @@ /* - * (c) 2016-2021 Swirlds, Inc. + * Copyright (C) 2016-2025 Hedera Hashgraph, LLC * - * This software is the confidential and proprietary information of - * Swirlds, Inc. ("Confidential Information"). You shall not - * disclose such Confidential Information and shall use it only in - * accordance with the terms of the license agreement you entered into - * with Swirlds. + * 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 * - * SWIRLDS MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF - * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED - * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SWIRLDS SHALL NOT BE LIABLE FOR - * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR - * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. + * 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. */ /** @@ -27,14 +26,15 @@ exports com.swirlds.merkledb.files.hashmap; exports com.swirlds.merkledb.utilities; + requires transitive com.hedera.pbj.runtime; requires transitive com.swirlds.common; requires transitive com.swirlds.config.api; requires transitive com.swirlds.metrics.api; requires transitive com.swirlds.virtualmap; - requires transitive com.hedera.pbj.runtime; requires com.swirlds.base; requires com.swirlds.config.extensions; requires com.swirlds.logging; + requires org.hiero.wiring.framework; requires java.management; requires jdk.management; requires jdk.unsupported; diff --git a/platform-sdk/swirlds-platform-core/build.gradle.kts b/platform-sdk/swirlds-platform-core/build.gradle.kts index 7a0d06d2ea9..7ee8f81d642 100644 --- a/platform-sdk/swirlds-platform-core/build.gradle.kts +++ b/platform-sdk/swirlds-platform-core/build.gradle.kts @@ -58,5 +58,6 @@ timingSensitiveModuleInfo { requires("com.swirlds.platform.core.test.fixtures") requires("org.assertj.core") requires("org.junit.jupiter.api") + requires("org.hiero.wiring.framework") requires("org.junit.jupiter.params") } diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/builder/PlatformBuilder.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/builder/PlatformBuilder.java index d5721284782..b568ab83404 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/builder/PlatformBuilder.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/builder/PlatformBuilder.java @@ -32,9 +32,6 @@ import com.swirlds.common.crypto.Signature; import com.swirlds.common.notification.NotificationEngine; import com.swirlds.common.platform.NodeId; -import org.hiero.wiring.framework.WiringConfig; -import org.hiero.wiring.framework.model.WiringModel; -import org.hiero.wiring.framework.model.WiringModelBuilder; import com.swirlds.config.api.Configuration; import com.swirlds.platform.SwirldsPlatform; import com.swirlds.platform.consensus.ConsensusSnapshot; @@ -73,6 +70,9 @@ import java.util.function.Consumer; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.hiero.wiring.framework.WiringConfig; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.model.WiringModelBuilder; /** * Builds a {@link SwirldsPlatform} instance. diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/builder/PlatformBuildingBlocks.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/builder/PlatformBuildingBlocks.java index b0f589df2aa..05af0813673 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/builder/PlatformBuildingBlocks.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/builder/PlatformBuildingBlocks.java @@ -21,7 +21,6 @@ import com.swirlds.common.context.PlatformContext; import com.swirlds.common.notification.NotificationEngine; import com.swirlds.common.platform.NodeId; -import org.hiero.wiring.framework.model.WiringModel; import com.swirlds.platform.consensus.ConsensusSnapshot; import com.swirlds.platform.crypto.KeysAndCerts; import com.swirlds.platform.event.PlatformEvent; @@ -46,6 +45,7 @@ import java.util.function.Function; import java.util.function.Predicate; import java.util.function.Supplier; +import org.hiero.wiring.framework.model.WiringModel; /** * This record contains core utilities and basic objects needed to build a platform. It should not contain any platform diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/cli/DiagramCommand.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/cli/DiagramCommand.java index 7ba860a8418..7e22c93d47f 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/cli/DiagramCommand.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/cli/DiagramCommand.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,11 +20,6 @@ import com.swirlds.cli.utility.AbstractCommand; import com.swirlds.cli.utility.SubcommandOf; import com.swirlds.common.context.PlatformContext; -import org.hiero.wiring.framework.model.WiringModel; -import org.hiero.wiring.framework.model.WiringModelBuilder; -import org.hiero.wiring.framework.model.diagram.ModelEdgeSubstitution; -import org.hiero.wiring.framework.model.diagram.ModelGroup; -import org.hiero.wiring.framework.model.diagram.ModelManualLink; import com.swirlds.config.api.Configuration; import com.swirlds.config.api.ConfigurationBuilder; import com.swirlds.platform.builder.ApplicationCallbacks; @@ -38,6 +33,11 @@ import java.util.ArrayList; import java.util.List; import java.util.Set; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.model.WiringModelBuilder; +import org.hiero.wiring.framework.model.diagram.ModelEdgeSubstitution; +import org.hiero.wiring.framework.model.diagram.ModelGroup; +import org.hiero.wiring.framework.model.diagram.ModelManualLink; import picocli.CommandLine; @CommandLine.Command( diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/cli/DiagramLegendCommand.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/cli/DiagramLegendCommand.java index 90fdd5caab9..b440f3ff0bc 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/cli/DiagramLegendCommand.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/cli/DiagramLegendCommand.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,14 +19,6 @@ import com.swirlds.cli.utility.AbstractCommand; import com.swirlds.cli.utility.SubcommandOf; import com.swirlds.common.context.PlatformContext; -import org.hiero.wiring.framework.model.WiringModel; -import org.hiero.wiring.framework.model.WiringModelBuilder; -import org.hiero.wiring.framework.model.diagram.ModelEdgeSubstitution; -import org.hiero.wiring.framework.model.diagram.ModelGroup; -import org.hiero.wiring.framework.model.diagram.ModelManualLink; -import org.hiero.wiring.framework.schedulers.TaskScheduler; -import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; -import org.hiero.wiring.framework.wires.SolderType; import com.swirlds.config.api.Configuration; import com.swirlds.config.api.ConfigurationBuilder; import com.swirlds.platform.config.DefaultConfiguration; @@ -35,6 +27,14 @@ import java.util.Base64; import java.util.List; import java.util.Set; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.model.WiringModelBuilder; +import org.hiero.wiring.framework.model.diagram.ModelEdgeSubstitution; +import org.hiero.wiring.framework.model.diagram.ModelGroup; +import org.hiero.wiring.framework.model.diagram.ModelManualLink; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.wires.SolderType; import picocli.CommandLine; @CommandLine.Command( diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/components/AppNotifier.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/components/AppNotifier.java index 0ad1eabda04..57efc528e94 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/components/AppNotifier.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/components/AppNotifier.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 Hedera Hashgraph, LLC + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +16,6 @@ package com.swirlds.platform.components; -import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.components.appcomm.CompleteStateNotificationWithCleanup; import com.swirlds.platform.listeners.ReconnectCompleteNotification; import com.swirlds.platform.listeners.StateWriteToDiskCompleteNotification; @@ -24,6 +23,7 @@ import com.swirlds.platform.system.state.notifications.StateHashedNotification; import com.swirlds.platform.system.status.PlatformStatus; import edu.umd.cs.findbugs.annotations.NonNull; +import org.hiero.wiring.framework.component.InputWireLabel; /** * A component that wraps around a notification engine, for sending notifications to the app. diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/components/EventWindowManager.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/components/EventWindowManager.java index 55a6acf5df7..1b6148f24f6 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/components/EventWindowManager.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/components/EventWindowManager.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 Hedera Hashgraph, LLC + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,10 +16,10 @@ package com.swirlds.platform.components; -import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.consensus.EventWindow; import com.swirlds.platform.internal.ConsensusRound; import edu.umd.cs.findbugs.annotations.NonNull; +import org.hiero.wiring.framework.component.InputWireLabel; /** * The gateway for disseminating {@link EventWindow} instances to the rest of the platform. diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/components/SavedStateController.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/components/SavedStateController.java index 657127f7bff..c613e48d87a 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/components/SavedStateController.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/components/SavedStateController.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 Hedera Hashgraph, LLC + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,11 +16,11 @@ package com.swirlds.platform.components; -import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.state.signed.ReservedSignedState; import com.swirlds.platform.state.signed.SignedState; import com.swirlds.platform.wiring.components.StateAndRound; import edu.umd.cs.findbugs.annotations.NonNull; +import org.hiero.wiring.framework.component.InputWireLabel; /** * Controls which signed states should be written to disk based on input from other components. diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/components/appcomm/LatestCompleteStateNotifier.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/components/appcomm/LatestCompleteStateNotifier.java index af435aa9d6d..b7d5f1a7505 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/components/appcomm/LatestCompleteStateNotifier.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/components/appcomm/LatestCompleteStateNotifier.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 Hedera Hashgraph, LLC + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,10 +16,10 @@ package com.swirlds.platform.components.appcomm; -import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.state.signed.ReservedSignedState; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; +import org.hiero.wiring.framework.component.InputWireLabel; /** * Responsible for notifying the app of the latest complete state. diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/components/consensus/ConsensusEngine.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/components/consensus/ConsensusEngine.java index b14df2f7b66..17980312f61 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/components/consensus/ConsensusEngine.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/components/consensus/ConsensusEngine.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 Hedera Hashgraph, LLC + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +16,6 @@ package com.swirlds.platform.components.consensus; -import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.Consensus; import com.swirlds.platform.consensus.ConsensusSnapshot; import com.swirlds.platform.event.PlatformEvent; @@ -25,6 +24,7 @@ import com.swirlds.platform.system.status.PlatformStatus; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.List; +import org.hiero.wiring.framework.component.InputWireLabel; /** * Responsible for adding events to {@link Consensus}. diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/config/PlatformConfigurationExtension.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/config/PlatformConfigurationExtension.java index bf3188b5fda..0c74a28c9d2 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/config/PlatformConfigurationExtension.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/config/PlatformConfigurationExtension.java @@ -27,8 +27,6 @@ import com.swirlds.common.metrics.platform.prometheus.PrometheusConfig; import com.swirlds.common.platform.NodeId; import com.swirlds.common.platform.NodeIdConverter; -import org.hiero.wiring.framework.WiringConfig; -import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerConfiguration; import com.swirlds.config.api.ConfigurationExtension; import com.swirlds.logging.api.internal.configuration.InternalLoggingConfig; import com.swirlds.merkledb.config.MerkleDbConfig; @@ -50,6 +48,8 @@ import edu.umd.cs.findbugs.annotations.NonNull; import java.util.Set; import org.hiero.event.creator.impl.EventCreationConfig; +import org.hiero.wiring.framework.WiringConfig; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerConfiguration; /** * Registers configuration types for the platform. diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/FutureEventBuffer.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/FutureEventBuffer.java index 84ee1f1f355..1edb3cdbe6f 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/FutureEventBuffer.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/FutureEventBuffer.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 Hedera Hashgraph, LLC + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,12 +16,12 @@ package com.swirlds.platform.event; -import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.consensus.EventWindow; import com.swirlds.platform.wiring.NoInput; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; import java.util.List; +import org.hiero.wiring.framework.component.InputWireLabel; /** * Buffers events from the future (i.e. events with a birth round that is greater than the round that consensus is diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/branching/BranchDetector.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/branching/BranchDetector.java index 542795a0218..0385a02c5de 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/branching/BranchDetector.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/branching/BranchDetector.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 Hedera Hashgraph, LLC + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,11 +16,11 @@ package com.swirlds.platform.event.branching; -import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.consensus.EventWindow; import com.swirlds.platform.event.PlatformEvent; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; +import org.hiero.wiring.framework.component.InputWireLabel; /** * Detects branching in the hashgraph. diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/branching/BranchReporter.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/branching/BranchReporter.java index dc53a6e14b8..5f9cba94c9c 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/branching/BranchReporter.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/branching/BranchReporter.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 Hedera Hashgraph, LLC + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,10 +16,10 @@ package com.swirlds.platform.event.branching; -import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.consensus.EventWindow; import com.swirlds.platform.event.PlatformEvent; import edu.umd.cs.findbugs.annotations.NonNull; +import org.hiero.wiring.framework.component.InputWireLabel; /** * This class is responsible for logging and producing metrics when a branch is observed. diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/creation/EventCreationManager.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/creation/EventCreationManager.java index a66de462ed2..86029eeaad9 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/creation/EventCreationManager.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/creation/EventCreationManager.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 Hedera Hashgraph, LLC + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +16,6 @@ package com.swirlds.platform.event.creation; -import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.consensus.EventWindow; import com.swirlds.platform.event.PlatformEvent; import com.swirlds.platform.system.events.UnsignedEvent; @@ -24,6 +23,7 @@ import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; import java.time.Duration; +import org.hiero.wiring.framework.component.InputWireLabel; /** * Wraps an {@link EventCreator} and provides additional functionality. Will sometimes decide not to create new events diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/deduplication/EventDeduplicator.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/deduplication/EventDeduplicator.java index 1be735bed5c..d57a15b0808 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/deduplication/EventDeduplicator.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/deduplication/EventDeduplicator.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,12 +16,12 @@ package com.swirlds.platform.event.deduplication; -import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.consensus.EventWindow; import com.swirlds.platform.event.PlatformEvent; import com.swirlds.platform.wiring.NoInput; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; +import org.hiero.wiring.framework.component.InputWireLabel; /** * Deduplicates events. diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/hashing/EventHasher.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/hashing/EventHasher.java index c3fec5f0867..1edc87c6595 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/hashing/EventHasher.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/hashing/EventHasher.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 Hedera Hashgraph, LLC + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,9 +16,9 @@ package com.swirlds.platform.event.hashing; -import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.event.PlatformEvent; import edu.umd.cs.findbugs.annotations.NonNull; +import org.hiero.wiring.framework.component.InputWireLabel; /** * Hashes events. diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/linking/InOrderLinker.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/linking/InOrderLinker.java index e669da3dcbf..1704b705873 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/linking/InOrderLinker.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/linking/InOrderLinker.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2024 Hedera Hashgraph, LLC + * Copyright (C) 2022-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,13 +16,13 @@ package com.swirlds.platform.event.linking; -import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.consensus.EventWindow; import com.swirlds.platform.event.PlatformEvent; import com.swirlds.platform.gossip.shadowgraph.Shadowgraph; import com.swirlds.platform.internal.EventImpl; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; +import org.hiero.wiring.framework.component.InputWireLabel; /** * Links events to their parents. Expects events to be provided in topological order. diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/orphan/OrphanBuffer.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/orphan/OrphanBuffer.java index 26da523e55e..21a7c8ba94c 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/orphan/OrphanBuffer.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/orphan/OrphanBuffer.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,11 +16,11 @@ package com.swirlds.platform.event.orphan; -import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.consensus.EventWindow; import com.swirlds.platform.event.PlatformEvent; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.List; +import org.hiero.wiring.framework.component.InputWireLabel; /** * Takes as input an unordered stream of {@link PlatformEvent}s and emits a stream diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/preconsensus/InlinePcesWriter.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/preconsensus/InlinePcesWriter.java index 44c5ea43d09..7853a75cc4f 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/preconsensus/InlinePcesWriter.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/preconsensus/InlinePcesWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016-2024 Hedera Hashgraph, LLC + * Copyright (C) 2016-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,10 +16,10 @@ package com.swirlds.platform.event.preconsensus; -import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.consensus.EventWindow; import com.swirlds.platform.event.PlatformEvent; import edu.umd.cs.findbugs.annotations.NonNull; +import org.hiero.wiring.framework.component.InputWireLabel; /** * This object is responsible for writing preconsensus events to disk. It differs from {@link PcesWriter} in that it diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/preconsensus/PcesReplayer.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/preconsensus/PcesReplayer.java index ceacef5b659..87d30823630 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/preconsensus/PcesReplayer.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/preconsensus/PcesReplayer.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,7 +26,6 @@ import com.swirlds.common.formatting.UnitFormatter; import com.swirlds.common.io.IOIterator; import com.swirlds.common.utility.throttle.RateLimiter; -import org.hiero.wiring.framework.wires.output.StandardOutputWire; import com.swirlds.platform.event.PlatformEvent; import com.swirlds.platform.state.signed.ReservedSignedState; import com.swirlds.platform.wiring.NoInput; @@ -40,6 +39,7 @@ import java.util.function.Supplier; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.hiero.wiring.framework.wires.output.StandardOutputWire; /** * This class encapsulates the logic for replaying preconsensus events at boot up time. diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/preconsensus/PcesSequencer.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/preconsensus/PcesSequencer.java index 08ba8c72266..71751829199 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/preconsensus/PcesSequencer.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/preconsensus/PcesSequencer.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 Hedera Hashgraph, LLC + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,9 +16,9 @@ package com.swirlds.platform.event.preconsensus; -import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.event.PlatformEvent; import edu.umd.cs.findbugs.annotations.NonNull; +import org.hiero.wiring.framework.component.InputWireLabel; /** * Responsible for assigning stream sequence numbers to events. All events that are written diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/preconsensus/PcesWriter.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/preconsensus/PcesWriter.java index 408deb8e6c7..539cad79760 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/preconsensus/PcesWriter.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/preconsensus/PcesWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016-2024 Hedera Hashgraph, LLC + * Copyright (C) 2016-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,11 +16,11 @@ package com.swirlds.platform.event.preconsensus; -import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.consensus.EventWindow; import com.swirlds.platform.event.PlatformEvent; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; +import org.hiero.wiring.framework.component.InputWireLabel; /** * This object is responsible for writing preconsensus events to disk. diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/preconsensus/durability/RoundDurabilityBuffer.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/preconsensus/durability/RoundDurabilityBuffer.java index 0f7a4b50073..6572879c4b9 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/preconsensus/durability/RoundDurabilityBuffer.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/preconsensus/durability/RoundDurabilityBuffer.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 Hedera Hashgraph, LLC + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,11 +16,11 @@ package com.swirlds.platform.event.preconsensus.durability; -import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.internal.ConsensusRound; import edu.umd.cs.findbugs.annotations.NonNull; import java.time.Instant; import java.util.List; +import org.hiero.wiring.framework.component.InputWireLabel; /** * This component performs a logical "join" operation between states ready to be handled and events that are known to be diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/resubmitter/TransactionResubmitter.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/resubmitter/TransactionResubmitter.java index d087471e40e..0c2fff9fd16 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/resubmitter/TransactionResubmitter.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/resubmitter/TransactionResubmitter.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 Hedera Hashgraph, LLC + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,11 +17,11 @@ package com.swirlds.platform.event.resubmitter; import com.hedera.hapi.platform.event.EventTransaction; -import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.consensus.EventWindow; import com.swirlds.platform.event.PlatformEvent; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.List; +import org.hiero.wiring.framework.component.InputWireLabel; /** * A simple utility responsible for resubmitting stale transactions. diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/signing/SelfEventSigner.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/signing/SelfEventSigner.java index 496367f66b5..3b81032729a 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/signing/SelfEventSigner.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/signing/SelfEventSigner.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 Hedera Hashgraph, LLC + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,10 +16,10 @@ package com.swirlds.platform.event.signing; -import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.event.PlatformEvent; import com.swirlds.platform.system.events.UnsignedEvent; import edu.umd.cs.findbugs.annotations.NonNull; +import org.hiero.wiring.framework.component.InputWireLabel; /** * Signs self events. diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/stale/DefaultStaleEventDetector.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/stale/DefaultStaleEventDetector.java index db8b201f419..7b16dd31b00 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/stale/DefaultStaleEventDetector.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/stale/DefaultStaleEventDetector.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 Hedera Hashgraph, LLC + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +20,6 @@ import com.swirlds.common.context.PlatformContext; import com.swirlds.common.platform.NodeId; -import org.hiero.wiring.framework.transformers.RoutableData; import com.swirlds.platform.consensus.EventWindow; import com.swirlds.platform.event.AncientMode; import com.swirlds.platform.event.PlatformEvent; @@ -33,6 +32,7 @@ import java.util.List; import java.util.Objects; import java.util.function.ToLongFunction; +import org.hiero.wiring.framework.transformers.RoutableData; /** * Detects when a self event becomes stale. Note that this detection may not observe a self event go stale if the node diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/stale/StaleEventDetector.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/stale/StaleEventDetector.java index c96e641c132..3589508b44a 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/stale/StaleEventDetector.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/stale/StaleEventDetector.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 Hedera Hashgraph, LLC + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,13 +16,13 @@ package com.swirlds.platform.event.stale; -import org.hiero.wiring.framework.component.InputWireLabel; -import org.hiero.wiring.framework.transformers.RoutableData; import com.swirlds.platform.consensus.EventWindow; import com.swirlds.platform.event.PlatformEvent; import com.swirlds.platform.internal.ConsensusRound; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.List; +import org.hiero.wiring.framework.component.InputWireLabel; +import org.hiero.wiring.framework.transformers.RoutableData; /** * Detects when a self event becomes stale. This utility does not pay attention to events created by other nodes. This diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/stream/ConsensusEventStream.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/stream/ConsensusEventStream.java index 9dd17ea04ac..6656f62f64d 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/stream/ConsensusEventStream.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/stream/ConsensusEventStream.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 Hedera Hashgraph, LLC + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,10 +17,10 @@ package com.swirlds.platform.event.stream; import com.swirlds.common.stream.RunningEventHashOverride; -import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.system.events.CesEvent; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.List; +import org.hiero.wiring.framework.component.InputWireLabel; /** * Generates event stream files when enableEventStreaming is true, and calculates runningHash for consensus Events. diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/validation/EventSignatureValidator.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/validation/EventSignatureValidator.java index 0bc83d5aac3..178ec6c2154 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/validation/EventSignatureValidator.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/validation/EventSignatureValidator.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 Hedera Hashgraph, LLC + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,11 +16,11 @@ package com.swirlds.platform.event.validation; -import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.consensus.EventWindow; import com.swirlds.platform.event.PlatformEvent; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; +import org.hiero.wiring.framework.component.InputWireLabel; /** * Verifies event signatures diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/validation/InternalEventValidator.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/validation/InternalEventValidator.java index e675ca03992..076534cd83b 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/validation/InternalEventValidator.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/validation/InternalEventValidator.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 Hedera Hashgraph, LLC + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,10 +16,10 @@ package com.swirlds.platform.event.validation; -import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.event.PlatformEvent; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; +import org.hiero.wiring.framework.component.InputWireLabel; /** * Validates that events are internally complete and consistent. diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/eventhandling/DefaultTransactionHandler.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/eventhandling/DefaultTransactionHandler.java index 80f4759131c..e61197f6c9a 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/eventhandling/DefaultTransactionHandler.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/eventhandling/DefaultTransactionHandler.java @@ -31,7 +31,6 @@ import com.swirlds.common.context.PlatformContext; import com.swirlds.common.crypto.Hash; import com.swirlds.common.stream.RunningEventHashOverride; -import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; import com.swirlds.platform.components.transaction.system.ScopedSystemTransaction; import com.swirlds.platform.consensus.ConsensusConfig; import com.swirlds.platform.crypto.CryptoStatic; @@ -54,6 +53,7 @@ import java.util.Objects; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; /** * A standard implementation of {@link TransactionHandler}. diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/eventhandling/TransactionHandler.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/eventhandling/TransactionHandler.java index 89dcd1835df..49930c5f9b1 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/eventhandling/TransactionHandler.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/eventhandling/TransactionHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016-2024 Hedera Hashgraph, LLC + * Copyright (C) 2016-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,11 +17,11 @@ package com.swirlds.platform.eventhandling; import com.swirlds.common.stream.RunningEventHashOverride; -import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.internal.ConsensusRound; import com.swirlds.platform.wiring.components.StateAndRound; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; +import org.hiero.wiring.framework.component.InputWireLabel; /** * Applies transactions from rounds that have reached consensus to the state diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/eventhandling/TransactionPrehandler.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/eventhandling/TransactionPrehandler.java index 0b9c21246db..180a84f5e2c 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/eventhandling/TransactionPrehandler.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/eventhandling/TransactionPrehandler.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 Hedera Hashgraph, LLC + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,11 +17,11 @@ package com.swirlds.platform.eventhandling; import com.hedera.hapi.platform.event.StateSignatureTransaction; -import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.components.transaction.system.ScopedSystemTransaction; import com.swirlds.platform.event.PlatformEvent; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.List; +import org.hiero.wiring.framework.component.InputWireLabel; /** * Performs the prehandling of transactions diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/gossip/SyncGossip.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/gossip/SyncGossip.java index 093dbd77e77..89b48ae2ea8 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/gossip/SyncGossip.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/gossip/SyncGossip.java @@ -30,9 +30,6 @@ import com.swirlds.common.threading.manager.ThreadManager; import com.swirlds.common.threading.pool.CachedPoolParallelExecutor; import com.swirlds.common.threading.pool.ParallelExecutor; -import org.hiero.wiring.framework.model.WiringModel; -import org.hiero.wiring.framework.wires.input.BindableInputWire; -import org.hiero.wiring.framework.wires.output.StandardOutputWire; import com.swirlds.platform.Utilities; import com.swirlds.platform.config.BasicConfig; import com.swirlds.platform.config.StateConfig; @@ -98,6 +95,9 @@ import java.util.function.Supplier; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.wires.input.BindableInputWire; +import org.hiero.wiring.framework.wires.output.StandardOutputWire; /** * Boilerplate code for gossip. diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/pool/TransactionPool.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/pool/TransactionPool.java index 824b14b2650..ef616e316d1 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/pool/TransactionPool.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/pool/TransactionPool.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 Hedera Hashgraph, LLC + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,10 +17,10 @@ package com.swirlds.platform.pool; import com.hedera.hapi.platform.event.StateSignatureTransaction; -import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.system.status.PlatformStatus; import edu.umd.cs.findbugs.annotations.NonNull; import java.time.Duration; +import org.hiero.wiring.framework.component.InputWireLabel; /** * Coordinates and manages a pool of transactions waiting to be submitted. diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/publisher/PlatformPublisher.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/publisher/PlatformPublisher.java index 8284bc4bced..72c89529e51 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/publisher/PlatformPublisher.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/publisher/PlatformPublisher.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 Hedera Hashgraph, LLC + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,10 +16,10 @@ package com.swirlds.platform.publisher; -import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.consensus.ConsensusSnapshot; import com.swirlds.platform.event.PlatformEvent; import edu.umd.cs.findbugs.annotations.NonNull; +import org.hiero.wiring.framework.component.InputWireLabel; /** * This component is responsible for publishing internal platform data to external subscribers. By default this is not diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/state/hasher/StateHasher.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/state/hasher/StateHasher.java index eebb4db9d6d..88c7abfeae9 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/state/hasher/StateHasher.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/state/hasher/StateHasher.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 Hedera Hashgraph, LLC + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,10 +16,10 @@ package com.swirlds.platform.state.hasher; -import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.wiring.components.StateAndRound; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; +import org.hiero.wiring.framework.component.InputWireLabel; /** * Hashes signed states diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/state/hashlogger/HashLogger.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/state/hashlogger/HashLogger.java index 9cfedff68c2..eaf49451ee6 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/state/hashlogger/HashLogger.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/state/hashlogger/HashLogger.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2024 Hedera Hashgraph, LLC + * Copyright (C) 2022-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,9 +16,9 @@ package com.swirlds.platform.state.hashlogger; -import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.state.signed.ReservedSignedState; import edu.umd.cs.findbugs.annotations.NonNull; +import org.hiero.wiring.framework.component.InputWireLabel; /** * This component is responsible for logging the hash of the state each round (for debugging). diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/state/nexus/LatestCompleteStateNexus.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/state/nexus/LatestCompleteStateNexus.java index 14d32f1855b..f6f538e5b6a 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/state/nexus/LatestCompleteStateNexus.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/state/nexus/LatestCompleteStateNexus.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 Hedera Hashgraph, LLC + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,10 +16,10 @@ package com.swirlds.platform.state.nexus; -import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.consensus.EventWindow; import com.swirlds.platform.state.signed.ReservedSignedState; import edu.umd.cs.findbugs.annotations.NonNull; +import org.hiero.wiring.framework.component.InputWireLabel; /** * A nexus that holds the latest complete signed state. diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/state/nexus/SignedStateNexus.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/state/nexus/SignedStateNexus.java index ba6b49d94b5..67f1c990863 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/state/nexus/SignedStateNexus.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/state/nexus/SignedStateNexus.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 Hedera Hashgraph, LLC + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,11 +17,11 @@ package com.swirlds.platform.state.nexus; import com.swirlds.common.utility.Clearable; -import org.hiero.wiring.framework.component.SchedulerLabel; import com.swirlds.platform.consensus.ConsensusConstants; import com.swirlds.platform.state.signed.ReservedSignedState; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; +import org.hiero.wiring.framework.component.SchedulerLabel; /** * A thread-safe container that also manages reservations for a single signed state. diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/state/signed/StateSignatureCollector.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/state/signed/StateSignatureCollector.java index 02b4f103f9f..c06dc3f6220 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/state/signed/StateSignatureCollector.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/state/signed/StateSignatureCollector.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 Hedera Hashgraph, LLC + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,11 +17,11 @@ package com.swirlds.platform.state.signed; import com.hedera.hapi.platform.event.StateSignatureTransaction; -import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.components.transaction.system.ScopedSystemTransaction; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; import java.util.List; +import org.hiero.wiring.framework.component.InputWireLabel; /** * Collects signatures for signed states. This class ensures that all the non-ancient states that are not fully signed diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/system/events/BirthRoundMigrationShim.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/system/events/BirthRoundMigrationShim.java index 57ea972546a..3517529c0c2 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/system/events/BirthRoundMigrationShim.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/system/events/BirthRoundMigrationShim.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 Hedera Hashgraph, LLC + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,9 +16,9 @@ package com.swirlds.platform.system.events; -import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.event.PlatformEvent; import edu.umd.cs.findbugs.annotations.NonNull; +import org.hiero.wiring.framework.component.InputWireLabel; /** * Performs special migration on events during the birth round migration pathway. diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/system/status/StatusStateMachine.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/system/status/StatusStateMachine.java index 04e8f4a442d..77c6c96c1dc 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/system/status/StatusStateMachine.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/system/status/StatusStateMachine.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,11 +16,11 @@ package com.swirlds.platform.system.status; -import org.hiero.wiring.framework.component.InputWireLabel; import com.swirlds.platform.system.status.actions.PlatformStatusAction; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; import java.time.Instant; +import org.hiero.wiring.framework.component.InputWireLabel; /** * A state machine that processes {@link PlatformStatusAction}s diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/PlatformCoordinator.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/PlatformCoordinator.java index a733cbe6ca8..4b52241faf3 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/PlatformCoordinator.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/PlatformCoordinator.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,8 +17,6 @@ package com.swirlds.platform.wiring; import com.hedera.hapi.platform.event.StateSignatureTransaction; -import org.hiero.wiring.framework.component.ComponentWiring; -import org.hiero.wiring.framework.transformers.RoutableData; import com.swirlds.platform.components.consensus.ConsensusEngine; import com.swirlds.platform.components.transaction.system.ScopedSystemTransaction; import com.swirlds.platform.event.PlatformEvent; @@ -49,6 +47,8 @@ import edu.umd.cs.findbugs.annotations.Nullable; import java.util.List; import java.util.Objects; +import org.hiero.wiring.framework.component.ComponentWiring; +import org.hiero.wiring.framework.transformers.RoutableData; /** * Responsible for coordinating the clearing of the platform wiring objects. diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/PlatformSchedulersConfig.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/PlatformSchedulersConfig.java index e673886fc6f..a715ecaebcf 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/PlatformSchedulersConfig.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/PlatformSchedulersConfig.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,10 +16,10 @@ package com.swirlds.platform.wiring; -import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerConfiguration; import com.swirlds.config.api.ConfigData; import com.swirlds.config.api.ConfigProperty; import java.time.Duration; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerConfiguration; /** * Contains configuration values for the platform schedulers. diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/PlatformWiring.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/PlatformWiring.java index f302606e18b..16944206828 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/PlatformWiring.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/PlatformWiring.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 Hedera Hashgraph, LLC + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,26 +16,17 @@ package com.swirlds.platform.wiring; +import static com.swirlds.platform.event.stale.StaleEventDetectorOutput.SELF_EVENT; +import static com.swirlds.platform.event.stale.StaleEventDetectorOutput.STALE_SELF_EVENT; import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerConfiguration.DIRECT_THREADSAFE_CONFIGURATION; import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerConfiguration.NO_OP_CONFIGURATION; import static org.hiero.wiring.framework.wires.SolderType.INJECT; import static org.hiero.wiring.framework.wires.SolderType.OFFER; -import static com.swirlds.platform.event.stale.StaleEventDetectorOutput.SELF_EVENT; -import static com.swirlds.platform.event.stale.StaleEventDetectorOutput.STALE_SELF_EVENT; import com.hedera.hapi.platform.event.StateSignatureTransaction; import com.swirlds.common.context.PlatformContext; import com.swirlds.common.io.IOIterator; import com.swirlds.common.stream.RunningEventHashOverride; -import org.hiero.wiring.framework.component.ComponentWiring; -import org.hiero.wiring.framework.model.WiringModel; -import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerConfiguration; -import org.hiero.wiring.framework.transformers.RoutableData; -import org.hiero.wiring.framework.transformers.WireFilter; -import org.hiero.wiring.framework.transformers.WireTransformer; -import org.hiero.wiring.framework.wires.input.InputWire; -import org.hiero.wiring.framework.wires.output.OutputWire; -import org.hiero.wiring.framework.wires.output.StandardOutputWire; import com.swirlds.platform.builder.ApplicationCallbacks; import com.swirlds.platform.builder.PlatformComponentBuilder; import com.swirlds.platform.components.AppNotifier; @@ -108,6 +99,15 @@ import java.util.List; import java.util.Objects; import org.hiero.event.creator.impl.EventCreationConfig; +import org.hiero.wiring.framework.component.ComponentWiring; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerConfiguration; +import org.hiero.wiring.framework.transformers.RoutableData; +import org.hiero.wiring.framework.transformers.WireFilter; +import org.hiero.wiring.framework.transformers.WireTransformer; +import org.hiero.wiring.framework.wires.input.InputWire; +import org.hiero.wiring.framework.wires.output.OutputWire; +import org.hiero.wiring.framework.wires.output.StandardOutputWire; /** * Encapsulates wiring for {@link com.swirlds.platform.SwirldsPlatform}. diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/SignedStateReserver.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/SignedStateReserver.java index 612c71408c6..1f67b127247 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/SignedStateReserver.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/SignedStateReserver.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,9 +16,9 @@ package com.swirlds.platform.wiring; -import org.hiero.wiring.framework.transformers.AdvancedTransformation; import com.swirlds.platform.state.signed.ReservedSignedState; import edu.umd.cs.findbugs.annotations.NonNull; +import org.hiero.wiring.framework.transformers.AdvancedTransformation; /** * Manages reservations of a signed state when it needs to be passed to one or more input wires. diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/StateAndRoundReserver.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/StateAndRoundReserver.java index fff1c5368eb..411d39a74a5 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/StateAndRoundReserver.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/StateAndRoundReserver.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,9 +16,9 @@ package com.swirlds.platform.wiring; -import org.hiero.wiring.framework.transformers.AdvancedTransformation; import com.swirlds.platform.wiring.components.StateAndRound; import edu.umd.cs.findbugs.annotations.NonNull; +import org.hiero.wiring.framework.transformers.AdvancedTransformation; /** * Manages reservations of a signed state contained in a {@link StateAndRound} object, when it needs to be passed to one diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/StateAndRoundToStateReserver.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/StateAndRoundToStateReserver.java index a188a1f2e59..c6ab8c5539e 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/StateAndRoundToStateReserver.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/StateAndRoundToStateReserver.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,10 +16,10 @@ package com.swirlds.platform.wiring; -import org.hiero.wiring.framework.transformers.AdvancedTransformation; import com.swirlds.platform.state.signed.ReservedSignedState; import com.swirlds.platform.wiring.components.StateAndRound; import edu.umd.cs.findbugs.annotations.NonNull; +import org.hiero.wiring.framework.transformers.AdvancedTransformation; /** * Manages reservations of a signed state contained in a {@link StateAndRound} object, when the StateAndRound needs to diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/components/Gossip.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/components/Gossip.java index 961615fa96a..42fd6ece775 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/components/Gossip.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/components/Gossip.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 Hedera Hashgraph, LLC + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,15 +16,15 @@ package com.swirlds.platform.wiring.components; -import org.hiero.wiring.framework.model.WiringModel; -import org.hiero.wiring.framework.wires.input.BindableInputWire; -import org.hiero.wiring.framework.wires.output.StandardOutputWire; import com.swirlds.platform.consensus.EventWindow; import com.swirlds.platform.event.PlatformEvent; import com.swirlds.platform.system.status.PlatformStatus; import com.swirlds.platform.wiring.NoInput; import edu.umd.cs.findbugs.annotations.NonNull; import java.time.Duration; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.wires.input.BindableInputWire; +import org.hiero.wiring.framework.wires.output.StandardOutputWire; /** * Implements gossip with network peers. diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/components/GossipWiring.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/components/GossipWiring.java index 17f6e88a27c..e5c9cd5a24a 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/components/GossipWiring.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/components/GossipWiring.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 Hedera Hashgraph, LLC + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,12 +17,6 @@ package com.swirlds.platform.wiring.components; import com.swirlds.common.context.PlatformContext; -import org.hiero.wiring.framework.model.WiringModel; -import org.hiero.wiring.framework.schedulers.TaskScheduler; -import org.hiero.wiring.framework.wires.input.BindableInputWire; -import org.hiero.wiring.framework.wires.input.InputWire; -import org.hiero.wiring.framework.wires.output.OutputWire; -import org.hiero.wiring.framework.wires.output.StandardOutputWire; import com.swirlds.platform.consensus.EventWindow; import com.swirlds.platform.event.PlatformEvent; import com.swirlds.platform.system.status.PlatformStatus; @@ -30,6 +24,12 @@ import com.swirlds.platform.wiring.PlatformSchedulersConfig; import edu.umd.cs.findbugs.annotations.NonNull; import java.time.Duration; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.wires.input.BindableInputWire; +import org.hiero.wiring.framework.wires.input.InputWire; +import org.hiero.wiring.framework.wires.output.OutputWire; +import org.hiero.wiring.framework.wires.output.StandardOutputWire; /** * Wiring for gossip. diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/components/PassThroughWiring.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/components/PassThroughWiring.java index 31339f99a0a..828c139b21b 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/components/PassThroughWiring.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/components/PassThroughWiring.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 Hedera Hashgraph, LLC + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,15 +16,15 @@ package com.swirlds.platform.wiring.components; +import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Objects; +import java.util.function.Function; import org.hiero.wiring.framework.model.WiringModel; import org.hiero.wiring.framework.schedulers.TaskScheduler; import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; import org.hiero.wiring.framework.wires.input.BindableInputWire; import org.hiero.wiring.framework.wires.input.InputWire; import org.hiero.wiring.framework.wires.output.OutputWire; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.Objects; -import java.util.function.Function; /** * PassThrough Component Wiring, useful for wiring no-op components with the given scheduler type. diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/components/PcesReplayerWiring.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/components/PcesReplayerWiring.java index 9c152eae1f3..c30d4558079 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/components/PcesReplayerWiring.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/components/PcesReplayerWiring.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,16 +20,16 @@ import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.DIRECT; import com.swirlds.common.io.IOIterator; +import com.swirlds.platform.event.PlatformEvent; +import com.swirlds.platform.event.preconsensus.PcesReplayer; +import com.swirlds.platform.wiring.NoInput; +import edu.umd.cs.findbugs.annotations.NonNull; import org.hiero.wiring.framework.model.WiringModel; import org.hiero.wiring.framework.schedulers.TaskScheduler; import org.hiero.wiring.framework.wires.input.BindableInputWire; import org.hiero.wiring.framework.wires.input.InputWire; import org.hiero.wiring.framework.wires.output.OutputWire; import org.hiero.wiring.framework.wires.output.StandardOutputWire; -import com.swirlds.platform.event.PlatformEvent; -import com.swirlds.platform.event.preconsensus.PcesReplayer; -import com.swirlds.platform.wiring.NoInput; -import edu.umd.cs.findbugs.annotations.NonNull; /** * The wiring for the {@link PcesReplayer}. diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/components/RunningEventHashOverrideWiring.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/components/RunningEventHashOverrideWiring.java index c38e94f1cbe..7dc18ca1e22 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/components/RunningEventHashOverrideWiring.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/wiring/components/RunningEventHashOverrideWiring.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 Hedera Hashgraph, LLC + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,12 +20,12 @@ import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType.DIRECT_THREADSAFE; import com.swirlds.common.stream.RunningEventHashOverride; +import edu.umd.cs.findbugs.annotations.NonNull; import org.hiero.wiring.framework.model.WiringModel; import org.hiero.wiring.framework.schedulers.TaskScheduler; import org.hiero.wiring.framework.wires.input.BindableInputWire; import org.hiero.wiring.framework.wires.input.InputWire; import org.hiero.wiring.framework.wires.output.OutputWire; -import edu.umd.cs.findbugs.annotations.NonNull; /** * A wiring object for distributing {@link RunningEventHashOverride}s diff --git a/platform-sdk/swirlds-platform-core/src/main/java/module-info.java b/platform-sdk/swirlds-platform-core/src/main/java/module-info.java index b1e6a8cb2b0..920f131e8c2 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/module-info.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/module-info.java @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2025 Hedera Hashgraph, LLC + * + * 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. + */ + /** * The Swirlds public API module used by platform applications. */ @@ -146,6 +162,7 @@ requires com.swirlds.merkledb; requires com.swirlds.virtualmap; requires org.hiero.event.creator.impl; + requires org.hiero.wiring.framework; requires com.fasterxml.jackson.core; requires com.fasterxml.jackson.dataformat.yaml; requires com.github.spotbugs.annotations; diff --git a/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/components/EventWindowManagerTests.java b/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/components/EventWindowManagerTests.java index 4ac130166ed..a2ee2b6b310 100644 --- a/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/components/EventWindowManagerTests.java +++ b/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/components/EventWindowManagerTests.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 Hedera Hashgraph, LLC + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,13 +22,13 @@ import static org.mockito.Mockito.when; import com.swirlds.common.test.fixtures.platform.TestPlatformContextBuilder; +import com.swirlds.platform.consensus.EventWindow; +import com.swirlds.platform.internal.ConsensusRound; +import java.util.concurrent.atomic.AtomicReference; import org.hiero.wiring.framework.component.ComponentWiring; import org.hiero.wiring.framework.model.WiringModel; import org.hiero.wiring.framework.model.WiringModelBuilder; import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; -import com.swirlds.platform.consensus.EventWindow; -import com.swirlds.platform.internal.ConsensusRound; -import java.util.concurrent.atomic.AtomicReference; import org.junit.jupiter.api.Test; public class EventWindowManagerTests { diff --git a/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/event/stale/StaleEventDetectorTests.java b/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/event/stale/StaleEventDetectorTests.java index 73a4bd828a6..d190d206443 100644 --- a/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/event/stale/StaleEventDetectorTests.java +++ b/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/event/stale/StaleEventDetectorTests.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 Hedera Hashgraph, LLC + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,7 +27,6 @@ import com.swirlds.common.platform.NodeId; import com.swirlds.common.test.fixtures.Randotron; import com.swirlds.common.test.fixtures.platform.TestPlatformContextBuilder; -import org.hiero.wiring.framework.transformers.RoutableData; import com.swirlds.config.api.Configuration; import com.swirlds.config.extensions.test.fixtures.TestConfigBuilder; import com.swirlds.platform.consensus.ConsensusSnapshot; @@ -43,6 +42,7 @@ import java.util.HashSet; import java.util.List; import java.util.Set; +import org.hiero.wiring.framework.transformers.RoutableData; import org.junit.jupiter.api.Test; class StaleEventDetectorTests { diff --git a/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/event/stream/ConsensusEventStreamTest.java b/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/event/stream/ConsensusEventStreamTest.java index 667a174847c..f302fde2d4a 100644 --- a/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/event/stream/ConsensusEventStreamTest.java +++ b/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/event/stream/ConsensusEventStreamTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,13 +27,13 @@ import com.swirlds.common.stream.RunningEventHashOverride; import com.swirlds.common.test.fixtures.RandomUtils; import com.swirlds.common.test.fixtures.platform.TestPlatformContextBuilder; +import com.swirlds.platform.system.events.CesEvent; +import java.util.List; +import java.util.Random; import org.hiero.wiring.framework.component.ComponentWiring; import org.hiero.wiring.framework.model.WiringModel; import org.hiero.wiring.framework.model.WiringModelBuilder; import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; -import com.swirlds.platform.system.events.CesEvent; -import java.util.List; -import java.util.Random; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; diff --git a/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/turtle/gossip/SimulatedGossipTests.java b/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/turtle/gossip/SimulatedGossipTests.java index 2c9299db9a2..6599f08cb95 100644 --- a/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/turtle/gossip/SimulatedGossipTests.java +++ b/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/turtle/gossip/SimulatedGossipTests.java @@ -25,12 +25,6 @@ import com.swirlds.common.platform.NodeId; import com.swirlds.common.test.fixtures.Randotron; import com.swirlds.common.test.fixtures.platform.TestPlatformContextBuilder; -import org.hiero.wiring.framework.model.TraceableWiringModel; -import org.hiero.wiring.framework.model.WiringModel; -import org.hiero.wiring.framework.model.WiringModelBuilder; -import org.hiero.wiring.framework.schedulers.TaskScheduler; -import org.hiero.wiring.framework.wires.input.BindableInputWire; -import org.hiero.wiring.framework.wires.output.StandardOutputWire; import com.swirlds.platform.event.PlatformEvent; import com.swirlds.platform.event.hashing.DefaultEventHasher; import com.swirlds.platform.system.address.AddressBook; @@ -47,6 +41,12 @@ import java.util.Map; import java.util.Set; import java.util.function.Consumer; +import org.hiero.wiring.framework.model.TraceableWiringModel; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.model.WiringModelBuilder; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.wires.input.BindableInputWire; +import org.hiero.wiring.framework.wires.output.StandardOutputWire; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; diff --git a/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/turtle/runner/TurtleNode.java b/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/turtle/runner/TurtleNode.java index 196db2d3494..d34e0f70dce 100644 --- a/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/turtle/runner/TurtleNode.java +++ b/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/turtle/runner/TurtleNode.java @@ -29,8 +29,6 @@ import com.swirlds.common.platform.NodeId; import com.swirlds.common.test.fixtures.Randotron; import com.swirlds.common.test.fixtures.platform.TestPlatformContextBuilder; -import org.hiero.wiring.framework.model.DeterministicWiringModel; -import org.hiero.wiring.framework.model.WiringModelBuilder; import com.swirlds.config.api.Configuration; import com.swirlds.config.extensions.test.fixtures.TestConfigBuilder; import com.swirlds.platform.builder.PlatformBuilder; @@ -49,6 +47,8 @@ import com.swirlds.platform.wiring.PlatformSchedulersConfig_; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.function.Supplier; +import org.hiero.wiring.framework.model.DeterministicWiringModel; +import org.hiero.wiring.framework.model.WiringModelBuilder; /** * Encapsulates a single node running in a TURTLE network. diff --git a/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/wiring/PlatformWiringTests.java b/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/wiring/PlatformWiringTests.java index fe39385beae..dd49e3bcec1 100644 --- a/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/wiring/PlatformWiringTests.java +++ b/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/wiring/PlatformWiringTests.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,8 +21,6 @@ import com.swirlds.common.context.PlatformContext; import com.swirlds.common.test.fixtures.platform.TestPlatformContextBuilder; -import org.hiero.wiring.framework.model.WiringModel; -import org.hiero.wiring.framework.model.WiringModelBuilder; import com.swirlds.config.api.ConfigurationBuilder; import com.swirlds.platform.builder.ApplicationCallbacks; import com.swirlds.platform.builder.PlatformBuildingBlocks; @@ -67,6 +65,8 @@ import com.swirlds.platform.system.events.BirthRoundMigrationShim; import com.swirlds.platform.system.status.StatusStateMachine; import java.util.stream.Stream; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.model.WiringModelBuilder; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; diff --git a/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/wiring/SignedStateReserverTest.java b/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/wiring/SignedStateReserverTest.java index 4ee80ec4ac1..8ae308db5cb 100644 --- a/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/wiring/SignedStateReserverTest.java +++ b/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/wiring/SignedStateReserverTest.java @@ -23,12 +23,6 @@ import com.swirlds.common.context.PlatformContext; import com.swirlds.common.test.fixtures.platform.TestPlatformContextBuilder; import com.swirlds.common.utility.ValueReference; -import org.hiero.wiring.framework.model.WiringModel; -import org.hiero.wiring.framework.model.WiringModelBuilder; -import org.hiero.wiring.framework.schedulers.TaskScheduler; -import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; -import org.hiero.wiring.framework.wires.input.BindableInputWire; -import org.hiero.wiring.framework.wires.output.OutputWire; import com.swirlds.platform.crypto.SignatureVerifier; import com.swirlds.platform.state.PlatformMerkleStateRoot; import com.swirlds.platform.state.signed.ReservedSignedState; @@ -36,6 +30,12 @@ import java.util.List; import java.util.stream.IntStream; import java.util.stream.Stream; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.model.WiringModelBuilder; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.wires.input.BindableInputWire; +import org.hiero.wiring.framework.wires.output.OutputWire; import org.junit.jupiter.api.Test; import org.mockito.Mockito; diff --git a/platform-sdk/swirlds-platform-core/src/testFixtures/java/com/swirlds/platform/test/fixtures/turtle/gossip/SimulatedGossip.java b/platform-sdk/swirlds-platform-core/src/testFixtures/java/com/swirlds/platform/test/fixtures/turtle/gossip/SimulatedGossip.java index bfb6d77d954..4fc1845ffd1 100644 --- a/platform-sdk/swirlds-platform-core/src/testFixtures/java/com/swirlds/platform/test/fixtures/turtle/gossip/SimulatedGossip.java +++ b/platform-sdk/swirlds-platform-core/src/testFixtures/java/com/swirlds/platform/test/fixtures/turtle/gossip/SimulatedGossip.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 Hedera Hashgraph, LLC + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,9 +17,6 @@ package com.swirlds.platform.test.fixtures.turtle.gossip; import com.swirlds.common.platform.NodeId; -import org.hiero.wiring.framework.model.WiringModel; -import org.hiero.wiring.framework.wires.input.BindableInputWire; -import org.hiero.wiring.framework.wires.output.StandardOutputWire; import com.swirlds.platform.consensus.EventWindow; import com.swirlds.platform.event.PlatformEvent; import com.swirlds.platform.gossip.IntakeEventCounter; @@ -29,6 +26,9 @@ import edu.umd.cs.findbugs.annotations.NonNull; import java.time.Duration; import java.util.Objects; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.wires.input.BindableInputWire; +import org.hiero.wiring.framework.wires.output.StandardOutputWire; /** * Simulates the {@link Gossip} subsystem for a group of nodes running on a {@link SimulatedNetwork}. diff --git a/platform-sdk/swirlds-platform-core/src/testFixtures/java/module-info.java b/platform-sdk/swirlds-platform-core/src/testFixtures/java/module-info.java index 9d6da6f4816..93416d8eeec 100644 --- a/platform-sdk/swirlds-platform-core/src/testFixtures/java/module-info.java +++ b/platform-sdk/swirlds-platform-core/src/testFixtures/java/module-info.java @@ -1,4 +1,20 @@ -open module com.swirlds.platform.core.test.fixtures { +/* + * Copyright (C) 2025 Hedera Hashgraph, LLC + * + * 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. + */ + +module com.swirlds.platform.core.test.fixtures { requires transitive com.hedera.node.hapi; requires transitive com.swirlds.common.test.fixtures; requires transitive com.swirlds.common; @@ -14,6 +30,7 @@ requires com.swirlds.logging; requires com.swirlds.merkledb; requires com.swirlds.state.api.test.fixtures; + requires org.hiero.wiring.framework; requires com.github.spotbugs.annotations; requires org.junit.jupiter.api; requires org.mockito; diff --git a/platform-sdk/swirlds-unit-tests/core/swirlds-platform-test/src/main/java/com/swirlds/platform/test/consensus/TestIntake.java b/platform-sdk/swirlds-unit-tests/core/swirlds-platform-test/src/main/java/com/swirlds/platform/test/consensus/TestIntake.java index 6c08813e923..50d957bd903 100644 --- a/platform-sdk/swirlds-unit-tests/core/swirlds-platform-test/src/main/java/com/swirlds/platform/test/consensus/TestIntake.java +++ b/platform-sdk/swirlds-unit-tests/core/swirlds-platform-test/src/main/java/com/swirlds/platform/test/consensus/TestIntake.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2024 Hedera Hashgraph, LLC + * Copyright (C) 2022-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,19 +16,13 @@ package com.swirlds.platform.test.consensus; -import static org.hiero.wiring.framework.wires.SolderType.INJECT; import static com.swirlds.platform.consensus.SyntheticSnapshot.GENESIS_SNAPSHOT; import static com.swirlds.platform.event.AncientMode.GENERATION_THRESHOLD; +import static org.hiero.wiring.framework.wires.SolderType.INJECT; import com.swirlds.base.time.Time; import com.swirlds.common.context.PlatformContext; import com.swirlds.common.platform.NodeId; -import org.hiero.wiring.framework.component.ComponentWiring; -import org.hiero.wiring.framework.model.WiringModel; -import org.hiero.wiring.framework.model.WiringModelBuilder; -import org.hiero.wiring.framework.schedulers.TaskScheduler; -import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; -import org.hiero.wiring.framework.wires.output.OutputWire; import com.swirlds.platform.components.DefaultEventWindowManager; import com.swirlds.platform.components.EventWindowManager; import com.swirlds.platform.components.consensus.ConsensusEngine; @@ -53,6 +47,12 @@ import edu.umd.cs.findbugs.annotations.Nullable; import java.util.LinkedList; import java.util.List; +import org.hiero.wiring.framework.component.ComponentWiring; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.model.WiringModelBuilder; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.wires.output.OutputWire; /** * Event intake with consensus and shadowgraph, used for testing diff --git a/platform-sdk/swirlds-unit-tests/core/swirlds-platform-test/src/main/java/module-info.java b/platform-sdk/swirlds-unit-tests/core/swirlds-platform-test/src/main/java/module-info.java index 38868fc570e..092abbf410e 100644 --- a/platform-sdk/swirlds-unit-tests/core/swirlds-platform-test/src/main/java/module-info.java +++ b/platform-sdk/swirlds-unit-tests/core/swirlds-platform-test/src/main/java/module-info.java @@ -1,4 +1,20 @@ -open module com.swirlds.platform.test { +/* + * Copyright (C) 2025 Hedera Hashgraph, LLC + * + * 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. + */ + +module com.swirlds.platform.test { requires transitive com.swirlds.base; requires transitive com.swirlds.common.test.fixtures; requires transitive com.swirlds.common; @@ -8,6 +24,7 @@ requires com.swirlds.config.api; requires com.swirlds.config.extensions.test.fixtures; requires com.swirlds.state.api; + requires org.hiero.wiring.framework; requires java.desktop; requires org.junit.jupiter.api; requires static transitive com.github.spotbugs.annotations; diff --git a/platform-sdk/swirlds-unit-tests/core/swirlds-platform-test/src/test/java/com/swirlds/platform/test/event/preconsensus/PcesReplayerTests.java b/platform-sdk/swirlds-unit-tests/core/swirlds-platform-test/src/test/java/com/swirlds/platform/test/event/preconsensus/PcesReplayerTests.java index 192898056ee..3324214f688 100644 --- a/platform-sdk/swirlds-unit-tests/core/swirlds-platform-test/src/test/java/com/swirlds/platform/test/event/preconsensus/PcesReplayerTests.java +++ b/platform-sdk/swirlds-unit-tests/core/swirlds-platform-test/src/test/java/com/swirlds/platform/test/event/preconsensus/PcesReplayerTests.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 Hedera Hashgraph, LLC + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,7 +30,6 @@ import com.swirlds.common.io.IOIterator; import com.swirlds.common.test.fixtures.Randotron; import com.swirlds.common.test.fixtures.platform.TestPlatformContextBuilder; -import org.hiero.wiring.framework.wires.output.StandardOutputWire; import com.swirlds.config.extensions.test.fixtures.TestConfigBuilder; import com.swirlds.platform.event.PlatformEvent; import com.swirlds.platform.event.preconsensus.PcesConfig_; @@ -45,6 +44,7 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Supplier; +import org.hiero.wiring.framework.wires.output.StandardOutputWire; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/platform-sdk/swirlds-virtualmap/src/main/java/com/swirlds/virtualmap/internal/hash/VirtualHasher.java b/platform-sdk/swirlds-virtualmap/src/main/java/com/swirlds/virtualmap/internal/hash/VirtualHasher.java index bb865d09253..e1eb5bec7c7 100644 --- a/platform-sdk/swirlds-virtualmap/src/main/java/com/swirlds/virtualmap/internal/hash/VirtualHasher.java +++ b/platform-sdk/swirlds-virtualmap/src/main/java/com/swirlds/virtualmap/internal/hash/VirtualHasher.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021-2024 Hedera Hashgraph, LLC + * Copyright (C) 2021-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,7 +25,6 @@ import com.swirlds.common.crypto.CryptographyHolder; import com.swirlds.common.crypto.Hash; import com.swirlds.common.crypto.HashBuilder; -import org.hiero.wiring.framework.tasks.AbstractTask; import com.swirlds.virtualmap.VirtualKey; import com.swirlds.virtualmap.VirtualMap; import com.swirlds.virtualmap.VirtualValue; @@ -44,6 +43,7 @@ import java.util.function.LongFunction; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.hiero.wiring.framework.tasks.AbstractTask; /** * Responsible for hashing virtual merkle trees. This class is designed to work both for normal diff --git a/platform-sdk/swirlds-virtualmap/src/main/java/module-info.java b/platform-sdk/swirlds-virtualmap/src/main/java/module-info.java index d748cf6dd69..2818b2882ee 100644 --- a/platform-sdk/swirlds-virtualmap/src/main/java/module-info.java +++ b/platform-sdk/swirlds-virtualmap/src/main/java/module-info.java @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2025 Hedera Hashgraph, LLC + * + * 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. + */ + /** * A map that implements the FastCopyable interface. */ @@ -17,13 +33,14 @@ com.swirlds.virtualmap.test.fixtures, com.swirlds.platform.core.test.fixtures; + requires transitive com.hedera.pbj.runtime; requires transitive com.swirlds.common; requires transitive com.swirlds.config.api; requires transitive com.swirlds.metrics.api; - requires transitive com.hedera.pbj.runtime; requires com.swirlds.base; requires com.swirlds.config.extensions; requires com.swirlds.logging; + requires org.hiero.wiring.framework; requires java.management; // Test dependency requires org.apache.logging.log4j; requires static transitive com.github.spotbugs.annotations; diff --git a/platform-sdk/wiring-framework/build.gradle.kts b/platform-sdk/wiring-framework/build.gradle.kts index f620fe6f5d0..fadbabf0a64 100644 --- a/platform-sdk/wiring-framework/build.gradle.kts +++ b/platform-sdk/wiring-framework/build.gradle.kts @@ -37,4 +37,4 @@ testModuleInfo { requires("org.junit.jupiter.params") requires("org.mockito") requiresStatic("com.github.spotbugs.annotations") -} +} \ No newline at end of file diff --git a/platform-sdk/wiring-framework/src/main/java/module-info.java b/platform-sdk/wiring-framework/src/main/java/module-info.java index 6904b933eca..1093494d1fb 100644 --- a/platform-sdk/wiring-framework/src/main/java/module-info.java +++ b/platform-sdk/wiring-framework/src/main/java/module-info.java @@ -16,6 +16,18 @@ module org.hiero.wiring.framework { exports org.hiero.wiring.framework; + exports org.hiero.wiring.framework.model.diagram; + exports org.hiero.wiring.framework.component; + exports org.hiero.wiring.framework.counters; + exports org.hiero.wiring.framework.model; + exports org.hiero.wiring.framework.schedulers; + exports org.hiero.wiring.framework.schedulers.builders; + exports org.hiero.wiring.framework.schedulers.internal; + exports org.hiero.wiring.framework.tasks; + exports org.hiero.wiring.framework.transformers; + exports org.hiero.wiring.framework.wires; + exports org.hiero.wiring.framework.wires.input; + exports org.hiero.wiring.framework.wires.output; requires transitive com.swirlds.base; requires transitive com.swirlds.config.api; diff --git a/platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/TestWiringModelBuilder.java b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/TestWiringModelBuilder.java similarity index 97% rename from platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/TestWiringModelBuilder.java rename to platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/TestWiringModelBuilder.java index c6f5800a525..b489d65c9b4 100644 --- a/platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/TestWiringModelBuilder.java +++ b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/TestWiringModelBuilder.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.common; +package org.hiero.wiring.framework; import com.swirlds.common.context.PlatformContext; import com.swirlds.common.test.fixtures.platform.TestPlatformContextBuilder; diff --git a/platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring/schedulers/ConcurrentTaskSchedulerTests.java b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/schedulers/ConcurrentTaskSchedulerTests.java similarity index 97% rename from platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring/schedulers/ConcurrentTaskSchedulerTests.java rename to platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/schedulers/ConcurrentTaskSchedulerTests.java index 6683927f017..52b5576c939 100644 --- a/platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring/schedulers/ConcurrentTaskSchedulerTests.java +++ b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/schedulers/ConcurrentTaskSchedulerTests.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,20 +14,16 @@ * limitations under the License. */ -package com.swirlds.common.wiring.schedulers; +package org.hiero.wiring.framework.schedulers; import static com.swirlds.common.test.fixtures.AssertionUtils.assertEventuallyEquals; import static com.swirlds.common.test.fixtures.AssertionUtils.assertEventuallyTrue; import static com.swirlds.common.test.fixtures.RandomUtils.getRandomPrintSeed; -import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerBuilder.UNLIMITED_CAPACITY; import static java.util.concurrent.TimeUnit.MICROSECONDS; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerBuilder.UNLIMITED_CAPACITY; import static org.junit.jupiter.api.Assertions.assertEquals; -import com.swirlds.common.TestWiringModelBuilder; -import org.hiero.wiring.framework.model.WiringModel; -import org.hiero.wiring.framework.schedulers.TaskScheduler; -import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; -import org.hiero.wiring.framework.wires.input.BindableInputWire; +import org.hiero.wiring.framework.TestWiringModelBuilder; import edu.umd.cs.findbugs.annotations.Nullable; import java.time.Duration; import java.util.Random; @@ -36,6 +32,9 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import java.util.function.Consumer; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.wires.input.BindableInputWire; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring/schedulers/DefaultSquelcherTests.java b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/schedulers/DefaultSquelcherTests.java similarity index 95% rename from platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring/schedulers/DefaultSquelcherTests.java rename to platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/schedulers/DefaultSquelcherTests.java index 88f99d0a7e8..b9bae1414bd 100644 --- a/platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring/schedulers/DefaultSquelcherTests.java +++ b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/schedulers/DefaultSquelcherTests.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 Hedera Hashgraph, LLC + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.common.wiring.schedulers; +package org.hiero.wiring.framework.schedulers; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertThrows; diff --git a/platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring/schedulers/DirectTaskSchedulerTests.java b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/schedulers/DirectTaskSchedulerTests.java similarity index 97% rename from platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring/schedulers/DirectTaskSchedulerTests.java rename to platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/schedulers/DirectTaskSchedulerTests.java index 0ecbc815ece..e8bcbc6c9cc 100644 --- a/platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring/schedulers/DirectTaskSchedulerTests.java +++ b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/schedulers/DirectTaskSchedulerTests.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,24 +14,23 @@ * limitations under the License. */ -package com.swirlds.common.wiring.schedulers; +package org.hiero.wiring.framework.schedulers; import static com.swirlds.common.test.fixtures.RandomUtils.getRandomPrintSeed; import static com.swirlds.common.utility.NonCryptographicHashing.hash32; import static org.junit.jupiter.api.Assertions.assertEquals; -import com.swirlds.common.TestWiringModelBuilder; +import org.hiero.wiring.framework.TestWiringModelBuilder; +import java.lang.Thread.UncaughtExceptionHandler; +import java.time.Duration; +import java.util.Random; +import java.util.concurrent.atomic.AtomicInteger; import org.hiero.wiring.framework.counters.StandardObjectCounter; import org.hiero.wiring.framework.model.WiringModel; -import org.hiero.wiring.framework.schedulers.TaskScheduler; import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; import org.hiero.wiring.framework.wires.SolderType; import org.hiero.wiring.framework.wires.input.BindableInputWire; import org.hiero.wiring.framework.wires.output.OutputWire; -import java.lang.Thread.UncaughtExceptionHandler; -import java.time.Duration; -import java.util.Random; -import java.util.concurrent.atomic.AtomicInteger; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; diff --git a/platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring/schedulers/HeartbeatSchedulerTests.java b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/schedulers/HeartbeatSchedulerTests.java similarity index 97% rename from platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring/schedulers/HeartbeatSchedulerTests.java rename to platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/schedulers/HeartbeatSchedulerTests.java index a95d400b71c..2b5e1030bd3 100644 --- a/platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring/schedulers/HeartbeatSchedulerTests.java +++ b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/schedulers/HeartbeatSchedulerTests.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.common.wiring.schedulers; +package org.hiero.wiring.framework.schedulers; import static java.util.concurrent.TimeUnit.SECONDS; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -23,13 +23,12 @@ import com.swirlds.base.test.fixtures.time.FakeTime; import com.swirlds.common.context.PlatformContext; import com.swirlds.common.test.fixtures.platform.TestPlatformContextBuilder; -import org.hiero.wiring.framework.model.WiringModel; -import org.hiero.wiring.framework.model.WiringModelBuilder; -import org.hiero.wiring.framework.schedulers.TaskScheduler; -import org.hiero.wiring.framework.wires.input.BindableInputWire; import java.time.Duration; import java.time.Instant; import java.util.concurrent.atomic.AtomicLong; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.model.WiringModelBuilder; +import org.hiero.wiring.framework.wires.input.BindableInputWire; import org.junit.jupiter.api.Test; class HeartbeatSchedulerTests { diff --git a/platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring/schedulers/SequentialTaskSchedulerTests.java b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/schedulers/SequentialTaskSchedulerTests.java similarity index 99% rename from platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring/schedulers/SequentialTaskSchedulerTests.java rename to platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/schedulers/SequentialTaskSchedulerTests.java index 2f85c373262..d9dbe13c5ad 100644 --- a/platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring/schedulers/SequentialTaskSchedulerTests.java +++ b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/schedulers/SequentialTaskSchedulerTests.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.common.wiring.schedulers; +package org.hiero.wiring.framework.schedulers; import static com.swirlds.common.test.fixtures.AssertionUtils.assertEventuallyEquals; import static com.swirlds.common.test.fixtures.AssertionUtils.assertEventuallyTrue; @@ -22,28 +22,19 @@ import static com.swirlds.common.test.fixtures.RandomUtils.getRandomPrintSeed; import static com.swirlds.common.threading.manager.AdHocThreadManager.getStaticThreadManager; import static com.swirlds.common.utility.NonCryptographicHashing.hash32; -import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerBuilder.UNLIMITED_CAPACITY; import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.concurrent.TimeUnit.NANOSECONDS; +import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerBuilder.UNLIMITED_CAPACITY; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; -import com.swirlds.common.TestWiringModelBuilder; +import org.hiero.wiring.framework.TestWiringModelBuilder; import com.swirlds.common.context.PlatformContext; import com.swirlds.common.test.fixtures.RandomUtils; import com.swirlds.common.test.fixtures.platform.TestPlatformContextBuilder; import com.swirlds.common.threading.framework.config.ThreadConfiguration; -import org.hiero.wiring.framework.counters.BackpressureObjectCounter; -import org.hiero.wiring.framework.counters.ObjectCounter; -import org.hiero.wiring.framework.model.WiringModel; -import org.hiero.wiring.framework.model.WiringModelBuilder; -import org.hiero.wiring.framework.schedulers.TaskScheduler; -import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; -import org.hiero.wiring.framework.wires.SolderType; -import org.hiero.wiring.framework.wires.input.BindableInputWire; -import org.hiero.wiring.framework.wires.output.StandardOutputWire; import java.time.Duration; import java.util.HashSet; import java.util.Random; @@ -55,6 +46,14 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Consumer; import java.util.function.Function; +import org.hiero.wiring.framework.counters.BackpressureObjectCounter; +import org.hiero.wiring.framework.counters.ObjectCounter; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.model.WiringModelBuilder; +import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; +import org.hiero.wiring.framework.wires.SolderType; +import org.hiero.wiring.framework.wires.input.BindableInputWire; +import org.hiero.wiring.framework.wires.output.StandardOutputWire; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; diff --git a/platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring/schedulers/ThrowingSquelcherTests.java b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/schedulers/ThrowingSquelcherTests.java similarity index 93% rename from platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring/schedulers/ThrowingSquelcherTests.java rename to platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/schedulers/ThrowingSquelcherTests.java index 2b800cb23cb..e7379db7f9c 100644 --- a/platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring/schedulers/ThrowingSquelcherTests.java +++ b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/schedulers/ThrowingSquelcherTests.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 Hedera Hashgraph, LLC + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.common.wiring.schedulers; +package org.hiero.wiring.framework.schedulers; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertThrows; diff --git a/platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring/transformers/TaskSchedulerTransformersTests.java b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/transformers/TaskSchedulerTransformersTests.java similarity index 99% rename from platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring/transformers/TaskSchedulerTransformersTests.java rename to platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/transformers/TaskSchedulerTransformersTests.java index 7b460a84692..fcf781ba5e7 100644 --- a/platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring/transformers/TaskSchedulerTransformersTests.java +++ b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/transformers/TaskSchedulerTransformersTests.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.swirlds.common.wiring.transformers; +package org.hiero.wiring.framework.transformers; import static com.swirlds.common.test.fixtures.AssertionUtils.assertEventuallyEquals; import static com.swirlds.common.test.fixtures.AssertionUtils.assertEventuallyTrue; @@ -22,13 +22,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; -import com.swirlds.common.TestWiringModelBuilder; -import org.hiero.wiring.framework.model.WiringModel; -import org.hiero.wiring.framework.schedulers.TaskScheduler; -import org.hiero.wiring.framework.transformers.AdvancedTransformation; -import org.hiero.wiring.framework.wires.SolderType; -import org.hiero.wiring.framework.wires.input.BindableInputWire; -import org.hiero.wiring.framework.wires.output.OutputWire; +import org.hiero.wiring.framework.TestWiringModelBuilder; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; import java.lang.Thread.UncaughtExceptionHandler; @@ -40,6 +34,11 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Consumer; import java.util.function.Function; +import org.hiero.wiring.framework.model.WiringModel; +import org.hiero.wiring.framework.schedulers.TaskScheduler; +import org.hiero.wiring.framework.wires.SolderType; +import org.hiero.wiring.framework.wires.input.BindableInputWire; +import org.hiero.wiring.framework.wires.output.OutputWire; import org.junit.jupiter.api.Test; class TaskSchedulerTransformersTests { diff --git a/platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring/wires/OutputWireTests.java b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/wires/OutputWireTests.java similarity index 98% rename from platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring/wires/OutputWireTests.java rename to platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/wires/OutputWireTests.java index d320089c5fa..5fb3e2efab1 100644 --- a/platform-sdk/swirlds-common/src/timingSensitive/java/com/swirlds/common/wiring/wires/OutputWireTests.java +++ b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/wires/OutputWireTests.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 Hedera Hashgraph, LLC + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,21 +14,21 @@ * limitations under the License. */ -package com.swirlds.common.wiring.wires; +package org.hiero.wiring.framework.wires; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import com.swirlds.common.context.PlatformContext; import com.swirlds.common.test.fixtures.platform.TestPlatformContextBuilder; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; import org.hiero.wiring.framework.model.WiringModel; import org.hiero.wiring.framework.model.WiringModelBuilder; import org.hiero.wiring.framework.schedulers.TaskScheduler; import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; import org.hiero.wiring.framework.wires.input.BindableInputWire; import org.hiero.wiring.framework.wires.input.InputWire; -import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; From 33ea845e807854b9a141b379f5cbf7d95b708524 Mon Sep 17 00:00:00 2001 From: mxtartaglia Date: Tue, 14 Jan 2025 23:59:08 -0300 Subject: [PATCH 5/6] chore: new module for wiring framework Signed-off-by: mxtartaglia --- .../swirlds-platform-core/build.gradle.kts | 17 ++++++++++++++++- platform-sdk/wiring-framework/build.gradle.kts | 2 +- .../framework/TestWiringModelBuilder.java | 4 ++-- .../ConcurrentTaskSchedulerTests.java | 2 +- .../schedulers/DirectTaskSchedulerTests.java | 2 +- .../SequentialTaskSchedulerTests.java | 2 +- .../TaskSchedulerTransformersTests.java | 2 +- 7 files changed, 23 insertions(+), 8 deletions(-) diff --git a/platform-sdk/swirlds-platform-core/build.gradle.kts b/platform-sdk/swirlds-platform-core/build.gradle.kts index 7ee8f81d642..aa7ca7466f4 100644 --- a/platform-sdk/swirlds-platform-core/build.gradle.kts +++ b/platform-sdk/swirlds-platform-core/build.gradle.kts @@ -1,4 +1,19 @@ -// SPDX-License-Identifier: Apache-2.0 +/* + * Copyright (C) 2025 Hedera Hashgraph, LLC + * + * 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. + */ + plugins { id("org.hiero.gradle.module.library") id("org.hiero.gradle.feature.publish-artifactregistry") diff --git a/platform-sdk/wiring-framework/build.gradle.kts b/platform-sdk/wiring-framework/build.gradle.kts index fadbabf0a64..f620fe6f5d0 100644 --- a/platform-sdk/wiring-framework/build.gradle.kts +++ b/platform-sdk/wiring-framework/build.gradle.kts @@ -37,4 +37,4 @@ testModuleInfo { requires("org.junit.jupiter.params") requires("org.mockito") requiresStatic("com.github.spotbugs.annotations") -} \ No newline at end of file +} diff --git a/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/TestWiringModelBuilder.java b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/TestWiringModelBuilder.java index b489d65c9b4..35e203b7399 100644 --- a/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/TestWiringModelBuilder.java +++ b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/TestWiringModelBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 Hedera Hashgraph, LLC + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,9 +18,9 @@ import com.swirlds.common.context.PlatformContext; import com.swirlds.common.test.fixtures.platform.TestPlatformContextBuilder; +import edu.umd.cs.findbugs.annotations.NonNull; import org.hiero.wiring.framework.model.WiringModel; import org.hiero.wiring.framework.model.WiringModelBuilder; -import edu.umd.cs.findbugs.annotations.NonNull; /** * A simple version of a wiring model for scenarios where the wiring model is not needed. diff --git a/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/schedulers/ConcurrentTaskSchedulerTests.java b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/schedulers/ConcurrentTaskSchedulerTests.java index 52b5576c939..2cbc4ca4ff2 100644 --- a/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/schedulers/ConcurrentTaskSchedulerTests.java +++ b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/schedulers/ConcurrentTaskSchedulerTests.java @@ -23,7 +23,6 @@ import static org.hiero.wiring.framework.schedulers.builders.TaskSchedulerBuilder.UNLIMITED_CAPACITY; import static org.junit.jupiter.api.Assertions.assertEquals; -import org.hiero.wiring.framework.TestWiringModelBuilder; import edu.umd.cs.findbugs.annotations.Nullable; import java.time.Duration; import java.util.Random; @@ -32,6 +31,7 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import java.util.function.Consumer; +import org.hiero.wiring.framework.TestWiringModelBuilder; import org.hiero.wiring.framework.model.WiringModel; import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; import org.hiero.wiring.framework.wires.input.BindableInputWire; diff --git a/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/schedulers/DirectTaskSchedulerTests.java b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/schedulers/DirectTaskSchedulerTests.java index e8bcbc6c9cc..15f9910311e 100644 --- a/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/schedulers/DirectTaskSchedulerTests.java +++ b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/schedulers/DirectTaskSchedulerTests.java @@ -20,11 +20,11 @@ import static com.swirlds.common.utility.NonCryptographicHashing.hash32; import static org.junit.jupiter.api.Assertions.assertEquals; -import org.hiero.wiring.framework.TestWiringModelBuilder; import java.lang.Thread.UncaughtExceptionHandler; import java.time.Duration; import java.util.Random; import java.util.concurrent.atomic.AtomicInteger; +import org.hiero.wiring.framework.TestWiringModelBuilder; import org.hiero.wiring.framework.counters.StandardObjectCounter; import org.hiero.wiring.framework.model.WiringModel; import org.hiero.wiring.framework.schedulers.builders.TaskSchedulerType; diff --git a/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/schedulers/SequentialTaskSchedulerTests.java b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/schedulers/SequentialTaskSchedulerTests.java index d9dbe13c5ad..24a370bbeca 100644 --- a/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/schedulers/SequentialTaskSchedulerTests.java +++ b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/schedulers/SequentialTaskSchedulerTests.java @@ -30,7 +30,6 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; -import org.hiero.wiring.framework.TestWiringModelBuilder; import com.swirlds.common.context.PlatformContext; import com.swirlds.common.test.fixtures.RandomUtils; import com.swirlds.common.test.fixtures.platform.TestPlatformContextBuilder; @@ -46,6 +45,7 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Consumer; import java.util.function.Function; +import org.hiero.wiring.framework.TestWiringModelBuilder; import org.hiero.wiring.framework.counters.BackpressureObjectCounter; import org.hiero.wiring.framework.counters.ObjectCounter; import org.hiero.wiring.framework.model.WiringModel; diff --git a/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/transformers/TaskSchedulerTransformersTests.java b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/transformers/TaskSchedulerTransformersTests.java index fcf781ba5e7..f06e4dd7ca3 100644 --- a/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/transformers/TaskSchedulerTransformersTests.java +++ b/platform-sdk/wiring-framework/src/test/java/org/hiero/wiring/framework/transformers/TaskSchedulerTransformersTests.java @@ -22,7 +22,6 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; -import org.hiero.wiring.framework.TestWiringModelBuilder; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; import java.lang.Thread.UncaughtExceptionHandler; @@ -34,6 +33,7 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Consumer; import java.util.function.Function; +import org.hiero.wiring.framework.TestWiringModelBuilder; import org.hiero.wiring.framework.model.WiringModel; import org.hiero.wiring.framework.schedulers.TaskScheduler; import org.hiero.wiring.framework.wires.SolderType; From 298e0fbd065b482db241369692d0f7bddd8a88a3 Mon Sep 17 00:00:00 2001 From: mxtartaglia Date: Wed, 15 Jan 2025 00:10:44 -0300 Subject: [PATCH 6/6] chore: new module for wiring framework Signed-off-by: mxtartaglia --- platform-sdk/swirlds-merkledb/src/main/java/module-info.java | 2 +- platform-sdk/swirlds-platform-core/build.gradle.kts | 1 - .../swirlds-platform-core/src/main/java/module-info.java | 2 +- .../core/swirlds-platform-test/src/main/java/module-info.java | 2 +- platform-sdk/wiring-framework/src/main/java/module-info.java | 2 +- 5 files changed, 4 insertions(+), 5 deletions(-) diff --git a/platform-sdk/swirlds-merkledb/src/main/java/module-info.java b/platform-sdk/swirlds-merkledb/src/main/java/module-info.java index 869208f6e65..1ab90a0f28f 100644 --- a/platform-sdk/swirlds-merkledb/src/main/java/module-info.java +++ b/platform-sdk/swirlds-merkledb/src/main/java/module-info.java @@ -31,10 +31,10 @@ requires transitive com.swirlds.config.api; requires transitive com.swirlds.metrics.api; requires transitive com.swirlds.virtualmap; + requires transitive org.hiero.wiring.framework; requires com.swirlds.base; requires com.swirlds.config.extensions; requires com.swirlds.logging; - requires org.hiero.wiring.framework; requires java.management; requires jdk.management; requires jdk.unsupported; diff --git a/platform-sdk/swirlds-platform-core/build.gradle.kts b/platform-sdk/swirlds-platform-core/build.gradle.kts index aa7ca7466f4..b7167954999 100644 --- a/platform-sdk/swirlds-platform-core/build.gradle.kts +++ b/platform-sdk/swirlds-platform-core/build.gradle.kts @@ -73,6 +73,5 @@ timingSensitiveModuleInfo { requires("com.swirlds.platform.core.test.fixtures") requires("org.assertj.core") requires("org.junit.jupiter.api") - requires("org.hiero.wiring.framework") requires("org.junit.jupiter.params") } diff --git a/platform-sdk/swirlds-platform-core/src/main/java/module-info.java b/platform-sdk/swirlds-platform-core/src/main/java/module-info.java index 920f131e8c2..f596d2a2601 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/module-info.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/module-info.java @@ -153,6 +153,7 @@ requires transitive com.swirlds.state.impl; requires transitive org.hiero.consensus.gossip; requires transitive org.hiero.event.creator; + requires transitive org.hiero.wiring.framework; requires transitive com.fasterxml.jackson.annotation; requires transitive com.fasterxml.jackson.databind; requires transitive info.picocli; @@ -162,7 +163,6 @@ requires com.swirlds.merkledb; requires com.swirlds.virtualmap; requires org.hiero.event.creator.impl; - requires org.hiero.wiring.framework; requires com.fasterxml.jackson.core; requires com.fasterxml.jackson.dataformat.yaml; requires com.github.spotbugs.annotations; diff --git a/platform-sdk/swirlds-unit-tests/core/swirlds-platform-test/src/main/java/module-info.java b/platform-sdk/swirlds-unit-tests/core/swirlds-platform-test/src/main/java/module-info.java index 092abbf410e..b2e949f6552 100644 --- a/platform-sdk/swirlds-unit-tests/core/swirlds-platform-test/src/main/java/module-info.java +++ b/platform-sdk/swirlds-unit-tests/core/swirlds-platform-test/src/main/java/module-info.java @@ -20,11 +20,11 @@ requires transitive com.swirlds.common; requires transitive com.swirlds.platform.core.test.fixtures; requires transitive com.swirlds.platform.core; + requires transitive org.hiero.wiring.framework; requires com.hedera.node.hapi; requires com.swirlds.config.api; requires com.swirlds.config.extensions.test.fixtures; requires com.swirlds.state.api; - requires org.hiero.wiring.framework; requires java.desktop; requires org.junit.jupiter.api; requires static transitive com.github.spotbugs.annotations; diff --git a/platform-sdk/wiring-framework/src/main/java/module-info.java b/platform-sdk/wiring-framework/src/main/java/module-info.java index 1093494d1fb..0dc3a3aba6f 100644 --- a/platform-sdk/wiring-framework/src/main/java/module-info.java +++ b/platform-sdk/wiring-framework/src/main/java/module-info.java @@ -30,8 +30,8 @@ exports org.hiero.wiring.framework.wires.output; requires transitive com.swirlds.base; + requires transitive com.swirlds.common; requires transitive com.swirlds.config.api; - requires com.swirlds.common; requires com.swirlds.logging; requires com.swirlds.metrics.api; requires org.apache.logging.log4j;