Skip to content

Commit

Permalink
Refactor result flow
Browse files Browse the repository at this point in the history
  • Loading branch information
ehmicky committed Jan 9, 2022
1 parent 9311963 commit 0ccf39b
Show file tree
Hide file tree
Showing 11 changed files with 115 additions and 68 deletions.
5 changes: 4 additions & 1 deletion src/combination/list.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import mapObj from 'map-obj'

import { UserError } from '../error/main.js'
import { selectCombinations } from '../select/main.js'

import { validateCombinationsIds } from './ids/validate.js'
import { toInputsList } from './inputs.js'
Expand All @@ -14,13 +15,15 @@ export const listCombinations = async function ({
inputs,
system,
cwd,
select,
}) {
const tasks = await listTasks(runners, cwd)
const inputsList = toInputsList(inputs)

const combinations = getCombinationsProduct({ tasks, inputsList, system })
validateCombinationsIds(combinations, inputsList)
return combinations
const combinationsA = selectCombinations(combinations, select)
return combinationsA
}

// Get cartesian product of all combinations.
Expand Down
13 changes: 5 additions & 8 deletions src/history/data/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { pickLast } from '../../utils/last.js'
import { applyMainDelta, applySinceDelta } from '../delta/find.js'
import { groupMetadata, ungroupMetadata } from '../merge/metadata.js'
import { compressRawResult } from '../normalize/compress.js'
import { loadRawResults, normalizeRawResults } from '../normalize/load.js'
import { loadRawResults, normalizePreviousResults } from '../normalize/load.js'

