angular-cn/packages/benchpress/src/sampler.ts

90 lines
3.2 KiB
TypeScript

/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import {Inject, Injectable, StaticProvider} from '@angular/core';
import {Options} from './common_options';
import {MeasureValues} from './measure_values';
import {Metric} from './metric';
import {Reporter} from './reporter';
import {Validator} from './validator';
import {WebDriverAdapter} from './web_driver_adapter';
/**
* The Sampler owns the sample loop:
* 1. calls the prepare/execute callbacks,
* 2. gets data from the metric
* 3. asks the validator for a valid sample
* 4. reports the new data to the reporter
* 5. loop until there is a valid sample
*/
@Injectable()
export class Sampler {
static PROVIDERS = <StaticProvider[]>[{
provide: Sampler,
deps: [
WebDriverAdapter, Metric, Reporter, Validator, Options.PREPARE, Options.EXECUTE, Options.NOW
]
}];
constructor(
private _driver: WebDriverAdapter, private _metric: Metric, private _reporter: Reporter,
private _validator: Validator, @Inject(Options.PREPARE) private _prepare: Function,
@Inject(Options.EXECUTE) private _execute: Function,
@Inject(Options.NOW) private _now: Function) {}
sample(): Promise<SampleState> {
const loop = (lastState: SampleState): Promise<SampleState> => {
return this._iterate(lastState).then((newState) => {
if (newState.validSample != null) {
return newState;
} else {
return loop(newState);
}
});
};
return loop(new SampleState([], null));
}
private _iterate(lastState: SampleState): Promise<SampleState> {
let resultPromise: Promise<SampleState|null>;
if (this._prepare !== Options.NO_PREPARE) {
resultPromise = this._driver.waitFor(this._prepare);
} else {
resultPromise = Promise.resolve(null);
}
if (this._prepare !== Options.NO_PREPARE || lastState.completeSample.length === 0) {
resultPromise = resultPromise.then((_) => this._metric.beginMeasure());
}
return resultPromise.then((_) => this._driver.waitFor(this._execute))
.then((_) => this._metric.endMeasure(this._prepare === Options.NO_PREPARE))
.then((measureValues) => {
if (!!measureValues['invalid']) {
return lastState;
}
return this._report(lastState, measureValues);
});
}
private _report(state: SampleState, metricValues: {[key: string]: any}): Promise<SampleState> {
const measureValues = new MeasureValues(state.completeSample.length, this._now(), metricValues);
const completeSample = state.completeSample.concat([measureValues]);
const validSample = this._validator.validate(completeSample);
let resultPromise = this._reporter.reportMeasureValues(measureValues);
if (validSample != null) {
resultPromise =
resultPromise.then((_) => this._reporter.reportSample(completeSample, validSample));
}
return resultPromise.then((_) => new SampleState(completeSample, validSample));
}
}
export class SampleState {
constructor(public completeSample: MeasureValues[], public validSample: MeasureValues[]|null) {}
}