Best practice for scheduling longer running job at startup?

98 views
Skip to first unread message

Dominik Röttsches

unread,
Jan 18, 2019, 10:22:53 AM1/18/19
to Chromium-dev, Emil A Eklund
Hi,

I am working on fixing local unique font matching, and the implementation I have on Windows builds a ReadOnlySharedMemoryRegion containing a lookup structure from which the renderer can find fonts by uniquely matching by name. This is triggered on the first DWriteFontProxy Mojo call from the renderer looking up a @font-face { src: local(<name>) } font.

Triggering this lazily introduces too high a latency as it can take from 50 (beefy developer machine) to 1300ms (slow machine) depending on machine performance, with the average somewhere at 500-600ms. We don't want to stall the renderer for that long, and even if it wasn't a synchronous call, we could make this faster for the renderer by scheduling a low priority task to start building that lookup structure.

To this end, I am wondering, what is the best practice for scheduling a post startup task? 

I see many approaches in the code base doing, this:
Is BrowserThread::PostAfterStartupTask still the right way to this?

Which startup stage should I choose, PreProfileInit? From which stage do the BrowserThread::PostAfterStartupTask tasks start running from?

I've seen connection->GetConnector()->WarmService(...) as well - but to me it seems that is not suitable as the lookup table that needs to be build needs to be kept between instances of the service going up or down.

Where would I place this so that it's shared across all relevant "browser-like process", i.e. the same tasks gets posted for content_shell and the chrome browser executable.

Thanks for any pointers,

Dominik

Alex Clarke

unread,
Jan 18, 2019, 11:31:08 AM1/18/19
to dr...@chromium.org, Chromium-dev, Emil A Eklund
If you can move it off the UI thread, by using base::PostTask() that would be great.

--
--
Chromium Developers mailing list: chromi...@chromium.org
View archives, change email options, or unsubscribe:
http://groups.google.com/a/chromium.org/group/chromium-dev
---
You received this message because you are subscribed to the Google Groups "Chromium-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to chromium-dev...@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/chromium-dev/CAN6muBtpaomJB31gztTbEMvcTw-aegN9GtnwgRxAgNOTUV1YeQ%40mail.gmail.com.

Wez

unread,
Jan 18, 2019, 12:06:32 PM1/18/19
to Alex Clarke, dr...@chromium.org, Chromium-dev, Emil A Eklund
What kind of work does this task do for up-to-1.5-seconds?  e.g. is it CPU-bound, or I/O-bound, or some mix of the two?

Running a 1.5 second task on every startup seems pretty expensive, and also suggests that the resulting lookup table may be rather large?

Dominik Röttsches

unread,
Jan 18, 2019, 12:20:23 PM1/18/19
to Wez, Alex Clarke, Chromium-dev, Emil A Eklund
Hi Wez,


On Fri, Jan 18, 2019, 19:05 Wez <w...@chromium.org wrote:
What kind of work does this task do for up-to-1.5-seconds?  e.g. is it CPU-bound, or I/O-bound, or some mix of the two?

It is a mix with a focus on i/o as much as I can tell, but it's really inside DirectWrite. We're enumerating system fonts and retrieving name properties from them using DWrite API. To which degree this data is cached inside DirectWrite and to which it needs to be loaded from the fonts and access the disk, I cannot tell.


> Running a 1.5 second task on every startup seems pretty expensive, and also suggests that the resulting lookup table may be rather large?

The size of the lookup table is between 40kb and 120kb, rather on the lower end. And we can limit that if a user has an excessitve amount of fonts installed.

The 1.5 second task duration is on the very slow end, it's rather a bit lower than that in most cases.

On Android, the implementation persists this lookup structure, but the key for updating it there is easy: we only need to detect a firmware update.

Persisting this on Windows is a lot more difficult as fonts on the system can have changed and building a detection for this is hard. In addition we have been painfully bitten by persisting cached data about fonts on Windows before

Even if it would be persisted on Windows, we would still need to solve the case of the first startup and all startups where fonts have changed.

Dominik

Dominik Röttsches

unread,
Jan 18, 2019, 12:34:49 PM1/18/19
to Wez, Alex Clarke, Chromium-dev, Emil A Eklund

Wez

unread,
Jan 18, 2019, 5:39:28 PM1/18/19
to Dominik Röttsches, Alex Clarke, Chromium-dev, Emil A Eklund
Thanks for the extra context :)

Patrick Monette

unread,
Jan 19, 2019, 10:29:41 AM1/19/19
to w...@chromium.org, Dominik Röttsches, Alex Clarke, Chromium-dev, Emil A Eklund

Alex Clarke

unread,
Jan 21, 2019, 3:54:09 AM1/21/19
to Dominik Röttsches, Wez, Chromium-dev, Emil A Eklund
On Fri, 18 Jan 2019 at 17:19, Dominik Röttsches <dr...@chromium.org> wrote:
Hi Wez,

On Fri, Jan 18, 2019, 19:05 Wez <w...@chromium.org wrote:
What kind of work does this task do for up-to-1.5-seconds?  e.g. is it CPU-bound, or I/O-bound, or some mix of the two?

It is a mix with a focus on i/o as much as I can tell, but it's really inside DirectWrite. We're enumerating system fonts and retrieving name properties from them using DWrite API. To which degree this data is cached inside DirectWrite and to which it needs to be loaded from the fonts and access the disk, I cannot tell.


