MickJ commited on
Commit
3864f2f
·
0 Parent(s):

init: upload perfetto_relay.html

Browse files
Files changed (2) hide show
  1. README.md +2 -0
  2. pages/perfetto_relay.html +150 -0
README.md ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ Storage Repo for Nightly ci of SGLang
2
+
pages/perfetto_relay.html ADDED
@@ -0,0 +1,150 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>Perfetto Trace Relay</title>
6
+ <style>
7
+ body { font-family: sans-serif; padding: 2em; }
8
+ </style>
9
+ </head>
10
+ <body>
11
+ <h1>Perfetto Trace Relay</h1>
12
+ <p id="status">Initializing...</p>
13
+
14
+ <script>
15
+ (async () => {
16
+ const statusElement = document.getElementById('status');
17
+ const PERFETTO_UI_URL = 'https://ui.perfetto.dev';
18
+
19
+ /**
20
+ * Displays a final message on the relay page itself.
21
+ * @param {string} message The message to display.
22
+ * @param {boolean} isError If true, display as an error.
23
+ */
24
+ const setStatus = (message, isError = false) => {
25
+ console.log(message);
26
+ statusElement.textContent = message;
27
+ if (isError) {
28
+ statusElement.style.color = 'red';
29
+ console.error(message);
30
+ }
31
+ };
32
+
33
+ /**
34
+ * Establishes a handshake with the Perfetto UI window to ensure it's ready.
35
+ * The Perfetto UI will respond with 'PONG' when it receives a 'PING'.
36
+ * @param {Window} ui The window handle for the Perfetto UI.
37
+ * @returns {Promise<void>} A promise that resolves when the handshake is complete.
38
+ */
39
+ const establishHandshake = (ui) => {
40
+ return new Promise((resolve, reject) => {
41
+ let intervalId = null;
42
+ let timeoutId = null;
43
+
44
+ const cleanup = () => {
45
+ clearInterval(intervalId);
46
+ clearTimeout(timeoutId);
47
+ window.removeEventListener('message', messageHandler);
48
+ };
49
+
50
+ const messageHandler = (event) => {
51
+ if (event.source === ui && event.data === 'PONG') {
52
+ cleanup();
53
+ resolve();
54
+ }
55
+ };
56
+
57
+ window.addEventListener('message', messageHandler);
58
+
59
+ // 1. Start pinging the UI
60
+ intervalId = setInterval(() => {
61
+ // The try-catch is necessary because the UI window might be closed by the user.
62
+ try {
63
+ ui.postMessage('PING', PERFETTO_UI_URL);
64
+ } catch (e) {
65
+ // If postMessage fails, it's likely the window was closed.
66
+ cleanup();
67
+ reject(new Error('Perfetto UI window was closed before handshake could complete.'));
68
+ }
69
+ }, 200);
70
+
71
+ // 2. Set a timeout for the handshake
72
+ timeoutId = setTimeout(() => {
73
+ cleanup();
74
+ reject(new Error('Handshake with Perfetto UI timed out. The UI might not have loaded correctly.'));
75
+ }, 10000); // 10-second timeout
76
+ });
77
+ };
78
+
79
+ /**
80
+ * Fetches the trace file and posts it to the Perfetto UI.
81
+ * @param {Window} ui The window handle for the Perfetto UI.
82
+ * @param {string} srcUrl The URL of the trace file to fetch.
83
+ * @param {string | null} customTitle An optional title for the trace.
84
+ */
85
+ const fetchTraceAndPost = async (ui, srcUrl, customTitle) => {
86
+ // This fetch is executed on your domain, so it can handle auth/CORS/ACLs.
87
+ const response = await fetch(srcUrl, {
88
+ mode: 'cors',
89
+ credentials: 'omit', // Avoids "ACAO: * + credentials" error.
90
+ cache: 'no-store', // Ensures the latest trace is always fetched.
91
+ });
92
+
93
+ if (!response.ok) {
94
+ const errorMsg = `Failed to load trace: ${response.status} ${response.statusText}`;
95
+ ui.postMessage({ perfetto: { title: errorMsg } }, PERFETTO_UI_URL);
96
+ throw new Error(errorMsg);
97
+ }
98
+
99
+ const buffer = await response.arrayBuffer();
100
+
101
+ // Determine a sensible title and filename for the trace.
102
+ const title = customTitle || srcUrl.split('/').pop() || 'trace';
103
+ const fileName = title.endsWith('.gz') || title.endsWith('.zip') ? title : `${title}.perfetto-trace`;
104
+
105
+ // Post the trace buffer to the Perfetto UI.
106
+ ui.postMessage({
107
+ perfetto: {
108
+ buffer,
109
+ title,
110
+ fileName,
111
+ // Keep the UI open after loading, useful for debugging.
112
+ keepApiOpen: true,
113
+ }
114
+ }, PERFETTO_UI_URL, [buffer]); // Transfer the buffer for performance.
115
+ };
116
+
117
+
118
+ // --- Main Execution Logic ---
119
+ try {
120
+ const params = new URLSearchParams(location.search);
121
+ const src = params.get('src');
122
+ const title = params.get('title');
123
+
124
+ if (!src) {
125
+ throw new Error('Required "src" URL parameter is missing.');
126
+ }
127
+
128
+ setStatus('Opening Perfetto UI...');
129
+ const ui = window.open(PERFETTO_UI_URL);
130
+ if (!ui) {
131
+ throw new Error('Failed to open Perfetto UI. Please disable your popup blocker for this site.');
132
+ }
133
+
134
+ setStatus('Waiting for handshake with Perfetto UI...');
135
+ await establishHandshake(ui);
136
+
137
+ setStatus(`Fetching trace from ${src}...`);
138
+ await fetchTraceAndPost(ui, src, title);
139
+
140
+ setStatus('Trace successfully sent to Perfetto UI. You can now close this tab.');
141
+ // Optionally, close the relay window automatically.
142
+ // window.close();
143
+
144
+ } catch (error) {
145
+ setStatus(error.message, true);
146
+ }
147
+ })();
148
+ </script>
149
+ </body>
150
+ </html>