viztracer 1.0.4__cp313-cp313t-win32.whl → 1.1.0__cp313-cp313t-win32.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.

Files changed (88) hide show
  1. viztracer/__init__.py +1 -1
  2. viztracer/code_monkey.py +10 -13
  3. viztracer/decorator.py +9 -12
  4. viztracer/event_base.py +2 -2
  5. viztracer/functree.py +7 -7
  6. viztracer/main.py +9 -13
  7. viztracer/modules/snaptrace.c +14 -12
  8. viztracer/modules/util.c +1 -5
  9. viztracer/modules/vcompressor/vc_dump.c +4 -24
  10. viztracer/modules/vcompressor/vcompressor.c +13 -13
  11. viztracer/patch.py +10 -6
  12. viztracer/report_builder.py +8 -8
  13. viztracer/snaptrace.cp313t-win32.pyd +0 -0
  14. viztracer/snaptrace.pyi +8 -8
  15. viztracer/util.py +1 -2
  16. viztracer/vcompressor.cp313t-win32.pyd +0 -0
  17. viztracer/viewer.py +5 -5
  18. viztracer/vizlogging.py +1 -2
  19. viztracer/vizplugin.py +3 -3
  20. viztracer/viztracer.py +16 -16
  21. viztracer/web_dist/index.html +1 -1
  22. viztracer/web_dist/service_worker.js +103 -1
  23. viztracer/web_dist/trace_processor +32 -31
  24. viztracer/web_dist/v52.0-6b9586def/assets/MaterialSymbolsOutlined.woff2 +0 -0
  25. viztracer/web_dist/v52.0-6b9586def/engine_bundle.js +3 -0
  26. viztracer/web_dist/v52.0-6b9586def/frontend_bundle.js +5495 -0
  27. viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/manifest.json +10 -8
  28. viztracer/web_dist/v52.0-6b9586def/perfetto.css +5737 -0
  29. viztracer/web_dist/v52.0-6b9586def/stdlib_docs.json +1 -0
  30. viztracer/web_dist/v52.0-6b9586def/trace_config_utils.wasm +0 -0
  31. viztracer/web_dist/{v47.0-02b2414d5/traceconv.wasm → v52.0-6b9586def/trace_processor.wasm} +0 -0
  32. viztracer/web_dist/v52.0-6b9586def/trace_processor_memory64.wasm +0 -0
  33. viztracer/web_dist/{v47.0-02b2414d5/trace_processor.wasm → v52.0-6b9586def/traceconv.wasm} +0 -0
  34. viztracer/web_dist/v52.0-6b9586def/traceconv_bundle.js +2 -0
  35. viztracer-1.1.0.dist-info/METADATA +316 -0
  36. viztracer-1.1.0.dist-info/RECORD +109 -0
  37. {viztracer-1.0.4.dist-info → viztracer-1.1.0.dist-info}/WHEEL +1 -1
  38. viztracer/web_dist/v47.0-02b2414d5/assets/._MaterialSymbolsOutlined.woff2 +0 -0
  39. viztracer/web_dist/v47.0-02b2414d5/assets/MaterialSymbolsOutlined.woff2 +0 -0
  40. viztracer/web_dist/v47.0-02b2414d5/engine_bundle.js +0 -3
  41. viztracer/web_dist/v47.0-02b2414d5/frontend_bundle.js +0 -4994
  42. viztracer/web_dist/v47.0-02b2414d5/perfetto.css +0 -5133
  43. viztracer/web_dist/v47.0-02b2414d5/traceconv_bundle.js +0 -2
  44. viztracer-1.0.4.dist-info/METADATA +0 -537
  45. viztracer-1.0.4.dist-info/RECORD +0 -107
  46. /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/Roboto-100.woff2 +0 -0
  47. /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/Roboto-300.woff2 +0 -0
  48. /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/Roboto-400.woff2 +0 -0
  49. /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/Roboto-500.woff2 +0 -0
  50. /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/RobotoCondensed-Light.woff2 +0 -0
  51. /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/RobotoCondensed-Regular.woff2 +0 -0
  52. /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/RobotoMono-Regular.woff2 +0 -0
  53. /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/brand.png +0 -0
  54. /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/catapult_trace_viewer.html +0 -0
  55. /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/catapult_trace_viewer.js +0 -0
  56. /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/favicon.png +0 -0
  57. /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/logo-128.png +0 -0
  58. /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/logo-3d.png +0 -0
  59. /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/rec_atrace.png +0 -0
  60. /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/rec_battery_counters.png +0 -0
  61. /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/rec_board_voltage.png +0 -0
  62. /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/rec_cpu_coarse.png +0 -0
  63. /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/rec_cpu_fine.png +0 -0
  64. /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/rec_cpu_freq.png +0 -0
  65. /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/rec_cpu_voltage.png +0 -0
  66. /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/rec_frame_timeline.png +0 -0
  67. /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/rec_ftrace.png +0 -0
  68. /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/rec_gpu_mem_total.png +0 -0
  69. /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/rec_java_heap_dump.png +0 -0
  70. /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/rec_lmk.png +0 -0
  71. /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/rec_logcat.png +0 -0
  72. /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/rec_long_trace.png +0 -0
  73. /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/rec_mem_hifreq.png +0 -0
  74. /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/rec_meminfo.png +0 -0
  75. /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/rec_native_heap_profiler.png +0 -0
  76. /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/rec_one_shot.png +0 -0
  77. /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/rec_profiling.png +0 -0
  78. /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/rec_ps_stats.png +0 -0
  79. /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/rec_ring_buf.png +0 -0
  80. /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/rec_syscalls.png +0 -0
  81. /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/rec_vmstat.png +0 -0
  82. /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/scheduling_latency.png +0 -0
  83. /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/assets/vscode-icon.png +0 -0
  84. /viztracer/web_dist/{v47.0-02b2414d5 → v52.0-6b9586def}/index.html +0 -0
  85. {viztracer-1.0.4.dist-info → viztracer-1.1.0.dist-info}/entry_points.txt +0 -0
  86. {viztracer-1.0.4.dist-info → viztracer-1.1.0.dist-info}/licenses/LICENSE +0 -0
  87. {viztracer-1.0.4.dist-info → viztracer-1.1.0.dist-info}/licenses/NOTICE.txt +0 -0
  88. {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, Optional
5
+ from typing import Any, Callable, Literal
6
6
 
7
7
 
8
8
  class Tracer:
9
9
  threadtracefunc: Callable
10
10
 
11
- include_files: Optional[list[str]]
12
- exclude_files: Optional[list[str]]
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: Optional[str]) -> None:
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 _set_curr_stack_depth(self, stack_depth: int) -> None:
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) -> Optional[dict[str, Any]]:
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: Optional[dict[str, Any]] = None) -> None:
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) -> Optional[float]:
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: Union[int, float], suffix: str = 'B') -> str:
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, Optional
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: Optional[ExternalProcessorProcess] = None
281
- self.fg_data: Optional[list[dict[str, Any]]] = None
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: Optional[VizViewerTCPServer] = None
283
+ self.httpd: VizViewerTCPServer | None = None
284
284
  self.last_active = time.time()
