Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(29)

Side by Side Diff: tools/perf/profile_creators/fast_navigation_profile_extender.py

Issue 914253005: Telemetry: Create new profile creator large_profile_creator. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase against top of tree. Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 # Copyright 2015 The Chromium Authors. All rights reserved. 1 # Copyright 2015 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 import multiprocessing
4 import time 5 import time
5 6
6 from telemetry.core import browser_finder 7 from telemetry.core import browser_finder
7 from telemetry.core import browser_finder_exceptions 8 from telemetry.core import browser_finder_exceptions
8 from telemetry.core import exceptions 9 from telemetry.core import exceptions
9 from telemetry.core import util 10 from telemetry.core import util
10 11
11 12
12 class FastNavigationProfileExtender(object): 13 class FastNavigationProfileExtender(object):
13 """Extends a Chrome profile. 14 """Extends a Chrome profile.
14 15
15 This class creates or extends an existing profile by performing a set of tab 16 This class creates or extends an existing profile by performing a set of tab
16 navigations in large batches. This is accomplished by opening a large number 17 navigations in large batches. This is accomplished by opening a large number
17 of tabs, simultaneously navigating all the tabs, and then waiting for all the 18 of tabs, simultaneously navigating all the tabs, and then waiting for all the
18 tabs to load. This provides two benefits: 19 tabs to load. This provides two benefits:
19 - Takes advantage of the high number of logical cores on modern CPUs. 20 - Takes advantage of the high number of logical cores on modern CPUs.
20 - The total time spent waiting for navigations to time out scales linearly 21 - The total time spent waiting for navigations to time out scales linearly
21 with the number of batches, but does not scale with the size of the 22 with the number of batches, but does not scale with the size of the
22 batch. 23 batch.
23 """ 24 """
24 def __init__(self): 25 def __init__(self):
25 super(FastNavigationProfileExtender, self).__init__() 26 super(FastNavigationProfileExtender, self).__init__()
26 27
28 # The path of the profile that the browser will use while its running.
sullivan 2015/02/18 21:18:05 nit: it's
erikchen 2015/02/18 22:04:01 Done.
29 # This member is initialized during SetUp().
30 self.profile_path = None
31
27 # A reference to the browser that will be performing all of the tab 32 # A reference to the browser that will be performing all of the tab
28 # navigations. 33 # navigations.
34 # This member is initialized during SetUp().
29 self._browser = None 35 self._browser = None
30 36
31 # A static copy of the urls that this class is going to navigate to.
32 self._navigation_urls = None
33
34 # The number of tabs to use. 37 # The number of tabs to use.
35 self._NUM_TABS = 15 38 # This member is initialized during SetUp().
36 39 self._NUM_TABS = None
nednguyen 2015/02/18 22:43:14 Why not make this a parameter in the constructor?
erikchen 2015/02/18 23:32:30 Done.
37 # The number of pages to load in parallel.
38 self._NUM_PARALLEL_PAGES = 15
39
40 assert self._NUM_PARALLEL_PAGES <= self._NUM_TABS, (' the batch size can\'t'
41 ' be larger than the number of available tabs')
42 40
43 # The amount of time to wait for a batch of pages to finish loading. 41 # The amount of time to wait for a batch of pages to finish loading.
44 self._BATCH_PAGE_LOAD_TIMEOUT_IN_SECONDS = 10 42 self._BATCH_PAGE_LOAD_TIMEOUT_IN_SECONDS = 10
45 43
46 # The default amount of time to wait for the retrieval of the URL of a tab. 44 # The default amount of time to wait for the retrieval of the URL of a tab.
47 self._TAB_URL_RETRIEVAL_TIMEOUT_IN_SECONDS = 1 45 self._TAB_URL_RETRIEVAL_TIMEOUT_IN_SECONDS = 1
48 46
49 def Run(self, finder_options): 47 def Run(self, finder_options):
50 """Extends the profile. 48 """Extends the profile.
51 49
52 Args: 50 Args:
53 finder_options: An instance of BrowserFinderOptions that contains the 51 finder_options: An instance of BrowserFinderOptions that contains the
54 directory of the input profile, the directory to place the output 52 directory of the input profile, the directory to place the output
55 profile, and sufficient information to choose a specific browser binary. 53 profile, and sufficient information to choose a specific browser binary.
56 """ 54 """
57 try: 55 try:
58 self._navigation_urls = self.GetUrlsToNavigate() 56 self.SetUp(finder_options)
59 self._SetUpBrowser(finder_options)
60 self._PerformNavigations() 57 self._PerformNavigations()
61 finally: 58 finally:
62 self._TearDownBrowser() 59 self.TearDown()
63 60
64 def GetUrlsToNavigate(self): 61 def GetUrlsToNavigate(self, maximum_batch_size):
65 """Returns a list of urls to be navigated to. 62 """Gets URLs for the browser to navigate to.
63
64 Intended for subclass override.
65
66 Args:
67 maximum_batch_size: A positive integer indicating the maximum allowed
68 length of the returned list.
69 Returns:
70 A list of urls to be navigated to.
71 """
72 raise NotImplementedError()
73
74 def ShouldExit(self):
75 """Returns a boolean indicating whether profile extension is finished.
66 76
67 Intended for subclass override. 77 Intended for subclass override.
68 """ 78 """
69 raise NotImplementedError() 79 raise NotImplementedError()
70 80
81 def NumTabs(self):
82 """Returns the number of tabs to simultaneously load pages in.
83
84 Can be overridden by subclasses.
85 """
86 return multiprocessing.cpu_count()
nednguyen 2015/02/18 22:43:14 Why do you think hat number of tabs should equal n
erikchen 2015/02/18 23:32:30 I moved this logic into the specific subclasses, a
87
88 def SetUp(self, finder_options):
89 """Finds the browser, starts the browser, and opens the requisite number of
90 tabs.
91
92 Can be overridden by subclasses. Subclasses must call the super class
93 implementation.
94 """
95 self.profile_path = finder_options.output_profile_path
96 self._NUM_TABS = self.NumTabs()
97 possible_browser = self._GetPossibleBrowser(finder_options)
98 self._browser = possible_browser.Create(finder_options)
sullivan 2015/02/18 21:18:05 I think there are some browser types this won't wo
erikchen 2015/02/18 22:04:01 I added asserts for "supports_tab_control" and os
99
100 while(len(self._browser.tabs) < self._NUM_TABS):
101 self._browser.tabs.New()
102
103 def TearDown(self):
104 """Teardown that is guaranteed to be executed before the instance is
105 destroyed.
106
107 Can be overridden by subclasses. Subclasses must call the super class
108 implementation.
109 """
110 if self._browser:
111 self._browser.Close()
112 self._browser = None
113
114 def FinishedNavigationOfBatch(self):
nednguyen 2015/02/18 22:43:14 CleanUpAfterBatchNavigation
erikchen 2015/02/18 23:32:30 Done.
115 """A hook for subclasses to perform cleanup after each batch of
116 navigations.
117
118 Can be overridden by subclasses.
119 """
120 pass
71 121
72 def _GetPossibleBrowser(self, finder_options): 122 def _GetPossibleBrowser(self, finder_options):
73 """Return a possible_browser with the given options.""" 123 """Return a possible_browser with the given options."""
74 possible_browser = browser_finder.FindBrowser(finder_options) 124 possible_browser = browser_finder.FindBrowser(finder_options)
75 if not possible_browser: 125 if not possible_browser:
76 raise browser_finder_exceptions.BrowserFinderException( 126 raise browser_finder_exceptions.BrowserFinderException(
77 'No browser found.\n\nAvailable browsers:\n%s\n' % 127 'No browser found.\n\nAvailable browsers:\n%s\n' %
78 '\n'.join(browser_finder.GetAllAvailableBrowserTypes(finder_options))) 128 '\n'.join(browser_finder.GetAllAvailableBrowserTypes(finder_options)))
79 finder_options.browser_options.browser_type = ( 129 finder_options.browser_options.browser_type = (
80 possible_browser.browser_type) 130 possible_browser.browser_type)
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 205
156 seconds_to_wait = end_time - time.time() 206 seconds_to_wait = end_time - time.time()
157 seconds_to_wait = max(0, seconds_to_wait) 207 seconds_to_wait = max(0, seconds_to_wait)
158 208
159 try: 209 try:
160 tab.WaitForDocumentReadyStateToBeComplete(seconds_to_wait) 210 tab.WaitForDocumentReadyStateToBeComplete(seconds_to_wait)
161 except (util.TimeoutException, exceptions.DevtoolsTargetCrashException): 211 except (util.TimeoutException, exceptions.DevtoolsTargetCrashException):
162 # Ignore time outs and web page crashes. 212 # Ignore time outs and web page crashes.
163 pass 213 pass
164 214
165 def _SetUpBrowser(self, finder_options):
166 """Finds the browser, starts the browser, and opens the requisite number of
167 tabs."""
168 possible_browser = self._GetPossibleBrowser(finder_options)
169 self._browser = possible_browser.Create(finder_options)
170
171 for _ in range(self._NUM_TABS):
172 self._browser.tabs.New()
173
174 def _PerformNavigations(self): 215 def _PerformNavigations(self):
175 """Performs the navigations specified by |_navigation_urls| in large 216 """Repeatedly fetches a batch of urls, and navigates to those urls. This
176 batches.""" 217 will run until an empty batch is returned, or ShouldExit() returns True.
177 # The index of the first url that has not yet been navigated to. 218 """
178 navigation_url_index = 0
179 while True: 219 while True:
180 # Generate the next batch of navigations. 220 # Generate the next batch of navigations.
221 urls = self.GetUrlsToNavigate(self._NUM_TABS)
222 if len(urls) == 0:
223 break
224
181 batch = [] 225 batch = []
182 max_index = min(navigation_url_index + self._NUM_PARALLEL_PAGES, 226 for i in range(len(urls)):
183 len(self._navigation_urls)) 227 url = urls[i]
184 for i in range(navigation_url_index, max_index): 228 tab = self._browser.tabs[i]
185 url = self._navigation_urls[i]
186 tab = self._browser.tabs[i % self._NUM_TABS]
187 batch.append((tab, url)) 229 batch.append((tab, url))
188 navigation_url_index = max_index
189 230
190 queued_tabs = self._BatchNavigateTabs(batch) 231 queued_tabs = self._BatchNavigateTabs(batch)
191 self._WaitForQueuedTabsToLoad(queued_tabs) 232 self._WaitForQueuedTabsToLoad(queued_tabs)
192 233
193 if navigation_url_index == len(self._navigation_urls): 234 self.FinishedNavigationOfBatch()
235
236 if self.ShouldExit():
nednguyen 2015/02/18 22:43:14 Just looking at this method name, it's unclear to
erikchen 2015/02/18 23:32:30 Done.
194 break 237 break
195
196 def _TearDownBrowser(self):
197 """Teardown that is guaranteed to be executed before the instance is
198 destroyed."""
199 if self._browser:
200 self._browser.Close()
201 self._browser = None
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698