import {
addRawResult,
Expand Down Expand Up @@ -54,13 +54,10 @@ export const getFromHistory = async function (config) {
const metadataGroupsC = await applySinceDelta(metadataGroupsB, config)
const metadataGroupsD = [...metadataGroupsC, targetMetadataGroup]
const history = await fetchHistory(metadataGroupsD, config)
const [historyA, targetResult] = pickLast(history)
const { targetResult: rawResult, history: historyB } = normalizeRawResults(
targetResult,
historyA,
config,
)
return { rawResult, history: historyB }
const [historyA, rawResult] = pickLast(history)
const { targetResult: rawResultA, history: historyB } =
normalizePreviousResults(rawResult, historyA, config)
return { rawResult: rawResultA, history: historyB }
}

// List all history results, after applying the `since` delta.
Expand Down
44 changes: 29 additions & 15 deletions src/history/normalize/load.js
Original file line number Diff line number Diff line change
@@ -1,33 +1,51 @@
import { addDefaultIds } from '../../combination/default.js'
import { keepResultCombinations } from '../../combination/result.js'
import { selectRawResult } from '../../select/main.js'
import { validateSelectMatches } from '../../select/validate.js'
import { mergeResults } from '../merge/results.js'

import { decompressRawResult } from './decompress.js'
import { migrateRawResults } from './migrate.js'

// Normalize rawResults on load
// Normalize rawResults after they have been loaded from result files.
export const loadRawResults = function (rawResults) {
const rawResultsA = migrateRawResults(rawResults)
const rawResultsB = rawResultsA.map(decompressRawResult)
return rawResultsB
}

// Normalize the history and target results after load, once the target result
// is known
export const normalizeRawResults = function (targetResult, history, config) {
// Normalize the history and target results after the target result is known,
// as reporting starts.
// The result is only used by the reporting logic, not the measuring logic,
// and it is not persisted in result files.
// We separate into two functions: this one is for new results with `run`.
export const normalizeNewResults = function (targetResult, history) {
const { history: historyA, targetResult: targetResultA } = mergeResults(
history,
targetResult,
)
const historyB = addDefaultIds(historyA, targetResultA)
const historyC = filterUnusedCombinations(historyB, targetResultA)
const [targetResultB, ...historyD] = [targetResultA, ...historyC].map(
(rawResult) => normalizeRawResult(rawResult, config),
const historyB = normalizeHistory(historyA, targetResultA)
return { targetResult: targetResultA, history: historyB }
}

// Same but for previous results with `show|remove`.
export const normalizePreviousResults = function (
targetResult,
history,
{ select },
) {
const { history: historyA, targetResult: targetResultA } = mergeResults(
history,
targetResult,
)
validateSelectMatches(targetResultB, config)
return { targetResult: targetResultB, history: historyD }
const targetResultB = selectRawResult(targetResultA, select)
const historyB = normalizeHistory(historyA, targetResultB)
return { targetResult: targetResultB, history: historyB }
}

const normalizeHistory = function (history, targetResult) {
const historyA = addDefaultIds(history, targetResult)
const historyB = filterUnusedCombinations(historyA, targetResult)
return historyB
}

// We ignore the combinations from history results that do not exist in the
Expand All @@ -38,7 +56,3 @@ const filterUnusedCombinations = function (history, targetResult) {
keepResultCombinations(rawResult, targetResult),
)
}

const normalizeRawResult = function (rawResult, { select }) {
return selectRawResult(rawResult, select)
}
10 changes: 1 addition & 9 deletions src/run/create.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,14 @@
import { listCombinations } from '../combination/list.js'
import { listHistory } from '../history/data/main.js'
import { normalizeRawResults } from '../history/normalize/load.js'
import { createTopProps } from '../top/create.js'
import { mergeSystemVersions } from '../top/system/versions/merge.js'

// Create a new rawResult to measure
export const createResult = async function (config) {
const [rawResult, history] = await Promise.all([
createRawResult(config),
listHistory(config),
])
const { targetResult: rawResultA, history: historyA } = normalizeRawResults(
rawResult,
history,
config,
)
const rawResultB = mergeSystemVersions(rawResultA)
return { rawResult: rawResultB, history: historyA }
return { rawResult, history }
}

const createRawResult = async function (config) {
Expand Down
30 changes: 21 additions & 9 deletions src/run/main.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { normalizeNewResults } from '../history/normalize/load.js'
import {
reportStart,
reportCompute,
Expand All @@ -7,7 +8,10 @@ import {

import { createResult } from './create.js'
import { measureCombinations } from './measure/main.js'
import { normalizeMeasuredResult } from './normalize.js'
import {
normalizeMeasuredResult,
updateCombinationsStats,
} from './normalize.js'
import {
initPreview,
startPreview,
Expand All @@ -26,33 +30,39 @@ export const performRun = async function (config) {
const previewState = initPreview(config)

const { rawResult, history } = await createResult(config)
const { targetResult: result, history: historyA } = normalizeNewResults(
normalizeMeasuredResult(rawResult),
history,
)
const {
result,
result: resultA,
sinceResult,
noDimensions,
config: configA,
} = await reportStart(rawResult, history, config)
} = await reportStart(result, historyA, config)

try {
const {
result: { combinations },
rawResult: rawResultA,
programmaticResult,
contents,
} = await previewAndMeasure({
result,
rawResult,
result: resultA,
sinceResult,
noDimensions,
previewState,
config: configA,
})
await reportPrint(contents)
return { rawResult: { ...rawResult, combinations }, programmaticResult }
return { rawResult: rawResultA, programmaticResult }
} finally {
await reportEnd(configA)
}
}

const previewAndMeasure = async function ({
rawResult,
result,
sinceResult,
noDimensions,
Expand All @@ -61,6 +71,7 @@ const previewAndMeasure = async function ({
config: { cwd, precisionTarget, outliers },
}) {
const previewStateA = await startPreview({
rawResult,
result,
sinceResult,
noDimensions,
Expand All @@ -69,23 +80,24 @@ const previewAndMeasure = async function ({
})

try {
const combinations = await measureCombinations(result.combinations, {
const combinations = await measureCombinations(rawResult.combinations, {
precisionTarget,
cwd,
previewState: previewStateA,
outliers,
stage: 'main',
noDimensions,
})
const resultA = normalizeMeasuredResult({ ...result, combinations })
const rawResultA = normalizeMeasuredResult({ ...rawResult, combinations })
const resultA = updateCombinationsStats(result, combinations)
const { programmaticResult, contents } = await reportCompute({
result: resultA,
sinceResult,
noDimensions,
config,
})
await endPreview(previewStateA)
return { result: resultA, programmaticResult, contents }
return { rawResult: rawResultA, programmaticResult, contents }
} catch (error) {
await endPreview(previewStateA, error)
throw error
Expand Down
35 changes: 30 additions & 5 deletions src/run/normalize.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import mapObj from 'map-obj'

// Normalize the result after measuring
export const normalizeMeasuredResult = function (result) {
const combinations = result.combinations.map(normalizeCombination)
return { ...result, combinations }
import { setArray } from '../utils/set.js'

// Normalize the rawResult after measuring
export const normalizeMeasuredResult = function (rawResult) {
const combinations = rawResult.combinations.map(normalizeCombination)
return { ...rawResult, combinations }
}

// Only keep the properties we need for reporting
// Only keep the properties we need when saving to the history file
const normalizeCombination = function ({ dimensions, stats }) {
const dimensionsA = mapObj(dimensions, getIdProp)
return { dimensions: dimensionsA, stats }
Expand All @@ -15,3 +17,26 @@ const normalizeCombination = function ({ dimensions, stats }) {
const getIdProp = function (propName, { id }) {
return [propName, { id }]
}

// Update post-reporting-normalization `result.combinations[index].stats` based
// on pre-reporting-normalization `rawResult.combinations[index].stats`.
// This assumes that the early reporting normalization logic does not change
// `result.combinations` array order, except for appending new ones.
// Done after measuring all combinations.
export const updateCombinationsStats = function (result, combinations) {
return combinations
.map(getCombinationStats)
.reduce(updateCombinationStats, result)
}

const getCombinationStats = function ({ stats }) {
return stats
}

// Same for a single combination.
// Done before each preview.
export const updateCombinationStats = function (result, stats, index) {
const combination = { ...result.combinations[index], stats }
const combinations = setArray(result.combinations, index, combination)
return { ...result, combinations }
}
26 changes: 10 additions & 16 deletions src/run/preview/results/main.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { reportPreview } from '../../../report/main.js'
import { normalizeMeasuredResult } from '../../normalize.js'
import { updateCombinationStats } from '../../normalize.js'
import {
setDescriptionIf,
START_DESCRIPTION,
Expand Down Expand Up @@ -30,7 +30,7 @@ export const updatePreviewStats = async function ({
return
}

await updateResultStats({ previewState, stats })
await updateResultStats(previewState, stats)

updateCombinationEnd({
stats,
Expand All @@ -48,18 +48,13 @@ const shouldSkipPreview = function ({ quiet }, { samples }) {
return quiet || samples === 0
}

const updateResultStats = async function ({
previewState,
previewState: { result, index },
stats,
}) {
const combinations = [
...result.combinations.slice(0, index),
{ ...result.combinations[index], stats },
...result.combinations.slice(index + 1),
]
const updateResultStats = async function (previewState, stats) {
// eslint-disable-next-line fp/no-mutation, no-param-reassign
previewState.result = { ...result, combinations }
previewState.result = updateCombinationStats(
previewState.result,
stats,
previewState.index,
)
await updateReport({ previewState })
}

Expand All @@ -79,18 +74,17 @@ export const updateReport = async function ({
noDimensions,
},
}) {
const resultA = normalizeMeasuredResult(result)
const preview = {
durationLeft,
percentage,
index: index + 1,
total,
combinationNameColor,
}
const resultB = { ...resultA, preview }
const resultA = { ...result, preview }
// eslint-disable-next-line fp/no-mutation, no-param-reassign
previewState.report = await reportPreview({
result: resultB,
result: resultA,
sinceResult,
noDimensions,
config: { reporters, titles },
Expand Down
2 changes: 2 additions & 0 deletions src/run/preview/start_end/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ const printPreviewStarting = function ({ quiet }) {

// Start the preview mode once the result has been loaded
export const startPreview = async function ({
rawResult,
result,
sinceResult,
noDimensions,
Expand All @@ -44,6 +45,7 @@ export const startPreview = async function ({

const previewStateA = addResultPreviewState({
previewState,
rawResult,
result,
sinceResult,
noDimensions,
Expand Down
3 changes: 2 additions & 1 deletion src/run/preview/start_end/state.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export const getPreviewState = function ({ reporters, titles }) {
// Add result-related properties to `previewState`
export const addResultPreviewState = function ({
previewState,
rawResult: { combinations },
result,
sinceResult,
noDimensions,
Expand All @@ -39,7 +40,7 @@ export const addResultPreviewState = function ({
result,
sinceResult,
noDimensions,
total: result.combinations.length,
total: combinations.length,
reporters: reportersA,
}
}
Expand Down
Loading

0 comments on commit 0ccf39b

Please sign in to comment.