285
- self.retcode: Optional[int] = None
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: Optional[VizTracer] = None
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, Optional, Sequence, Union
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: Optional[Sequence[Union[VizPluginBase, str]]]):
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: Optional[dict]) -> None:
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, Optional, Sequence, Union
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: Optional[list[str]] = None,
30
- exclude_files: Optional[list[str]] = None,
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: Optional[Callable[..., str]] = None,
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: Optional[Sequence[str]] = None,
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: Optional[str] = None,
51
+ process_name: str | None = None,
52
52
  output_file: str = "result.json",
53
- plugins: Optional[Sequence[Union[VizPluginBase, str]]] = None) -> None:
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: Optional[str] = None
115
+ self.viztmp: str | None = None
116
116
 
117
- self._afterfork_cb: Optional[Callable] = None
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: Optional[str] = None) -> None:
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: Optional[str] = None) -> None:
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: Optional[str] = None,
284
- file_info: Optional[bool] = None,
285
- verbose: Optional[int] = None) -> None:
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: Optional[str] = None) -> multiprocessing.Process:
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() -> Optional[VizTracer]:
471
+ def get_tracer() -> VizTracer | None:
472
472
  return builtins.__dict__.get("__viz_tracer__", None)
@@ -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":"v47.0-02b2414d5"}'>
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 v47.0
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
- 10209056,
40
+ 11378016,
41
41
  'url':