> Running a 1.5 second task on every startup seems pretty expensive, and also suggests that the resulting lookup table may be rather large?

The size of the lookup table is between 40kb and 120kb, rather on the lower end. And we can limit that if a user has an excessitve amount of fonts installed.

The 1.5 second task duration is on the very slow end, it's rather a bit lower than that in most cases.

Still sounds like we shouldn't be running this on the UI thread though.

Greg Thompson

unread,
Jan 21, 2019, 6:17:42 AM1/21/19
to pmon...@chromium.org, Wez, Dominik Röttsches, Alex Clarke, Chromium-dev, Emil A Eklund
On Sat, Jan 19, 2019 at 4:29 PM Patrick Monette <pmon...@chromium.org> wrote:
As for the original question, I think the best way to do it right now is to use https://cs.chromium.org/chromium/src/chrome/browser/after_startup_task_utils.h?sq=package:chromium&g=0&l=18

The new guidance is to use PostTaskWithTraits; see https://crbug.com/887407. Something like: base::PostTaskWithTraits(FROM_HERE, {base::TaskPriority::BEST_EFFORT, base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, ...);, but don't quote me on that.

Gabriel Charette

unread,
Jan 21, 2019, 12:20:08 PM1/21/19
to Greg Thompson, fdo...@chromium.org, scheduler-dev, pmon...@chromium.org, Wez, Dominik Röttsches, Alex Clarke, Chromium-dev, Emil Eklund
+scheduler-dev


Le lun. 21 janv. 2019 06 h 16, Greg Thompson <g...@chromium.org> a écrit :
On Sat, Jan 19, 2019 at 4:29 PM Patrick Monette <pmon...@chromium.org> wrote:
As for the original question, I think the best way to do it right now is to use https://cs.chromium.org/chromium/src/chrome/browser/after_startup_task_utils.h?sq=package:chromium&g=0&l=18

The new guidance is to use PostTaskWithTraits; see https://crbug.com/887407. Something like: base::PostTaskWithTraits(FROM_HERE, {base::TaskPriority::BEST_EFFORT, base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, ...);, but don't quote me on that.

Right, you probably don't want BEST_EFFORT though as that'll use a background thread and cause a priority inversions if a renderer blocks on it before it's done.

What we could do is introduce TaskPriority::IDLE (i.e. don't rush scheduling the task but still run it on a foreground thread when it is scheduled). We can then use our upcoming ability to toggle priority at runtime (almost ready) to switch the priority to TaskPriority::USER_BLOCKING if a renderer asks for it. That way it's effectively a lazy-eager load (i.e. eager but low priority and lazily bumped priority on demand).

If that sounds good we can do these APIs are almost ready and we can get them out to you in the next few days :)

PS: I'd rather not add more usage to PostAfterStartupTask if we can cover this use case with scheduling (we're about to remove the AfterStartup API just missing a few bits on the scheduling end).

bruce...@chromium.org

unread,
Jan 25, 2019, 7:21:09 PM1/25/19
to Chromium-dev, g...@chromium.org, fdo...@chromium.org, schedu...@chromium.org, pmon...@chromium.org, w...@chromium.org, dr...@chromium.org, alexc...@google.com, e...@chromium.org
Will you be adding metrics to record how long this task takes in the wild? Correlating that with font counts or other relevant details could also be helpful. Some users have pretty huge font collections and the disk I/O alone to query them all may be prohibitive.

Sorry for the delayed reply...
To unsubscribe from this group and stop receiving emails from it, send an email to chromium-dev+unsubscribe@chromium.org.

Dominik Röttsches

unread,
Jan 28, 2019, 4:34:08 AM1/28/19
to bruce...@chromium.org, Chromium-dev, g...@chromium.org, fdo...@chromium.org, schedu...@chromium.org, pmon...@chromium.org, w...@chromium.org, alexc...@google.com, Emil A Eklund
Hi Bruce,

On Sat, Jan 26, 2019 at 2:21 AM <bruce...@chromium.org> wrote:
Will you be adding metrics to record how long this task takes in the wild? Correlating that with font counts or other relevant details could also be helpful. Some users have pretty huge font collections and the disk I/O alone to query them all may be prohibitive.

Yes, these metrics are here: https://cs.chromium.org/chromium/src/content/browser/renderer_host/dwrite_font_proxy_impl_win.cc?type=cs&sq=package:chromium&g=0&l=771 and the initial results prompted me to switch the flag for this feature off for now, until I have found a better way of scanning the fonts earlier and not only when the first renderer asks for it. 

The idea of sampling the font count as well is a good idea. Any suggestions for making sure that I keep font counts and scanning time together? Record a ratio instead - in addition? Recording something like a combined or paired histogram if such thing exists?

Thanks,

Dominik

To unsubscribe from this group and stop receiving emails from it, send an email to chromium-dev...@chromium.org.

Bruce Dawson

unread,
Jan 28, 2019, 2:13:03 PM1/28/19
to Dominik Röttsches, Chromium-dev, Greg Thompson, Francois Pierre Doray, schedu...@chromium.org, pmon...@chromium.org, Wez, Alex Clarke, Emil A Eklund
You could have different metrics for different orders of magnitude font-counts - 0-99, 100-999, 1000+ or something like that. You might even need to 10,000+ category - I think font collectors get pretty serious.
Reply all
Reply to author
Forward
0 new messages