From 4a8b32d288ba3ee986ecef7933fa77554d34e762 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Tue, 4 May 2021 19:19:47 +0200 Subject: harness: Split harness into separate modules This change splits the OpenDC Experiment Harness into separate modules. This prevents users from pulling in unnecessary dependencies when depending on the harness API. --- .../runner/cli/ConsoleExperimentReporter.kt | 79 +++++++++++++++++ .../org/opendc/harness/runner/cli/ConsoleRunner.kt | 99 ++++++++++++++++++++++ .../src/main/resources/log4j2.xml | 38 +++++++++ 3 files changed, 216 insertions(+) create mode 100644 opendc-harness/opendc-harness-cli/src/main/kotlin/org/opendc/harness/runner/cli/ConsoleExperimentReporter.kt create mode 100644 opendc-harness/opendc-harness-cli/src/main/kotlin/org/opendc/harness/runner/cli/ConsoleRunner.kt create mode 100644 opendc-harness/opendc-harness-cli/src/main/resources/log4j2.xml (limited to 'opendc-harness/opendc-harness-cli/src/main') diff --git a/opendc-harness/opendc-harness-cli/src/main/kotlin/org/opendc/harness/runner/cli/ConsoleExperimentReporter.kt b/opendc-harness/opendc-harness-cli/src/main/kotlin/org/opendc/harness/runner/cli/ConsoleExperimentReporter.kt new file mode 100644 index 00000000..7177467a --- /dev/null +++ b/opendc-harness/opendc-harness-cli/src/main/kotlin/org/opendc/harness/runner/cli/ConsoleExperimentReporter.kt @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.harness.runner.cli + +import me.tongfei.progressbar.ProgressBar +import me.tongfei.progressbar.ProgressBarBuilder +import mu.KotlinLogging +import org.opendc.harness.api.Trial +import org.opendc.harness.engine.ExperimentExecutionListener + +/** + * A reporter that reports the experiment progress to the console. + */ +public class ConsoleExperimentReporter : ExperimentExecutionListener, AutoCloseable { + /** + * The active [Trial]s. + */ + private val trials: MutableSet = mutableSetOf() + + /** + * The total number of runs. + */ + private var total = 0 + + /** + * The logger for this reporter. + */ + private val logger = KotlinLogging.logger {} + + /** + * The progress bar to keep track of the progress. + */ + private val pb: ProgressBar = ProgressBarBuilder() + .setTaskName("") + .setInitialMax(1) + .build() + + override fun trialFinished(trial: Trial, throwable: Throwable?) { + trials -= trial + + pb.stepTo(total - trials.size.toLong()) + if (trials.isEmpty()) { + pb.close() + } + + if (throwable != null) { + logger.warn(throwable) { "Trial $trial failed" } + } + } + + override fun trialStarted(trial: Trial) { + trials += trial + pb.maxHint((++total).toLong()) + } + + override fun close() { + pb.close() + } +} diff --git a/opendc-harness/opendc-harness-cli/src/main/kotlin/org/opendc/harness/runner/cli/ConsoleRunner.kt b/opendc-harness/opendc-harness-cli/src/main/kotlin/org/opendc/harness/runner/cli/ConsoleRunner.kt new file mode 100644 index 00000000..c59e623c --- /dev/null +++ b/opendc-harness/opendc-harness-cli/src/main/kotlin/org/opendc/harness/runner/cli/ConsoleRunner.kt @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2021 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.harness.runner.cli + +import com.github.ajalt.clikt.core.CliktCommand +import com.github.ajalt.clikt.parameters.options.default +import com.github.ajalt.clikt.parameters.options.multiple +import com.github.ajalt.clikt.parameters.options.option +import com.github.ajalt.clikt.parameters.types.int +import mu.KotlinLogging +import org.opendc.harness.engine.ExperimentEngineLauncher +import org.opendc.harness.engine.discovery.DiscoveryProvider +import org.opendc.harness.engine.discovery.DiscoveryRequest +import org.opendc.harness.engine.discovery.DiscoverySelector +import org.opendc.harness.engine.scheduler.ThreadPoolExperimentScheduler + +/** + * The logger for this experiment runner. + */ +private val logger = KotlinLogging.logger {} + +/** + * The command line interface for the console experiment runner. + */ +public class ConsoleRunner : CliktCommand(name = "opendc-harness") { + /** + * The number of repeats per scenario. + */ + private val repeats by option("-r", "--repeats", help = "Number of repeats per scenario") + .int() + .default(1) + + /** + * The selected experiments to run by name. + */ + private val experiments by option("-e", "--experiments", help = "Names of experiments to explore") + .multiple(emptyList()) + + /** + * The maximum number of worker threads to use. + */ + private val parallelism by option("-p", "--parallelism", help = "Maximum number of concurrent simulation runs") + .int() + .default(Runtime.getRuntime().availableProcessors()) + + override fun run() { + logger.info { "Starting OpenDC Console Experiment Runner" } + + val discovery = DiscoveryProvider.createComposite() + val experiments = discovery.discover( + DiscoveryRequest( + selectors = experiments.map { DiscoverySelector.Name(it) } + ) + ) + + val reporter = ConsoleExperimentReporter() + val scheduler = ThreadPoolExperimentScheduler(parallelism) + + try { + ExperimentEngineLauncher() + .withListener(reporter) + .withRepeats(repeats) + .withScheduler(scheduler) + .runBlocking(experiments) + } catch (e: Throwable) { + logger.error(e) { "Failed to finish experiments" } + } finally { + reporter.close() + scheduler.close() + } + + logger.info { "Finished all experiments. Exiting." } + } +} + +/** + * Main entry point of the experiment runner. + */ +public fun main(args: Array): Unit = ConsoleRunner().main(args) diff --git a/opendc-harness/opendc-harness-cli/src/main/resources/log4j2.xml b/opendc-harness/opendc-harness-cli/src/main/resources/log4j2.xml new file mode 100644 index 00000000..32d81416 --- /dev/null +++ b/opendc-harness/opendc-harness-cli/src/main/resources/log4j2.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + -- cgit v1.2.3