viztracer 1.0.4__cp311-cp311-macosx_11_0_arm64.whl → 1.1.0__cp311-cp311-macosx_11_0_arm64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of viztracer might be problematic. Click here for more details.
- viztracer/__init__.py +1 -1
- viztracer/code_monkey.py +10 -13
- viztracer/decorator.py +9 -12
- viztracer/event_base.py +2 -2
- viztracer/functree.py +7 -7
- viztracer/main.py +9 -13
- viztracer/modules/snaptrace.c +14 -12
- viztracer/modules/util.c +1 -5
- viztracer/modules/vcompressor/vc_dump.c +4 -24
- viztracer/modules/vcompressor/vcompressor.c +13 -13
- viztracer/patch.py +10 -6
- viztracer/report_builder.py +8 -8
- viztracer/snaptrace.cpython-311-darwin.so +0 -0
- viztracer/snaptrace.pyi +8 -8
- viztracer/util.py +1 -2
- viztracer/vcompressor.cpython-311-darwin.so +0 -0
- viztracer/viewer.py +5 -5
- viztracer/vizlogging.py +1 -2
- viztracer/vizplugin.py +3 -3
- viztracer/viztracer.py +16 -16
- viztracer/web_dist/index.html +1 -1
- viztracer/web_dist/service_worker.js +103 -1
- viztracer/web_dist/trace_processor +32 -31
- viztracer/web_dist/v52.0-6b9586def/assets/MaterialSymbolsOutlined.woff2 +0 -0
- viztracer/web_dist/v52.0-6b9586def/engine_bundle.js +3 -0
- viztracer/web_dist/v52.0-6b9586def/frontend_bundle.js +5495 -0
- viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/manifest.json +10 -8
- viztracer/web_dist/v52.0-6b9586def/perfetto.css +5737 -0
- viztracer/web_dist/v52.0-6b9586def/stdlib_docs.json +1 -0
- viztracer/web_dist/v52.0-6b9586def/trace_config_utils.wasm +0 -0
- viztracer/web_dist/{v47.0-02b2414d5/traceconv.wasm → v52.0-6b9586def/trace_processor.wasm} +0 -0
- viztracer/web_dist/v52.0-6b9586def/trace_processor_memory64.wasm +0 -0
- viztracer/web_dist/{v47.0-02b2414d5/trace_processor.wasm → v52.0-6b9586def/traceconv.wasm} +0 -0
- viztracer/web_dist/v52.0-6b9586def/traceconv_bundle.js +2 -0
- viztracer-1.1.0.dist-info/METADATA +316 -0
- viztracer-1.1.0.dist-info/RECORD +106 -0
- {viztracer-1.0.4.dist-info → viztracer-1.1.0.dist-info}/WHEEL +1 -1
- viztracer/web_dist/v47.0-02b2414d5/assets/._MaterialSymbolsOutlined.woff2 +0 -0
- viztracer/web_dist/v47.0-02b2414d5/assets/MaterialSymbolsOutlined.woff2 +0 -0
- viztracer/web_dist/v47.0-02b2414d5/engine_bundle.js +0 -3
- viztracer/web_dist/v47.0-02b2414d5/frontend_bundle.js +0 -4994
- viztracer/web_dist/v47.0-02b2414d5/perfetto.css +0 -5133
- viztracer/web_dist/v47.0-02b2414d5/traceconv_bundle.js +0 -2
- viztracer-1.0.4.dist-info/METADATA +0 -537
- viztracer-1.0.4.dist-info/RECORD +0 -104
- /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/Roboto-100.woff2 +0 -0
- /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/Roboto-300.woff2 +0 -0
- /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/Roboto-400.woff2 +0 -0
- /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/Roboto-500.woff2 +0 -0
- /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/RobotoCondensed-Light.woff2 +0 -0
- /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/RobotoCondensed-Regular.woff2 +0 -0
- /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/RobotoMono-Regular.woff2 +0 -0
- /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/brand.png +0 -0
- /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/catapult_trace_viewer.html +0 -0
- /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/catapult_trace_viewer.js +0 -0
- /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/favicon.png +0 -0
- /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/logo-128.png +0 -0
- /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/logo-3d.png +0 -0
- /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/rec_atrace.png +0 -0
- /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/rec_battery_counters.png +0 -0
- /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/rec_board_voltage.png +0 -0
- /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/rec_cpu_coarse.png +0 -0
- /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/rec_cpu_fine.png +0 -0
- /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/rec_cpu_freq.png +0 -0
- /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/rec_cpu_voltage.png +0 -0
- /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/rec_frame_timeline.png +0 -0
- /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/rec_ftrace.png +0 -0
- /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/rec_gpu_mem_total.png +0 -0
- /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/rec_java_heap_dump.png +0 -0
- /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/rec_lmk.png +0 -0
- /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/rec_logcat.png +0 -0
- /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/rec_long_trace.png +0 -0
- /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/rec_mem_hifreq.png +0 -0
- /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/rec_meminfo.png +0 -0
- /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/rec_native_heap_profiler.png +0 -0
- /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/rec_one_shot.png +0 -0
- /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/rec_profiling.png +0 -0
- /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/rec_ps_stats.png +0 -0
- /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/rec_ring_buf.png +0 -0
- /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/rec_syscalls.png +0 -0
- /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/rec_vmstat.png +0 -0
- /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/scheduling_latency.png +0 -0
- /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/vscode-icon.png +0 -0
- /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/index.html +0 -0
- {viztracer-1.0.4.dist-info → viztracer-1.1.0.dist-info}/entry_points.txt +0 -0
- {viztracer-1.0.4.dist-info → viztracer-1.1.0.dist-info}/licenses/LICENSE +0 -0
- {viztracer-1.0.4.dist-info → viztracer-1.1.0.dist-info}/licenses/NOTICE.txt +0 -0
- {viztracer-1.0.4.dist-info → viztracer-1.1.0.dist-info}/top_level.txt +0 -0
viztracer/snaptrace.pyi
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
# For details: https://github.com/gaogaotiantian/viztracer/blob/master/NOTICE.txt
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
from typing import Any, Callable, Literal
|
|
5
|
+
from typing import Any, Callable, Literal
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
class Tracer:
|
|
9
9
|
threadtracefunc: Callable
|
|
10
10
|
|
|
11
|
-
include_files:
|
|
12
|
-
exclude_files:
|
|
11
|
+
include_files: list[str] | None
|
|
12
|
+
exclude_files: list[str] | None
|
|
13
13
|
|
|
14
14
|
def __init__(self, tracer_entries: int, /) -> None:
|
|
15
15
|
...
|
|
@@ -17,7 +17,7 @@ class Tracer:
|
|
|
17
17
|
def start(self) -> None:
|
|
18
18
|
...
|
|
19
19
|
|
|
20
|
-
def stop(self, stop_option:
|
|
20
|
+
def stop(self, stop_option: str | None) -> None:
|
|
21
21
|
...
|
|
22
22
|
|
|
23
23
|
def resume(self) -> None:
|
|
@@ -38,7 +38,7 @@ class Tracer:
|
|
|
38
38
|
def setignorestackcounter(self, value: int) -> int:
|
|
39
39
|
...
|
|
40
40
|
|
|
41
|
-
def
|
|
41
|
+
def reset_stack(self) -> None:
|
|
42
42
|
...
|
|
43
43
|
|
|
44
44
|
def getts(self) -> float:
|
|
@@ -53,13 +53,13 @@ class Tracer:
|
|
|
53
53
|
def add_func_args(self, key: str, value: Any) -> None:
|
|
54
54
|
...
|
|
55
55
|
|
|
56
|
-
def get_func_args(self) ->
|
|
56
|
+
def get_func_args(self) -> dict[str, Any] | None:
|
|
57
57
|
...
|
|
58
58
|
|
|
59
59
|
def add_raw(self, raw: dict[str, Any]) -> None:
|
|
60
60
|
...
|
|
61
61
|
|
|
62
|
-
def add_object(self, ph: str, obj_id: str, name: str, args:
|
|
62
|
+
def add_object(self, ph: str, obj_id: str, name: str, args: dict[str, Any] | None = None) -> None:
|
|
63
63
|
...
|
|
64
64
|
|
|
65
65
|
def add_counter(self, name: str, args: dict[str, Any]) -> None:
|
|
@@ -72,6 +72,6 @@ class Tracer:
|
|
|
72
72
|
"""set current timestamp to synchronization marker"""
|
|
73
73
|
...
|
|
74
74
|
|
|
75
|
-
def get_sync_marker(self) ->
|
|
75
|
+
def get_sync_marker(self) -> float | None:
|
|
76
76
|
"""get synchronization marker or None if not set"""
|
|
77
77
|
...
|
viztracer/util.py
CHANGED
|
@@ -7,7 +7,6 @@ import errno
|
|
|
7
7
|
import os
|
|
8
8
|
import re
|
|
9
9
|
import sys
|
|
10
|
-
from typing import Union
|
|
11
10
|
|
|
12
11
|
# Windows macros
|
|
13
12
|
STILL_ACTIVE = 0x103
|
|
@@ -15,7 +14,7 @@ ERROR_ACCESS_DENIED = 0x5
|
|
|
15
14
|
PROCESS_QUERY_LIMITED_INFORMATION = 0x1000
|
|
16
15
|
|
|
17
16
|
|
|
18
|
-
def size_fmt(num:
|
|
17
|
+
def size_fmt(num: int | float, suffix: str = 'B') -> str:
|
|
19
18
|
for unit in ['', 'Ki', 'Mi', 'Gi']:
|
|
20
19
|
if abs(num) < 1024.0:
|
|
21
20
|
return f"{num:3.1f}{unit}{suffix}"
|
|
Binary file
|
viztracer/viewer.py
CHANGED
|
@@ -20,7 +20,7 @@ import threading
|
|
|
20
20
|
import time
|
|
21
21
|
import urllib.parse
|
|
22
22
|
from http import HTTPStatus
|
|
23
|
-
from typing import Any, Callable
|
|
23
|
+
from typing import Any, Callable
|
|
24
24
|
|
|
25
25
|
|
|
26
26
|
dir_lock = threading.Lock()
|
|
@@ -277,12 +277,12 @@ class ServerThread(threading.Thread):
|
|
|
277
277
|
self.quiet = quiet
|
|
278
278
|
self.link = f"http://127.0.0.1:{self.port}"
|
|
279
279
|
self.use_external_procesor = use_external_processor
|
|
280
|
-
self.externel_processor_process:
|
|
281
|
-
self.fg_data:
|
|
280
|
+
self.externel_processor_process: ExternalProcessorProcess | None = None
|
|
281
|
+
self.fg_data: list[dict[str, Any]] | None = None
|
|
282
282
|
self.file_info = None
|
|
283
|
-
self.httpd:
|
|
283
|
+
self.httpd: VizViewerTCPServer | None = None
|
|
284
284
|
self.last_active = time.time()
|
|
285
|
-
self.retcode:
|
|
285
|
+
self.retcode: int | None = None
|
|
286
286
|
self.ready = threading.Event()
|
|
287
287
|
self.ready.clear()
|
|
288
288
|
super().__init__(daemon=True)
|
viztracer/vizlogging.py
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
# For details: https://github.com/gaogaotiantian/viztracer/blob/master/NOTICE.txt
|
|
3
3
|
|
|
4
4
|
from logging import Handler, LogRecord
|
|
5
|
-
from typing import Optional
|
|
6
5
|
|
|
7
6
|
from .viztracer import VizTracer
|
|
8
7
|
|
|
@@ -10,7 +9,7 @@ from .viztracer import VizTracer
|
|
|
10
9
|
class VizLoggingHandler(Handler):
|
|
11
10
|
def __init__(self, *args, **kwargs) -> None:
|
|
12
11
|
super().__init__(*args, **kwargs)
|
|
13
|
-
self._tracer:
|
|
12
|
+
self._tracer: VizTracer | None = None
|
|
14
13
|
|
|
15
14
|
def emit(self, record: LogRecord) -> None:
|
|
16
15
|
if not self._tracer:
|
viztracer/vizplugin.py
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
import sys
|
|
6
|
-
from typing import TYPE_CHECKING,
|
|
6
|
+
from typing import TYPE_CHECKING, Sequence
|
|
7
7
|
|
|
8
8
|
from . import __version__
|
|
9
9
|
from .util import color_print, compare_version
|
|
@@ -51,7 +51,7 @@ class VizPluginBase:
|
|
|
51
51
|
|
|
52
52
|
|
|
53
53
|
class VizPluginManager:
|
|
54
|
-
def __init__(self, tracer: "VizTracer", plugins:
|
|
54
|
+
def __init__(self, tracer: "VizTracer", plugins: Sequence[VizPluginBase | str] | None):
|
|
55
55
|
self._tracer = tracer
|
|
56
56
|
self._plugins = []
|
|
57
57
|
if plugins:
|
|
@@ -132,7 +132,7 @@ class VizPluginManager:
|
|
|
132
132
|
del plugin
|
|
133
133
|
self._plugins = []
|
|
134
134
|
|
|
135
|
-
def assert_success(self, plugin: VizPluginBase, cmd: dict, ret:
|
|
135
|
+
def assert_success(self, plugin: VizPluginBase, cmd: dict, ret: dict | None) -> None:
|
|
136
136
|
if not ret or "success" not in ret or not ret["success"]:
|
|
137
137
|
raise VizPluginError(f"{plugin} failed to process {cmd}")
|
|
138
138
|
|
viztracer/viztracer.py
CHANGED
|
@@ -9,7 +9,7 @@ import os
|
|
|
9
9
|
import platform
|
|
10
10
|
import signal
|
|
11
11
|
import sys
|
|
12
|
-
from typing import Any, Callable, Literal,
|
|
12
|
+
from typing import Any, Callable, Literal, Sequence
|
|
13
13
|
from viztracer.snaptrace import Tracer
|
|
14
14
|
|
|
15
15
|
from . import __version__
|
|
@@ -26,20 +26,20 @@ class VizTracer(Tracer):
|
|
|
26
26
|
tracer_entries: int = 1000000,
|
|
27
27
|
verbose: int = 1,
|
|
28
28
|
max_stack_depth: int = -1,
|
|
29
|
-
include_files:
|
|
30
|
-
exclude_files:
|
|
29
|
+
include_files: list[str] | None = None,
|
|
30
|
+
exclude_files: list[str] | None = None,
|
|
31
31
|
ignore_c_function: bool = False,
|
|
32
32
|
ignore_frozen: bool = False,
|
|
33
33
|
log_func_retval: bool = False,
|
|
34
34
|
log_func_args: bool = False,
|
|
35
|
-
log_func_repr:
|
|
35
|
+
log_func_repr: Callable[..., str] | None = None,
|
|
36
36
|
log_func_with_objprint: bool = False,
|
|
37
37
|
log_print: bool = False,
|
|
38
38
|
log_gc: bool = False,
|
|
39
39
|
log_sparse: bool = False,
|
|
40
40
|
log_async: bool = False,
|
|
41
41
|
log_torch: bool = False,
|
|
42
|
-
log_audit:
|
|
42
|
+
log_audit: Sequence[str] | None = None,
|
|
43
43
|
pid_suffix: bool = False,
|
|
44
44
|
file_info: bool = True,
|
|
45
45
|
register_global: bool = True,
|
|
@@ -48,9 +48,9 @@ class VizTracer(Tracer):
|
|
|
48
48
|
minimize_memory: bool = False,
|
|
49
49
|
dump_raw: bool = False,
|
|
50
50
|
sanitize_function_name: bool = False,
|
|
51
|
-
process_name:
|
|
51
|
+
process_name: str | None = None,
|
|
52
52
|
output_file: str = "result.json",
|
|
53
|
-
plugins:
|
|
53
|
+
plugins: Sequence[VizPluginBase | str] | None = None) -> None:
|
|
54
54
|
super().__init__(tracer_entries)
|
|
55
55
|
|
|
56
56
|
# Members of C Tracer object
|
|
@@ -112,9 +112,9 @@ class VizTracer(Tracer):
|
|
|
112
112
|
|
|
113
113
|
self.cwd = os.getcwd()
|
|
114
114
|
|
|
115
|
-
self.viztmp:
|
|
115
|
+
self.viztmp: str | None = None
|
|
116
116
|
|
|
117
|
-
self._afterfork_cb:
|
|
117
|
+
self._afterfork_cb: Callable | None = None
|
|
118
118
|
self._afterfork_args: tuple = tuple()
|
|
119
119
|
self._afterfork_kwargs: dict = {}
|
|
120
120
|
|
|
@@ -232,7 +232,7 @@ class VizTracer(Tracer):
|
|
|
232
232
|
self._plugin_manager.event("pre-start")
|
|
233
233
|
super().start()
|
|
234
234
|
|
|
235
|
-
def stop(self, stop_option:
|
|
235
|
+
def stop(self, stop_option: str | None = None) -> None:
|
|
236
236
|
if self.enable:
|
|
237
237
|
self.enable = False
|
|
238
238
|
if self.log_print:
|
|
@@ -272,7 +272,7 @@ class VizTracer(Tracer):
|
|
|
272
272
|
|
|
273
273
|
return self.total_entries
|
|
274
274
|
|
|
275
|
-
def run(self, command: str, output_file:
|
|
275
|
+
def run(self, command: str, output_file: str | None = None) -> None:
|
|
276
276
|
self.start()
|
|
277
277
|
exec(command)
|
|
278
278
|
self.stop()
|
|
@@ -280,9 +280,9 @@ class VizTracer(Tracer):
|
|
|
280
280
|
|
|
281
281
|
def save(
|
|
282
282
|
self,
|
|
283
|
-
output_file:
|
|
284
|
-
file_info:
|
|
285
|
-
verbose:
|
|
283
|
+
output_file: str | None = None,
|
|
284
|
+
file_info: bool | None = None,
|
|
285
|
+
verbose: int | None = None) -> None:
|
|
286
286
|
if file_info is None:
|
|
287
287
|
file_info = self.file_info
|
|
288
288
|
enabled = False
|
|
@@ -329,7 +329,7 @@ class VizTracer(Tracer):
|
|
|
329
329
|
if enabled:
|
|
330
330
|
self.start()
|
|
331
331
|
|
|
332
|
-
def fork_save(self, output_file:
|
|
332
|
+
def fork_save(self, output_file: str | None = None) -> multiprocessing.Process:
|
|
333
333
|
if multiprocessing.get_start_method() != "fork":
|
|
334
334
|
raise RuntimeError("fork_save is only supported in fork start method")
|
|
335
335
|
|
|
@@ -468,5 +468,5 @@ class VizTracer(Tracer):
|
|
|
468
468
|
})
|
|
469
469
|
|
|
470
470
|
|
|
471
|
-
def get_tracer() ->
|
|
471
|
+
def get_tracer() -> VizTracer | None:
|
|
472
472
|
return builtins.__dict__.get("__viz_tracer__", None)
|
viztracer/web_dist/index.html
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport" />
|
|
7
7
|
<link rel="shortcut icon" id="favicon" type="image/png" href="data:image/png;base64,iVBORw0KGgo=">
|
|
8
8
|
</head>
|
|
9
|
-
<body data-perfetto_version='{"stable":"
|
|
9
|
+
<body data-perfetto_version='{"stable":"v52.0-6b9586def"}'>
|
|
10
10
|
<!--
|
|
11
11
|
Don't add any content here. The whole <body> is replaced by
|
|
12
12
|
frontend/index.ts when bootstrapping. This is only used for very early
|
|
@@ -3,24 +3,58 @@ var service_worker = (function () {
|
|
|
3
3
|
|
|
4
4
|
var service_worker = {};
|
|
5
5
|
|
|
6
|
+
// Copyright (C) 2020 The Android Open Source Project
|
|
7
|
+
//
|
|
8
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
9
|
+
// you may not use this file except in compliance with the License.
|
|
10
|
+
// You may obtain a copy of the License at
|
|
11
|
+
//
|
|
12
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
13
|
+
//
|
|
14
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
15
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
16
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
17
|
+
// See the License for the specific language governing permissions and
|
|
18
|
+
// limitations under the License.
|
|
6
19
|
Object.defineProperty(service_worker, "__esModule", { value: true });
|
|
7
20
|
const LOG_TAG = `ServiceWorker: `;
|
|
8
21
|
const CACHE_NAME = 'ui-perfetto-dev';
|
|
9
22
|
const OPEN_TRACE_PREFIX = '/_open_trace';
|
|
23
|
+
// If the fetch() for the / doesn't respond within 3s, return a cached version.
|
|
24
|
+
// This is to avoid that a user waits too much if on a flaky network.
|
|
10
25
|
const INDEX_TIMEOUT_MS = 3000;
|
|
26
|
+
// Use more relaxed timeouts when caching the subresources for the new version
|
|
27
|
+
// in the background.
|
|
11
28
|
const INSTALL_TIMEOUT_MS = 30000;
|
|
29
|
+
// Files passed to POST /_open_trace/NNNN.
|
|
12
30
|
let postedFiles = new Map();
|
|
31
|
+
// The install() event is fired:
|
|
32
|
+
// 1. On the first visit, when there is no SW installed.
|
|
33
|
+
// 2. Every time the user opens the site and the version has been updated (they
|
|
34
|
+
// will get the newer version regardless, unless we hit INDEX_TIMEOUT_MS).
|
|
35
|
+
// The latter happens because:
|
|
36
|
+
// - / (index.html) is always served from the network (% timeout) and it pulls
|
|
37
|
+
// /v1.2-sha/frontend_bundle.js.
|
|
38
|
+
// - /v1.2-sha/frontend_bundle.js will register /service_worker.js?v=v1.2-sha.
|
|
39
|
+
// The service_worker.js script itself never changes, but the browser
|
|
40
|
+
// re-installs it because the version in the V? query-string argument changes.
|
|
41
|
+
// The reinstallation will cache the new files from the v.1.2-sha/manifest.json.
|
|
13
42
|
self.addEventListener('install', (event) => {
|
|
14
43
|
const doInstall = async () => {
|
|
44
|
+
// If we can not access the cache we must give up on the service
|
|
45
|
+
// worker:
|
|
15
46
|
let bypass = true;
|
|
16
47
|
try {
|
|
17
48
|
bypass = await caches.has('BYPASS_SERVICE_WORKER');
|
|
18
49
|
}
|
|
19
50
|
catch (_) {
|
|
51
|
+
// TODO(288483453)
|
|
20
52
|
}
|
|
21
53
|
if (bypass) {
|
|
54
|
+
// Throw will prevent the installation.
|
|
22
55
|
throw new Error(LOG_TAG + 'skipping installation, bypass enabled');
|
|
23
56
|
}
|
|
57
|
+
// Delete old cache entries from the pre-feb-2021 service worker.
|
|
24
58
|
try {
|
|
25
59
|
for (const key of await caches.keys()) {
|
|
26
60
|
if (key.startsWith('dist-')) {
|
|
@@ -29,13 +63,26 @@ self.addEventListener('install', (event) => {
|
|
|
29
63
|
}
|
|
30
64
|
}
|
|
31
65
|
catch (_) {
|
|
66
|
+
// TODO(288483453)
|
|
67
|
+
// It's desirable to delete the old entries but it's not actually
|
|
68
|
+
// damaging to keep them around so don't give up on the
|
|
69
|
+
// installation if this fails.
|
|
32
70
|
}
|
|
71
|
+
// The UI should register this as service_worker.js?v=v1.2-sha. Extract the
|
|
72
|
+
// version number and pre-fetch all the contents for the version.
|
|
33
73
|
const match = /\bv=([\w.-]*)/.exec(location.search);
|
|
34
74
|
if (!match) {
|
|
35
75
|
throw new Error('Failed to install. Was epecting a query string like ' +
|
|
36
76
|
`?v=v1.2-sha query string, got "${location.search}" instead`);
|
|
37
77
|
}
|
|
38
78
|
await installAppVersionIntoCache(match[1]);
|
|
79
|
+
// skipWaiting() still waits for the install to be complete. Without this
|
|
80
|
+
// call, the new version would be activated only when all tabs are closed.
|
|
81
|
+
// Instead, we ask to activate it immediately. This is safe because the
|
|
82
|
+
// subresources are versioned (e.g. /v1.2-sha/frontend_bundle.js). Even if
|
|
83
|
+
// there is an old UI tab opened while we activate() a newer version, the
|
|
84
|
+
// activate() would just cause cache-misses, hence fetch from the network,
|
|
85
|
+
// for the old tab.
|
|
39
86
|
self.skipWaiting();
|
|
40
87
|
};
|
|
41
88
|
event.waitUntil(doInstall());
|
|
@@ -43,11 +90,16 @@ self.addEventListener('install', (event) => {
|
|
|
43
90
|
self.addEventListener('activate', (event) => {
|
|
44
91
|
console.info(LOG_TAG + 'activated');
|
|
45
92
|
const doActivate = async () => {
|
|
93
|
+
// This makes a difference only for the very first load, when no service
|
|
94
|
+
// worker is present. In all the other cases the skipWaiting() will hot-swap
|
|
95
|
+
// the active service worker anyways.
|
|
46
96
|
await self.clients.claim();
|
|
47
97
|
};
|
|
48
98
|
event.waitUntil(doActivate());
|
|
49
99
|
});
|
|
50
100
|
self.addEventListener('fetch', (event) => {
|
|
101
|
+
// The early return here will cause the browser to fall back on standard
|
|
102
|
+
// network-based fetch.
|
|
51
103
|
if (!shouldHandleHttpRequest(event.request)) {
|
|
52
104
|
console.debug(LOG_TAG + `serving ${event.request.url} from network`);
|
|
53
105
|
return;
|
|
@@ -55,6 +107,9 @@ self.addEventListener('fetch', (event) => {
|
|
|
55
107
|
event.respondWith(handleHttpRequest(event.request));
|
|
56
108
|
});
|
|
57
109
|
function shouldHandleHttpRequest(req) {
|
|
110
|
+
// Suppress warning: 'only-if-cached' can be set only with 'same-origin' mode.
|
|
111
|
+
// This seems to be a chromium bug. An internal code search suggests this is a
|
|
112
|
+
// socially acceptable workaround.
|
|
58
113
|
if (req.cache === 'only-if-cached' && req.mode !== 'same-origin') {
|
|
59
114
|
return false;
|
|
60
115
|
}
|
|
@@ -69,18 +124,32 @@ async function handleHttpRequest(req) {
|
|
|
69
124
|
if (!shouldHandleHttpRequest(req)) {
|
|
70
125
|
throw new Error(LOG_TAG + `${req.url} shouldn't have been handled`);
|
|
71
126
|
}
|
|
127
|
+
// We serve from the cache even if req.cache == 'no-cache'. It's a bit
|
|
128
|
+
// contra-intuitive but it's the most consistent option. If the user hits the
|
|
129
|
+
// reload button*, the browser requests the "/" index with a 'no-cache' fetch.
|
|
130
|
+
// However all the other resources (css, js, ...) are requested with a
|
|
131
|
+
// 'default' fetch (this is just how Chrome works, it's not us). If we bypass
|
|
132
|
+
// the service worker cache when we get a 'no-cache' request, we can end up in
|
|
133
|
+
// an inconsistent state where the index.html is more recent than the other
|
|
134
|
+
// resources, which is undesirable.
|
|
135
|
+
// * Only Ctrl+R. Ctrl+Shift+R will always bypass service-worker for all the
|
|
136
|
+
// requests (index.html and the rest) made in that tab.
|
|
72
137
|
const cacheOps = { cacheName: CACHE_NAME };
|
|
73
138
|
const url = new URL(req.url);
|
|
74
139
|
if (url.pathname === '/') {
|
|
75
140
|
try {
|
|
76
141
|
console.debug(LOG_TAG + `Fetching live ${req.url}`);
|
|
142
|
+
// The await bleow is needed to fall through in case of an exception.
|
|
77
143
|
return await fetchWithTimeout(req, INDEX_TIMEOUT_MS);
|
|
78
144
|
}
|
|
79
145
|
catch (err) {
|
|
80
146
|
console.warn(LOG_TAG + `Failed to fetch ${req.url}, using cache.`, err);
|
|
147
|
+
// Fall through the code below.
|
|
81
148
|
}
|
|
82
149
|
}
|
|
83
150
|
else if (url.pathname === '/offline') {
|
|
151
|
+
// Escape hatch to force serving the offline version without attempting the
|
|
152
|
+
// network fetch.
|
|
84
153
|
const cachedRes = await caches.match(new Request('/'), cacheOps);
|
|
85
154
|
if (cachedRes)
|
|
86
155
|
return cachedRes;
|
|
@@ -93,9 +162,31 @@ async function handleHttpRequest(req) {
|
|
|
93
162
|
console.debug(LOG_TAG + `serving ${req.url} from cache`);
|
|
94
163
|
return cachedRes;
|
|
95
164
|
}
|
|
165
|
+
// In any other case, just propagate the fetch on the network, which is the
|
|
166
|
+
// safe behavior.
|
|
96
167
|
console.warn(LOG_TAG + `cache miss on ${req.url}, using live network`);
|
|
97
168
|
return fetch(req);
|
|
98
169
|
}
|
|
170
|
+
// Handles GET and POST requests to /_open_trace/NNNN, where NNNN is typically a
|
|
171
|
+
// random token generated by the client.
|
|
172
|
+
// This works as follows:
|
|
173
|
+
// - The client does a POST request to /_open_trace/NNNN passing the trace blob
|
|
174
|
+
// as multipart-data, alongside other options like hideSidebar & co that we
|
|
175
|
+
// support in the usual querystring (see router.ts)
|
|
176
|
+
// - The SW takes the file and puts it in the global variable `postedFiles`.
|
|
177
|
+
// - The SW responds to the POST request with a redirect to
|
|
178
|
+
// ui.perfetto.dev/#!/?url=https://ui.perfetto.dev/_open_trace/NNNN&other_args
|
|
179
|
+
// - When the new ui.perfetto.dev is reloaded, it will naturally try to fetch
|
|
180
|
+
// the trace from /_open_trace/NNNN, this time via a GET request.
|
|
181
|
+
// - The SW intercepts the GET request and returns the file previosly stored in
|
|
182
|
+
// `postedFiles`.
|
|
183
|
+
// We use postedFiles here to handle the case of progammatically POST-ing to >1
|
|
184
|
+
// instances of ui.perfetto.dev simultaneously, to avoid races.
|
|
185
|
+
// Note that we should not use a global variable for `postedFiles` but we should
|
|
186
|
+
// use the CacheAPI because, technically speaking, the SW could be disposed
|
|
187
|
+
// and respawned in between the POST and the GET request. In practice, however,
|
|
188
|
+
// SWs are disposed only after 30s seconds of idleness. The POST->GET requests
|
|
189
|
+
// happen back-to-back..
|
|
99
190
|
async function handleOpenTraceRequest(req) {
|
|
100
191
|
const url = new URL(req.url);
|
|
101
192
|
console.assert(url.pathname.startsWith(OPEN_TRACE_PREFIX));
|
|
@@ -103,6 +194,9 @@ async function handleOpenTraceRequest(req) {
|
|
|
103
194
|
if (req.method === 'POST') {
|
|
104
195
|
const formData = await req.formData();
|
|
105
196
|
const qsParams = new URLSearchParams();
|
|
197
|
+
// Iterate over the POST fields and copy them over the querystring in
|
|
198
|
+
// the hash, with the exception of the trace file. The trace file is
|
|
199
|
+
// kept in the serviceworker and passed as a url= argument.
|
|
106
200
|
formData.forEach((value, key) => {
|
|
107
201
|
if (key === 'trace') {
|
|
108
202
|
if (value instanceof File) {
|
|
@@ -112,14 +206,16 @@ async function handleOpenTraceRequest(req) {
|
|
|
112
206
|
return;
|
|
113
207
|
}
|
|
114
208
|
qsParams.set(key, `${value}`);
|
|
115
|
-
});
|
|
209
|
+
}); // formData.forEach()
|
|
116
210
|
return Response.redirect(`${url.protocol}//${url.host}/#!/?${qsParams}`);
|
|
117
211
|
}
|
|
212
|
+
// else... method == 'GET'
|
|
118
213
|
const file = postedFiles.get(fileKey);
|
|
119
214
|
if (file !== undefined) {
|
|
120
215
|
postedFiles.delete(fileKey);
|
|
121
216
|
return new Response(file);
|
|
122
217
|
}
|
|
218
|
+
// The file /_open_trace/NNNN does not exist.
|
|
123
219
|
return Response.error();
|
|
124
220
|
}
|
|
125
221
|
async function installAppVersionIntoCache(version) {
|
|
@@ -135,8 +231,14 @@ async function installAppVersionIntoCache(version) {
|
|
|
135
231
|
}
|
|
136
232
|
const cache = await caches.open(CACHE_NAME);
|
|
137
233
|
const urlsToCache = [];
|
|
234
|
+
// We use cache:reload to make sure that the index is always current and we
|
|
235
|
+
// don't end up in some cycle where we keep re-caching the index coming from
|
|
236
|
+
// the service worker itself.
|
|
138
237
|
urlsToCache.push(new Request('/', { cache: 'reload', mode: 'same-origin' }));
|
|
139
238
|
for (const [resource, integrity] of Object.entries(manifestResources)) {
|
|
239
|
+
// We use cache: no-cache rather then reload here because the versioned
|
|
240
|
+
// sub-resources are expected to be immutable and should never be
|
|
241
|
+
// ambiguous. A revalidation request is enough.
|
|
140
242
|
const reqOpts = {
|
|
141
243
|
cache: 'no-cache',
|
|
142
244
|
mode: 'same-origin',
|
|
@@ -30,18 +30,18 @@ exec python3 - "$@" <<'#'EOF
|
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
# ----- Amalgamator: begin of python/perfetto/prebuilts/manifests/trace_processor_shell.py
|
|
33
|
-
# This file has been generated by: tools/roll-prebuilts
|
|
33
|
+
# This file has been generated by: tools/roll-prebuilts v52.0
|
|
34
34
|
TRACE_PROCESSOR_SHELL_MANIFEST = [{
|
|
35
35
|
'arch':
|
|
36
36
|
'mac-amd64',
|
|
37
37
|
'file_name':
|
|
38
38
|
'trace_processor_shell',
|
|
39
39
|
'file_size':
|
|
40
|
-
|
|
40
|
+
11378016,
|
|
41
41
|
'url':
|
|
42
|
-
'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/
|
|
42
|
+
'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v52.0/mac-amd64/trace_processor_shell',
|
|
43
43
|
'sha256':
|
|
44
|
-
'
|
|
44
|
+
'0ce16fc3e2add79cd66c6596a04ec61eb3b2b8d5507496c5d325f57cb89dc5e8',
|
|
45
45
|
'platform':
|
|
46
46
|
'darwin',
|
|
47
47
|
'machine': ['x86_64']
|
|
@@ -51,11 +51,11 @@ TRACE_PROCESSOR_SHELL_MANIFEST = [{
|
|
|
51
51
|
'file_name':
|
|
52
52
|
'trace_processor_shell',
|
|
53
53
|
'file_size':
|
|
54
|
-
|
|
54
|
+
10561528,
|
|
55
55
|
'url':
|
|
56
|
-
'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/
|
|
56
|
+
'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v52.0/mac-arm64/trace_processor_shell',
|
|
57
57
|
'sha256':
|
|
58
|
-
'
|
|
58
|
+
'5d7d89fb2472c2ef40413141d5e8f3603d4a500a645d35aa57cb023b9d635b31',
|
|
59
59
|
'platform':
|
|
60
60
|
'darwin',
|
|
61
61
|
'machine': ['arm64']
|
|
@@ -65,11 +65,11 @@ TRACE_PROCESSOR_SHELL_MANIFEST = [{
|
|
|
65
65
|
'file_name':
|
|
66
66
|
'trace_processor_shell',
|
|
67
67
|
'file_size':
|
|
68
|
-
|
|
68
|
+
11599408,
|
|
69
69
|
'url':
|
|
70
|
-
'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/
|
|
70
|
+
'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v52.0/linux-amd64/trace_processor_shell',
|
|
71
71
|
'sha256':
|
|
72
|
-
'
|
|
72
|
+
'411402424f34f2ac1fafa819493c13827ae5a10e335d9387a483c4b696b7f6e1',
|
|
73
73
|
'platform':
|
|
74
74
|
'linux',
|
|
75
75
|
'machine': ['x86_64']
|
|
@@ -79,11 +79,11 @@ TRACE_PROCESSOR_SHELL_MANIFEST = [{
|
|
|
79
79
|
'file_name':
|
|
80
80
|
'trace_processor_shell',
|
|
81
81
|
'file_size':
|
|
82
|
-
|
|
82
|
+
8656808,
|
|
83
83
|
'url':
|
|
84
|
-
'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/
|
|
84
|
+
'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v52.0/linux-arm/trace_processor_shell',
|
|
85
85
|
'sha256':
|
|
86
|
-
'
|
|
86
|
+
'e45b30a268e2a68f528cb181414383a02317b0e9ab530edb72041faf9fa60468',
|
|
87
87
|
'platform':
|
|
88
88
|
'linux',
|
|
89
89
|
'machine': ['armv6l', 'armv7l', 'armv8l']
|
|
@@ -93,11 +93,11 @@ TRACE_PROCESSOR_SHELL_MANIFEST = [{
|
|
|
93
93
|
'file_name':
|
|
94
94
|
'trace_processor_shell',
|
|
95
95
|
'file_size':
|
|
96
|
-
|
|
96
|
+
11055208,
|
|
97
97
|
'url':
|
|
98
|
-
'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/
|
|
98
|
+
'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v52.0/linux-arm64/trace_processor_shell',
|
|
99
99
|
'sha256':
|
|
100
|
-
'
|
|
100
|
+
'e52888ab9b7d4f3d2620a6f803402e60a11230536d048d0ece4f33b78dd7c368',
|
|
101
101
|
'platform':
|
|
102
102
|
'linux',
|
|
103
103
|
'machine': ['aarch64']
|
|
@@ -107,55 +107,55 @@ TRACE_PROCESSOR_SHELL_MANIFEST = [{
|
|
|
107
107
|
'file_name':
|
|
108
108
|
'trace_processor_shell',
|
|
109
109
|
'file_size':
|
|
110
|
-
|
|
110
|
+
8691452,
|
|
111
111
|
'url':
|
|
112
|
-
'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/
|
|
112
|
+
'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v52.0/android-arm/trace_processor_shell',
|
|
113
113
|
'sha256':
|
|
114
|
-
'
|
|
114
|
+
'2d5881d738d086296dcb5a82a56eb94860ba1b6b41f11f0e48aeff26b63be406'
|
|
115
115
|
}, {
|
|
116
116
|
'arch':
|
|
117
117
|
'android-arm64',
|
|
118
118
|
'file_name':
|
|
119
119
|
'trace_processor_shell',
|
|
120
120
|
'file_size':
|
|
121
|
-
|
|
121
|
+
10966008,
|
|
122
122
|
'url':
|
|
123
|
-
'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/
|
|
123
|
+
'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v52.0/android-arm64/trace_processor_shell',
|
|
124
124
|
'sha256':
|
|
125
|
-
'
|
|
125
|
+
'6c76a80e4dbf5f6b58905da995111b659c573bd3a100f683c046dd7854a2179a'
|
|
126
126
|
}, {
|
|
127
127
|
'arch':
|
|
128
128
|
'android-x86',
|
|
129
129
|
'file_name':
|
|
130
130
|
'trace_processor_shell',
|
|
131
131
|
'file_size':
|
|
132
|
-
|
|
132
|
+
12232376,
|
|
133
133
|
'url':
|
|
134
|
-
'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/
|
|
134
|
+
'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v52.0/android-x86/trace_processor_shell',
|
|
135
135
|
'sha256':
|
|
136
|
-
'
|
|
136
|
+
'135e557cedcec6cd580aafc1a74cac974da0811f56fd724d61e60b575f772193'
|
|
137
137
|
}, {
|
|
138
138
|
'arch':
|
|
139
139
|
'android-x64',
|
|
140
140
|
'file_name':
|
|
141
141
|
'trace_processor_shell',
|
|
142
142
|
'file_size':
|
|
143
|
-
|
|
143
|
+
11432000,
|
|
144
144
|
'url':
|
|
145
|
-
'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/
|
|
145
|
+
'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v52.0/android-x64/trace_processor_shell',
|
|
146
146
|
'sha256':
|
|
147
|
-
'
|
|
147
|
+
'634ecc32a0055c805ac62aab77bdf040daed3f5f148064f3e252912705eb3f6d'
|
|
148
148
|
}, {
|
|
149
149
|
'arch':
|
|
150
150
|
'windows-amd64',
|
|
151
151
|
'file_name':
|
|
152
152
|
'trace_processor_shell.exe',
|
|
153
153
|
'file_size':
|
|
154
|
-
|
|
154
|
+
11401216,
|
|
155
155
|
'url':
|
|
156
|
-
'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/
|
|
156
|
+
'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v52.0/windows-amd64/trace_processor_shell.exe',
|
|
157
157
|
'sha256':
|
|
158
|
-
'
|
|
158
|
+
'e46f58f5158b48508389e096aa3d5cf7b510b9767a89f949e423abe8c09ca380',
|
|
159
159
|
'platform':
|
|
160
160
|
'win32',
|
|
161
161
|
'machine': ['amd64']
|
|
@@ -291,6 +291,7 @@ def run_perfetto_prebuilt(manifest):
|
|
|
291
291
|
sys.exit(subprocess.check_call([bin_path, *sys.argv[1:]]))
|
|
292
292
|
os.execv(bin_path, [bin_path] + sys.argv[1:])
|
|
293
293
|
|
|
294
|
+
|
|
294
295
|
# ----- Amalgamator: end of python/perfetto/prebuilts/perfetto_prebuilts.py
|
|
295
296
|
|
|
296
297
|
if __name__ == '__main__':
|
|
Binary file
|