42
- 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v47.0/mac-amd64/trace_processor_shell',
42
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v52.0/mac-amd64/trace_processor_shell',
43
43
  'sha256':
44
- '203c4c7a3621ee7c60a3d558613216427aa0f7245dc34fbe27e03cbcaf15cbd7',
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
- 9518360,
54
+ 10561528,
55
55
  'url':
56
- 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v47.0/mac-arm64/trace_processor_shell',
56
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v52.0/mac-arm64/trace_processor_shell',
57
57
  'sha256':
58
- '02130db81f477e795f0fb33e5183eed6d9350057346d730fe30aac5a6443d9c1',
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
- 10363488,
68
+ 11599408,
69
69
  'url':
70
- 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v47.0/linux-amd64/trace_processor_shell',
70
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v52.0/linux-amd64/trace_processor_shell',
71
71
  'sha256':
72
- '832425c3c7934904d1e0ec1721beb51423de7dbcf399a899973f2b6b464603fa',
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
- 7682608,
82
+ 8656808,
83
83
  'url':
84
- 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v47.0/linux-arm/trace_processor_shell',
84
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v52.0/linux-arm/trace_processor_shell',
85
85
  'sha256':
86
- '0d5e41279051326311b178c73289d6027493bdd8627f537e538aa39a6f74af81',
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
- 9949744,
96
+ 11055208,
97
97
  'url':
98
- 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v47.0/linux-arm64/trace_processor_shell',
98
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v52.0/linux-arm64/trace_processor_shell',
99
99
  'sha256':
100
- '2a9e5f6ee3d9a0d6007fc5503a9358629d7b3881233ee6fbe157edaa0f5a3b1b',
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
- 7716332,
110
+ 8691452,
111
111
  'url':
112
- 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v47.0/android-arm/trace_processor_shell',
112
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v52.0/android-arm/trace_processor_shell',
113
113
  'sha256':
114
- 'a3a1f49448e72c368748cb6ec0cb1f63ba4fe5598ff08118053dac68916b9433'
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
- 9861544,
121
+ 10966008,
122
122
  'url':
123
- 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v47.0/android-arm64/trace_processor_shell',
123
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v52.0/android-arm64/trace_processor_shell',
124
124
  'sha256':
125
- '49c9f94802986b9cada8ffab9ec911f21a416966a7c0b2acc3e467f03892ec56'
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
- 10805720,
132
+ 12232376,
133
133
  'url':
134
- 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v47.0/android-x86/trace_processor_shell',
134
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v52.0/android-x86/trace_processor_shell',
135
135
  'sha256':
136
- 'b188a7d95533a26b9eadcc5233d9fcc8552f94c0c7224a7f39f5e6eaebd7e981'
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
- 10150016,
143
+ 11432000,
144
144
  'url':
145
- 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v47.0/android-x64/trace_processor_shell',
145
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v52.0/android-x64/trace_processor_shell',
146
146
  'sha256':
147
- 'ff83eb7f53fc91d42c8756bb752fd70ed1f03b40a9daba99a6843c391bc8ff66'
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
- 10187264,
154
+ 11401216,
155
155
  'url':
156
- 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v47.0/windows-amd64/trace_processor_shell.exe',
156
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v52.0/windows-amd64/trace_processor_shell.exe',
157
157
  'sha256':
158
- 'f9b39c21a99f412697b4bf59f7046f80482c9f07dc3507c2d448dda02915aa14',
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__':