Skip to content

Commit 801d1e3

Browse files
Profiler Teamcopybara-github
Profiler Team
authored andcommitted
Creates new data service for Angular frontend with DataServiceInterface
PiperOrigin-RevId: 720673081
1 parent 3fe152b commit 801d1e3

File tree

7 files changed

+2116
-2
lines changed

7 files changed

+2116
-2
lines changed

frontend/app/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ xprof_ng_module(
2828
"@org_xprof//frontend/app/pipes",
2929
"@org_xprof//frontend/app/services/data_dispatcher",
3030
"@org_xprof//frontend/app/services/data_service",
31+
"@org_xprof//frontend/app/services/data_service:data_service_interface",
3132
"@org_xprof//frontend/app/store",
3233
],
3334
)

frontend/app/app_module.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {MainPageModule} from 'org_xprof/frontend/app/components/main_page/main_p
88
import {PipesModule} from 'org_xprof/frontend/app/pipes/pipes_module';
99
import {DataDispatcher} from 'org_xprof/frontend/app/services/data_dispatcher/data_dispatcher';
1010
import {DataService} from 'org_xprof/frontend/app/services/data_service/data_service';
11+
import {DataServiceInterface} from 'org_xprof/frontend/app/services/data_service/data_service_interface';
1112
import {RootStoreModule} from 'org_xprof/frontend/app/store/store_module';
1213

1314
import {App} from './app';
@@ -28,6 +29,7 @@ import {App} from './app';
2829
providers: [
2930
DataDispatcher,
3031
DataService,
32+
DataServiceInterface,
3133
],
3234
bootstrap: [App],
3335
})

frontend/app/components/memory_profile/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ xprof_ng_module(
2929
"@org_xprof//frontend/app/components/memory_profile/memory_profile_summary",
3030
"@org_xprof//frontend/app/components/memory_profile/memory_timeline_graph",
3131
"@org_xprof//frontend/app/services/data_service",
32+
"@org_xprof//frontend/app/services/data_service:data_service_interface",
3233
"@org_xprof//frontend/app/store",
3334
],
3435
)

