ui: Remove the controller dispatch() layer
The existence of two different globals.ts files:
- ui/src/controller/globals.ts
- ui/src/frontent/globals.ts
is a source of confusion and, now the controller worker is no more,
completely unnecessary. We should remove ui/src/controller/globals.ts.
The first step for that is to remove the legacy dispatch() method
on controllers/globals and instead have controllers invoke the
frontent/globals version directly.
Change-Id: Iea6083f2834d4284b63c17d40b3a021892eaf707
diff --git a/ui/src/controller/globals.ts b/ui/src/controller/globals.ts
index 84564a8..5cd8f67 100644
--- a/ui/src/controller/globals.ts
+++ b/ui/src/controller/globals.ts
@@ -15,16 +15,13 @@
import {applyPatches, Patch} from 'immer';
import {assertExists} from '../base/logging';
-import {DeferredAction} from '../common/actions';
import {createEmptyState} from '../common/empty_state';
import {State} from '../common/state';
-import {globals as frontendGlobals} from '../frontend/globals';
import {ControllerAny} from './controller';
export interface App {
state: State;
- dispatch(action: DeferredAction): void;
}
/**
@@ -40,19 +37,6 @@
this._state = createEmptyState();
}
- dispatch(action: DeferredAction): void {
- frontendGlobals.dispatch(action);
- }
-
- // Send the passed dispatch actions to the frontend. The frontend logic
- // will run the actions, compute the new state and invoke patchState() so
- // our copy is updated.
- dispatchMultiple(actions: DeferredAction[]): void {
- for (const action of actions) {
- this.dispatch(action);
- }
- }
-
// This is called by the frontend logic which now owns and handle the
// source-of-truth state, to give us an update on the newer state updates.
patchState(patches: Patch[]): void {
diff --git a/ui/src/controller/metrics_controller.ts b/ui/src/controller/metrics_controller.ts
index d0e0916..7c7c9be 100644
--- a/ui/src/controller/metrics_controller.ts
+++ b/ui/src/controller/metrics_controller.ts
@@ -15,6 +15,7 @@
import {Actions} from '../common/actions';
import {Engine} from '../common/engine';
import {QueryError} from '../common/query_result';
+import {globals as frontendGlobals} from '../frontend/globals';
import {publishMetricResult} from '../frontend/publish';
import {Controller} from './controller';
@@ -48,7 +49,7 @@
throw e;
}
}
- globals.dispatch(Actions.resetMetricRequest({name}));
+ frontendGlobals.dispatch(Actions.resetMetricRequest({name}));
this.currentlyRunningMetric = undefined;
}
diff --git a/ui/src/controller/permalink_controller.ts b/ui/src/controller/permalink_controller.ts
index 349a02a..22cf3de 100644
--- a/ui/src/controller/permalink_controller.ts
+++ b/ui/src/controller/permalink_controller.ts
@@ -79,7 +79,7 @@
PermalinkController.createPermalink(isRecordingConfig)
.then((hash) => {
- globals.dispatch(Actions.setPermalink({requestId, hash}));
+ frontendGlobals.dispatch(Actions.setPermalink({requestId, hash}));
})
.finally(() => {
publishConversionJobStatusUpdate({
@@ -99,11 +99,12 @@
const validConfig =
runValidator(recordConfigValidator, stateOrConfig as unknown)
.result;
- globals.dispatch(Actions.setRecordConfig({config: validConfig}));
+ frontendGlobals.dispatch(
+ Actions.setRecordConfig({config: validConfig}));
Router.navigate('#!/record');
return;
}
- globals.dispatch(Actions.setState({newState: stateOrConfig}));
+ frontendGlobals.dispatch(Actions.setState({newState: stateOrConfig}));
this.lastRequestId = stateOrConfig.permalink.requestId;
});
}
@@ -215,7 +216,7 @@
private static updateStatus(msg: string): void {
// TODO(hjd): Unify loading updates.
- globals.dispatch(Actions.updateStatus({
+ frontendGlobals.dispatch(Actions.updateStatus({
msg,
timestamp: Date.now() / 1000,
}));
diff --git a/ui/src/controller/pivot_table_redux_controller.ts b/ui/src/controller/pivot_table_redux_controller.ts
index 4f57891..8658822 100644
--- a/ui/src/controller/pivot_table_redux_controller.ts
+++ b/ui/src/controller/pivot_table_redux_controller.ts
@@ -26,6 +26,7 @@
PivotTableReduxResult,
PivotTableReduxState,
} from '../common/state';
+import {globals as frontendGlobals} from '../frontend/globals';
import {
aggregationIndex,
generateQueryFromState,
@@ -219,7 +220,7 @@
if (!it.valid()) {
// Iterator is invalid after creation; means that there are no rows
// satisfying filtering criteria. Return an empty tree.
- globals.dispatch(Actions.setPivotStateQueryResult(
+ frontendGlobals.dispatch(Actions.setPivotStateQueryResult(
{queryResult: createEmptyQueryResult(query.metadata)}));
return;
}
@@ -232,9 +233,9 @@
treeBuilder.ingestRow(nextRow());
}
- globals.dispatch(Actions.setPivotStateQueryResult(
+ frontendGlobals.dispatch(Actions.setPivotStateQueryResult(
{queryResult: {tree: treeBuilder.build(), metadata: query.metadata}}));
- globals.dispatch(Actions.setCurrentTab({tab: 'pivot_table_redux'}));
+ frontendGlobals.dispatch(Actions.setCurrentTab({tab: 'pivot_table_redux'}));
}
async requestArgumentNames() {
@@ -250,7 +251,8 @@
it.next();
}
- globals.dispatch(Actions.setPivotTableArgumentNames({argumentNames}));
+ frontendGlobals.dispatch(
+ Actions.setPivotTableArgumentNames({argumentNames}));
}
@@ -269,17 +271,18 @@
if (pivotTableState.queryRequested ||
(selection !== null && selection.kind === 'AREA' &&
this.shouldRerun(pivotTableState, selection))) {
- globals.dispatch(
+ frontendGlobals.dispatch(
Actions.setPivotTableQueryRequested({queryRequested: false}));
// Need to re-run the existing query, clear the current result.
- globals.dispatch(Actions.setPivotStateQueryResult({queryResult: null}));
+ frontendGlobals.dispatch(
+ Actions.setPivotStateQueryResult({queryResult: null}));
this.processQuery(generateQueryFromState(pivotTableState));
}
if (selection !== null && selection.kind === 'AREA' &&
(pivotTableState.selectionArea === undefined ||
pivotTableState.selectionArea.areaId !== selection.areaId)) {
- globals.dispatch(
+ frontendGlobals.dispatch(
Actions.togglePivotTableRedux({areaId: selection.areaId}));
}
}
diff --git a/ui/src/controller/query_controller.ts b/ui/src/controller/query_controller.ts
index 4e9017f..3a896d8 100644
--- a/ui/src/controller/query_controller.ts
+++ b/ui/src/controller/query_controller.ts
@@ -16,6 +16,7 @@
import {Actions} from '../common/actions';
import {Engine} from '../common/engine';
import {runQuery} from '../common/queries';
+import {globals as frontendGlobals} from '../frontend/globals';
import {publishQueryResult} from '../frontend/publish';
import {Controller} from './controller';
@@ -39,7 +40,7 @@
.then((result) => {
console.log(`Query ${config.query} took ${result.durationMs} ms`);
publishQueryResult({id: this.args.queryId, data: result});
- globals.dispatch(
+ frontendGlobals.dispatch(
Actions.deleteQuery({queryId: this.args.queryId}));
});
this.setState('querying');
diff --git a/ui/src/controller/record_controller.ts b/ui/src/controller/record_controller.ts
index aef43ab..3ce567e 100644
--- a/ui/src/controller/record_controller.ts
+++ b/ui/src/controller/record_controller.ts
@@ -29,6 +29,7 @@
isChromeTarget,
RecordingTarget,
} from '../common/state';
+import {globals as frontendGlobals} from '../frontend/globals';
import {publishBufferUsage, publishTrackData} from '../frontend/publish';
import {AdbOverWebUsb} from './adb';
@@ -208,7 +209,8 @@
if (this.app.state.extensionInstalled) {
this.extensionPort.postMessage({method: 'GetCategories'});
}
- globals.dispatch(Actions.setFetchChromeCategories({fetch: false}));
+ frontendGlobals.dispatch(
+ Actions.setFetchChromeCategories({fetch: false}));
}
if (this.app.state.recordConfig === this.config &&
this.app.state.recordingInProgress === this.recordingInProgress) {
@@ -302,15 +304,15 @@
onTraceComplete() {
this.consumerPort.freeBuffers({});
- globals.dispatch(Actions.setRecordingStatus({status: undefined}));
+ frontendGlobals.dispatch(Actions.setRecordingStatus({status: undefined}));
if (globals.state.recordingCancelled) {
- globals.dispatch(
+ frontendGlobals.dispatch(
Actions.setLastRecordingError({error: 'Recording cancelled.'}));
this.traceBuffer = [];
return;
}
const trace = this.generateTrace();
- globals.dispatch(Actions.openTraceFromBuffer({
+ frontendGlobals.dispatch(Actions.openTraceFromBuffer({
title: 'Recorded trace',
buffer: trace.buffer,
fileName: `recorded_trace${this.recordedTraceSuffix}`,
@@ -346,13 +348,13 @@
onError(message: string) {
// TODO(octaviant): b/204998302
console.error('Error in record controller: ', message);
- globals.dispatch(
+ frontendGlobals.dispatch(
Actions.setLastRecordingError({error: message.substr(0, 150)}));
- globals.dispatch(Actions.stopRecording({}));
+ frontendGlobals.dispatch(Actions.stopRecording({}));
}
onStatus(message: string) {
- globals.dispatch(Actions.setRecordingStatus({status: message}));
+ frontendGlobals.dispatch(Actions.setRecordingStatus({status: message}));
}
// Depending on the recording target, different implementation of the
diff --git a/ui/src/controller/trace_controller.ts b/ui/src/controller/trace_controller.ts
index dd62689..a6c8771 100644
--- a/ui/src/controller/trace_controller.ts
+++ b/ui/src/controller/trace_controller.ts
@@ -206,17 +206,17 @@
switch (this.state) {
case 'init':
this.loadTrace()
- .then((mode) => {
- globals.dispatch(Actions.setEngineReady({
- engineId: this.engineId,
- ready: true,
- mode,
- }));
- })
- .catch((err) => {
- this.updateStatus(`${err}`);
- throw err;
- });
+ .then((mode) => {
+ frontendGlobals.dispatch(Actions.setEngineReady({
+ engineId: this.engineId,
+ ready: true,
+ mode,
+ }));
+ })
+ .catch((err) => {
+ this.updateStatus(`${err}`);
+ throw err;
+ });
this.updateStatus('Opening trace');
this.setState('loading_trace');
break;
@@ -349,8 +349,8 @@
engineMode = 'HTTP_RPC';
engine = new HttpRpcEngine(this.engineId, LoadingManager.getInstance);
engine.errorHandler = (err) => {
- globals.dispatch(
- Actions.setEngineFailed({mode: 'HTTP_RPC', failure: `${err}`}));
+ frontendGlobals.dispatch(
+ Actions.setEngineFailed({mode: 'HTTP_RPC', failure: `${err}`}));
throw err;
};
} else {
@@ -375,7 +375,7 @@
new BottomTabList(engine.getProxy('BottomTabList'));
frontendGlobals.engines.set(this.engineId, engine);
- globals.dispatch(Actions.setEngineReady({
+ frontendGlobals.dispatch(Actions.setEngineReady({
engineId: this.engineId,
ready: false,
mode: engineMode,
@@ -476,7 +476,7 @@
resolution,
}));
- globals.dispatchMultiple(actions);
+ frontendGlobals.dispatchMultiple(actions);
Router.navigate(`#!/viewer?local_cache_key=${traceUuid}`);
// Make sure the helper views are available before we start adding tracks.
@@ -510,9 +510,9 @@
publishHasFtrace(hasFtrace);
}
- globals.dispatch(Actions.removeDebugTrack({}));
- globals.dispatch(Actions.sortThreadTracks({}));
- globals.dispatch(Actions.maybeExpandOnlyTrackGroup({}));
+ frontendGlobals.dispatch(Actions.removeDebugTrack({}));
+ frontendGlobals.dispatch(Actions.sortThreadTracks({}));
+ frontendGlobals.dispatch(Actions.maybeExpandOnlyTrackGroup({}));
await this.selectFirstHeapProfile();
if (PERF_SAMPLE_FLAG.get()) {
@@ -531,7 +531,7 @@
if (!isJsonTrace && ENABLE_CHROME_RELIABLE_RANGE_ANNOTATION_FLAG.get()) {
const reliableRangeStart = await computeTraceReliableRangeStart(engine);
if (reliableRangeStart > 0) {
- globals.dispatch(Actions.addAutomaticNote({
+ frontendGlobals.dispatch(Actions.addAutomaticNote({
timestamp: reliableRangeStart,
color: '#ff0000',
text: 'Reliable Range Start',
@@ -554,8 +554,8 @@
const upid = row.upid;
const leftTs = toNs(globals.state.traceTime.startSec);
const rightTs = toNs(globals.state.traceTime.endSec);
- globals.dispatch(Actions.selectPerfSamples(
- {id: 0, upid, leftTs, rightTs, type: ProfileType.PERF_SAMPLE}));
+ frontendGlobals.dispatch(Actions.selectPerfSamples(
+ {id: 0, upid, leftTs, rightTs, type: ProfileType.PERF_SAMPLE}));
}
private async selectFirstHeapProfile() {
@@ -576,14 +576,15 @@
const ts = row.ts;
const type = profileType(row.type);
const upid = row.upid;
- globals.dispatch(Actions.selectHeapProfile({id: 0, upid, ts, type}));
+ frontendGlobals.dispatch(
+ Actions.selectHeapProfile({id: 0, upid, ts, type}));
}
private async listTracks() {
this.updateStatus('Loading tracks');
const engine = assertExists<Engine>(this.engine);
const actions = await decideTracks(this.engineId, engine);
- globals.dispatchMultiple(actions);
+ frontendGlobals.dispatchMultiple(actions);
}
private async listThreads() {
@@ -776,7 +777,7 @@
for (const it = metricsResult.iter({name: STR}); it.valid(); it.next()) {
availableMetrics.push(it.name);
}
- globals.dispatch(Actions.setAvailableMetrics({availableMetrics}));
+ frontendGlobals.dispatch(Actions.setAvailableMetrics({availableMetrics}));
const availableMetricsSet = new Set<string>(availableMetrics);
for (const [flag, metric] of FLAGGED_METRICS) {
@@ -895,7 +896,7 @@
}
private updateStatus(msg: string): void {
- globals.dispatch(Actions.updateStatus({
+ frontendGlobals.dispatch(Actions.updateStatus({
msg,
timestamp: Date.now() / 1000,
}));
diff --git a/ui/src/controller/visualised_args_controller.ts b/ui/src/controller/visualised_args_controller.ts
index 9ac6d3d..ec1d67c 100644
--- a/ui/src/controller/visualised_args_controller.ts
+++ b/ui/src/controller/visualised_args_controller.ts
@@ -18,6 +18,7 @@
import {Engine} from '../common/engine';
import {NUM} from '../common/query_result';
import {InThreadTrackSortKey} from '../common/state';
+import {globals as frontendGlobals} from '../frontend/globals';
import {
VISUALISED_ARGS_SLICE_TRACK_KIND,
} from '../tracks/visualised_args/index';
@@ -48,7 +49,7 @@
onDestroy() {
this.engine.query(`drop table if exists ${this.tableName}`);
- globals.dispatch(
+ frontendGlobals.dispatch(
Actions.removeVisualisedArgTracks({trackIds: this.addedTrackIds}));
}
@@ -113,8 +114,8 @@
},
});
}
- globals.dispatch(Actions.addTracks({tracks: tracksToAdd}));
- globals.dispatch(Actions.sortThreadTracks({}));
+ frontendGlobals.dispatch(Actions.addTracks({tracks: tracksToAdd}));
+ frontendGlobals.dispatch(Actions.sortThreadTracks({}));
}
run() {
diff --git a/ui/src/frontend/globals.ts b/ui/src/frontend/globals.ts
index 5b8728a..0e5de55 100644
--- a/ui/src/frontend/globals.ts
+++ b/ui/src/frontend/globals.ts
@@ -293,6 +293,13 @@
return assertExists(this._dispatch);
}
+ dispatchMultiple(actions: DeferredAction[]): void {
+ const dispatch = this.dispatch;
+ for (const action of actions) {
+ dispatch(action);
+ }
+ }
+
get frontendLocalState() {
return assertExists(this._frontendLocalState);
}