/* Copyright 2012 Google, Inc.
*
* 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.arbeitspferde.groningen;
import com.google.inject.Inject;
import org.arbeitspferde.groningen.config.GroningenConfig;
import org.arbeitspferde.groningen.config.PipelineIterationScoped;
import org.arbeitspferde.groningen.executor.Executor;
import org.arbeitspferde.groningen.generator.Generator;
import org.arbeitspferde.groningen.hypothesizer.Hypothesizer;
import org.arbeitspferde.groningen.scorer.IterationScorer;
import org.arbeitspferde.groningen.utility.Metric;
import org.arbeitspferde.groningen.utility.MetricExporter;
import org.arbeitspferde.groningen.validator.Validator;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Logger;
/**
* This class encapsulates the logic of one pipeline iteration. It's assumed that this class
* is used withing @PipelineIterationScoped Guice scope with all the dependencies injected or
* seeded by Guice.
*
* TODO(team): Current implementation doesn't allow more than one PipelineIteration instance
* to be used simultaneously (see currentPipelineStage metrics, for example).
*/
@PipelineIterationScoped
public class PipelineIteration {
private static final Logger log = Logger.getLogger(PipelineIteration.class.getCanonicalName());
private final GroningenConfig config;
private final PipelineSynchronizer pipelineSynchronizer;
private final Executor executor;
private final Generator generator;
private final Hypothesizer hypothesizer;
private final Validator validator;
private final IterationScorer scorer;
private final PipelineStageInfo pipelineStageInfo;
/**
* Track the pipestage we are in. It's fine to have this metrics defined this way as there's only
* one pipeline per Groningen instance.
*
* TODO(team): fix when we have multiple pipelines
**/
private static final AtomicInteger currentPipelineStage = new AtomicInteger();
@Inject
public PipelineIteration(final GroningenConfig config,
final PipelineSynchronizer pipelineSynchronizer,
final Executor executor,
final Generator generator,
final Hypothesizer hypothesizer,
final Validator validator,
final IterationScorer scorer,
final MetricExporter metricExporter,
final PipelineStageInfo pipelineStageInfo) {
this.config = config;
this.pipelineSynchronizer = pipelineSynchronizer;
this.executor = executor;
this.generator = generator;
this.hypothesizer = hypothesizer;
this.validator = validator;
this.scorer = scorer;
this.pipelineStageInfo = pipelineStageInfo;
metricExporter.register(
"current_pipeline_stage",
"Current stage: 0=Hypothesizer, 1=Generator, 2=Executor, 3=Validator 4=Scorer",
Metric.make(currentPipelineStage));
}
public int getStage() {
return currentPipelineStage.get();
}
/**
* Provide the remaining time within the run of the experiment.
*
* This does not include any restart or wait times and is only valid when the experiment
* is running.
*
* @return time in secs remaining in the experiment, -1 if the request was made outside the
* valid window.
*/
public int getRemainingExperimentalSecs() {
return (int) executor.getRemainingDurationSeconds();
}
public boolean run() {
executor.startUp();
generator.startUp();
hypothesizer.startUp();
validator.startUp();
scorer.startUp();
currentPipelineStage.set(0);
// Synchronization within the pipeline iteration - after the config is updated
pipelineSynchronizer.iterationStartHook();
pipelineStageInfo.set(PipelineStageState.HYPOTHESIZER);
hypothesizer.run(config);
boolean notComplete = hypothesizer.notComplete();
if (notComplete) {
currentPipelineStage.set(1);
pipelineStageInfo.set(PipelineStageState.GENERATOR);
generator.run(config);
// This stage returns only when all experiments are complete
currentPipelineStage.set(2);
pipelineSynchronizer.executorStartHook();
executor.run(config);
currentPipelineStage.set(3);
pipelineStageInfo.set(PipelineStageState.SCORING);
validator.run(config);
currentPipelineStage.set(4);
scorer.run(config);
}
return notComplete;
}
}