frontend/app/components/memory_profile/memory_profile.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {Store} from '@ngrx/store';
44
import {MemoryProfileProto} from 'org_xprof/frontend/app/common/interfaces/data_table';
55
import {NavigationEvent} from 'org_xprof/frontend/app/common/interfaces/navigation_event';
66
import {MemoryProfileBase} from 'org_xprof/frontend/app/components/memory_profile/memory_profile_base';
7-
import {DataService} from 'org_xprof/frontend/app/services/data_service/data_service';
7+
import {DataServiceInterface} from 'org_xprof/frontend/app/services/data_service/data_service_interface';
88
import {setLoadingStateAction} from 'org_xprof/frontend/app/store/actions';
99
import {ReplaySubject} from 'rxjs';
1010
import {takeUntil} from 'rxjs/operators';
@@ -25,7 +25,7 @@ export class MemoryProfile extends MemoryProfileBase implements OnDestroy {
2525
host = '';
2626

2727
constructor(
28-
route: ActivatedRoute, private readonly dataService: DataService,
28+
route: ActivatedRoute, private readonly dataService: DataServiceInterface,
2929
private readonly store: Store<{}>) {
3030
super();
3131
route.params.pipe(takeUntil(this.destroyed)).subscribe((params) => {

frontend/app/services/data_service/BUILD

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,20 @@ xprof_ng_module(
1717
"@org_xprof//frontend/app/common/interfaces",
1818
],
1919
)
20+
21+
xprof_ng_module(
22+
name = "data_service_interface",
23+
srcs = [
24+
"data_service_interface.ts",
25+
"mock_interface_data.ts",
26+
],
27+
deps = [
28+
"//third_party/javascript/safevalues/dom",
29+
"@npm//@angular/common",
30+
"@npm//@angular/core",
31+
"@npm//rxjs",
32+
"@org_xprof//frontend/app/common/angular:angular_common_http",
33+
"@org_xprof//frontend/app/common/constants",
34+
"@org_xprof//frontend/app/common/interfaces",
35+
],
36+
)
Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
/**
2+
* @fileoverview Data service interface meant to replace and consolidate
3+
* 1P/3P data services in the xprof frontend.
4+
*/
5+
6+
import {PlatformLocation} from '@angular/common';
7+
import {HttpClient, HttpParams} from '@angular/common/http';
8+
import {Injectable} from '@angular/core';
9+
// import {TOOL_PARAMS_TO_KEEP} from
10+
// 'google3/perftools/accelerators/xprof/frontend/app/common/constants/constants';
11+
import {CaptureProfileOptions, CaptureProfileResponse} from 'org_xprof/frontend/app/common/interfaces/capture_profile';
12+
import {DataTable} from 'org_xprof/frontend/app/common/interfaces/data_table';
13+
import {HostMetadata} from 'org_xprof/frontend/app/common/interfaces/hosts';
14+
import {Observable, of} from 'rxjs';
15+
import {delay} from 'rxjs/operators';
16+
import {windowOpen} from 'safevalues/dom';
17+
18+
import * as mockData from './mock_interface_data';
19+
20+
/** Delay time for millisecond for testing */
21+
const DELAY_TIME_MS = 1000;
22+
import {API_PREFIX, CAPTURE_PROFILE_API, DATA_API, HOSTS_API, LOCAL_URL, PLUGIN_NAME, RUN_TOOLS_API, RUNS_API} from 'org_xprof/frontend/app/common/constants/constants';
23+
24+
/** The data service class that calls API and return response. */
25+
@Injectable()
26+
export class DataServiceInterface {
27+
searchParams?: URLSearchParams;
28+
dataParams?: HttpParams;
29+
isLocalOssDevelopment = false;
30+
pathPrefix = '';
31+
toolname = '';
32+
33+
constructor(
34+
protected readonly httpClient: HttpClient,
35+
platformLocation: PlatformLocation) {
36+
this.isLocalOssDevelopment = platformLocation.pathname === LOCAL_URL;
37+
if (String(platformLocation.pathname).includes(API_PREFIX + PLUGIN_NAME)) {
38+
this.pathPrefix =
39+
String(platformLocation.pathname).split(API_PREFIX + PLUGIN_NAME)[0];
40+
}
41+
this.searchParams = new URLSearchParams(window.location.search);
42+
}
43+
44+
// tslint:disable-next-line:no-any
45+
protected get<T>(
46+
url: string,
47+
// tslint:disable-next-line:no-any
48+
options: {[key: string]: any},
49+
notifyError = true,
50+
): Observable<T|null> {
51+
return this.httpClient.get<T>(url, options);
52+
}
53+
54+
getData(
55+
run: string, tool: string, host?: string,
56+
parameters?: Map<string, string>,
57+
ignoreError?: boolean): Observable<DataTable|null> {
58+
console.log('getData', run, tool, host, parameters, ignoreError);
59+
if (this.isLocalOssDevelopment) {
60+
if (tool.startsWith('overview_page')) {
61+
return of(mockData.DATA_PLUGIN_PROFILE_OVERVIEW_PAGE_DATA)
62+
.pipe(delay(DELAY_TIME_MS));
63+
} else if (tool.startsWith('input_pipeline_analyzer')) {
64+
return of(mockData.DATA_PLUGIN_PROFILE_INPUT_PIPELINE_DATA)
65+
.pipe(delay(DELAY_TIME_MS));
66+
} else if (tool.startsWith('tensorflow_stats')) {
67+
return of(mockData.DATA_PLUGIN_PROFILE_TENSORFLOW_STATS_DATA)
68+
.pipe(delay(DELAY_TIME_MS));
69+
} else if (tool.startsWith('memory_viewer')) {
70+
return of(mockData.DATA_PLUGIN_PROFILE_MEMORY_VIEWER_DATA)
71+
.pipe(delay(DELAY_TIME_MS));
72+
} else if (tool.startsWith('op_profile')) {
73+
return of(mockData.DATA_PLUGIN_PROFILE_OP_PROFILE_DATA)
74+
.pipe(delay(DELAY_TIME_MS));
75+
} else if (tool.startsWith('pod_viewer')) {
76+
return of(mockData.DATA_PLUGIN_PROFILE_POD_VIEWER_DATA)
77+
.pipe(delay(DELAY_TIME_MS));
78+
} else if (tool.startsWith('kernel_stats')) {
79+
return of(mockData.DATA_PLUGIN_PROFILE_KERNEL_STATS_DATA)
80+
.pipe(delay(DELAY_TIME_MS));
81+
} else if (tool.startsWith('memory_profile')) {
82+
console.log('tool: ', tool);
83+
return of(mockData.DATA_PLUGIN_PROFILE_MEMORY_PROFILE_DATA)
84+
.pipe(delay(DELAY_TIME_MS));
85+
} else if (tool.startsWith('tf_data_bottleneck_analysis')) {
86+
return of(mockData.DATA_PLUGIN_PROFILE_TF_DATA_BOTTLENECK_ANALYSIS_DATA)
87+
.pipe(delay(DELAY_TIME_MS));
88+
} else {
89+
return of([]).pipe(delay(DELAY_TIME_MS));
90+
}
91+
}
92+
this.setInitialHttpParams();
93+
this.dataParams = this.dataParams!.set('run', run).set('tool', tool);
94+
if (host) {
95+
this.dataParams = this.dataParams.set('host', host);
96+
}
97+
this.toolname = tool;
98+
return this.get(this.getDataPath(), this.getParams(), true) as
99+
Observable<DataTable>;
100+
}
101+
getHosts(run: string): Observable<HostMetadata[]> {
102+
if (this.isLocalOssDevelopment) {
103+
return of(mockData.DATA_PLUGIN_PROFILE_HOSTS).pipe(delay(DELAY_TIME_MS));
104+
}
105+
this.setInitialHttpParams();
106+
this.dataParams =
107+
this.dataParams!.set('run', run).set('tool', this.toolname);
108+
return this.get(this.getHostsPath(), this.getParams(), true) as
109+
Observable<HostMetadata[]>;
110+
}
111+
getTools(run?: string): Observable<string[]> {
112+
if (this.isLocalOssDevelopment) {
113+
return of(mockData.DATA_PLUGIN_PROFILE_RUN_TOOLS);
114+
}
115+
this.setInitialHttpParams();
116+
if (run && run !== '') {
117+
this.dataParams = this.dataParams!.set('run', run);
118+
}
119+
return this.get(this.getToolsPath(), this.getParams(), true) as
120+
Observable<string[]>;
121+
}
122+
getModuleList(run: string): Observable<string> {
123+
this.setInitialHttpParams();
124+
this.dataParams = this.dataParams!.set('run', run);
125+
return this.get(
126+
this.getDataPath(), {
127+
'params': this.dataParams,
128+
'responseType': 'text',
129+
},
130+
true) as Observable<string>;
131+
}
132+
133+
// Helper functions
134+
// makeToolQuery(pathname: string, params: Map<string, string>): string {
135+
// const toolParams = new URLSearchParams();
136+
// const parts = pathname.split('/').filter((i) => i);
137+
// if (parts.length === 0 || !TOOL_PARAMS_TO_KEEP[parts[0]]) return
138+
// pathname; for (const allowedParam of TOOL_PARAMS_TO_KEEP[parts[0]]) {
139+
// if (params.has(allowedParam)) {
140+
// const val = params.get(allowedParam) || '';
141+
// toolParams.set(allowedParam, val);
142+
// }
143+
// }
144+
// return pathname + '?' + toolParams.toString();
145+
// }
146+
setInitialHttpParams() {
147+
this.dataParams = new HttpParams();
148+
}
149+
150+
getDataPath(): string {
151+
return this.pathPrefix + DATA_API;
152+
}
153+
154+
getHostsPath(): string {
155+
return this.pathPrefix + HOSTS_API;
156+
}
157+
158+
getToolsPath(): string {
159+
return this.pathPrefix + RUN_TOOLS_API;
160+
}
161+
162+
// tslint:disable-next-line:no-any
163+
getParams(): {[key: string]: any} {
164+
const params = this.dataParams;
165+
// tslint:disable-next-line:no-any
166+
return {params} as {[key: string]: any};
167+
}
168+
169+
170+
171+
captureProfile(options: CaptureProfileOptions):
172+
Observable<CaptureProfileResponse> {
173+
if (this.isLocalOssDevelopment) {
174+
return of({result: 'Done'});
175+
}
176+
this.setInitialHttpParams();
177+
this.dataParams =
178+
this.dataParams!.set('service_addr', options.serviceAddr)
179+
.set('is_tpu_name', options.isTpuName.toString())
180+
.set('duration', options.duration.toString())
181+
.set('num_retry', options.numRetry.toString())
182+
.set('worker_list', options.workerList)
183+
.set('host_tracer_level', options.hostTracerLevel.toString())
184+
.set('device_tracer_level', options.deviceTracerLevel.toString())
185+
.set('python_tracer_level', options.pythonTracerLevel.toString())
186+
.set('delay', options.delay.toString());
187+
return this.get(
188+
this.pathPrefix + CAPTURE_PROFILE_API, this.getParams(), true) as
189+
Observable<CaptureProfileResponse>;
190+
}
191+
192+
getRuns() {
193+
if (this.isLocalOssDevelopment) {
194+
return of(mockData.DATA_PLUGIN_PROFILE_RUNS);
195+
}
196+
this.setInitialHttpParams();
197+
return this.get(this.pathPrefix + RUNS_API, this.getParams(), true) as
198+
Observable<CaptureProfileResponse>;
199+
}
200+
201+
getRunTools(run: string) {
202+
if (this.isLocalOssDevelopment) {
203+
return of(mockData.DATA_PLUGIN_PROFILE_RUN_TOOLS);
204+
}
205+
this.setInitialHttpParams();
206+
this.dataParams = this.dataParams!.set('run', run);
207+
return this.get(this.pathPrefix + RUN_TOOLS_API, this.getParams(), true) as
208+
Observable<CaptureProfileResponse>;
209+
}
210+
211+
exportDataAsCSV(run: string, tool: string, host: string) {
212+
this.setInitialHttpParams();
213+
this.dataParams = this.dataParams!.set('run', run)
214+
.set('tool', tool)
215+
.set('host', host)
216+
.set('tqx', 'out:csv;');
217+
windowOpen(
218+
window, this.pathPrefix + DATA_API + '?' + this.dataParams.toString(),
219+
'_blank');
220+
}
221+
}

0 commit comments

Comments
 (0)