Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create FLEDGE_implementation_overview.md #906

Merged
merged 14 commits into from
Mar 28, 2024

Conversation

MattMenke2
Copy link
Contributor

@MattMenke2 MattMenke2 commented Nov 14, 2023

At the WICG meeting two weeks ago, folks were interested in just how timeouts worked, and what impact order (of buyers / component auction configs) potentially had when paired with timeouts. It's difficult to explain them without going into details about just how FLEDGE auctions are implemented in Chrome. This perhaps goes into a little too much detail, but this is my effort to explain cumulative timeouts in FLEDGE auctions.

Copy link
Collaborator

@morlovich morlovich left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a nice write up; hopefully I won't make it worse by suggesting two many details.

### Starting Worklet Executors
Once all interest groups are loaded, Chrome starts loading the seller worklet, and all bidder worklets participating in an auction.  To load a worklet, Chrome first checks if there is already a matching worklet “executor” (Same worklet origin, same javascript URL, wasm URL, trusted signals URL, same frame - frame match is required by the DevTools hooks. "Frame" here means the frame runAdAuction() was called in.  It may be for a different auction / component auction, however).  If so, the executor is reused.  Note that different executors do not currently share any network fetches or Javascript contexts, although they do share the same global HTTP cache, so it’s generally a good idea to try and use the same URLs for all interest groups, to maximize executor reuse.  Also, interest groups that share an executor are guaranteed to be run in the priority order they were sorted into (this may change if trusted signals fetches are split up, though).  Interest groups that don’t share an executor are run on the basis of whichever has everything it needs to run first, runs first.

Otherwise, Chrome requests a bidder or seller worklet process for the associated buyer/seller origin.  Buyers and sellers do not share processes, even if the origin is the same, though a single buyer or seller origin will globally use a single process shared by all of its executors. There are separate Chrome-wide limits on the number of buyer processes (10) and seller processes (3).  These numbers are not optimized, and subject to change.  On mobile, Chrome will generally reuse the single renderer process, instead of using more secure, isolated processes, due to resource constraints.  Within a process, all Protect Audience worklets use a single Javascript thread.  Once a process is assigned, Chrome creates an executor for the worklet, which starts loading the javascript and wasm URLs.  Because bidders share processes based on origin, this process means that all of a single bidder origin’s interest groups are assigned an executor (newly created or reused) at once.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We use two threads (bidder and seller) in the mobile case.

re: everyone getting assigned at once: we do it in chunks and return to event loop in between; that's likely beyond the abstraction level of this document, but I am not 100% sure it doesn't affect some interleavings.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated to mention bidder vs seller threads.

What chunks are you referring to?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice memory! I had completely forgotten about that stuff.

I don't think it affects interleaving of a single BidderWorklet, since it keeps a FIFO queue. If there are two BidderWorklets for a single bidder, though, it could affect the interleaving between the two worklets (particularly if there's no trusted bidding signals URL, and the JS is cached, or something).

I think I don't actually understand the implications of this well enough to talk about it.

FLEDGE_implementation_overview.md Outdated Show resolved Hide resolved
FLEDGE_implementation_overview.md Outdated Show resolved Hide resolved
Copy link
Contributor Author

@MattMenke2 MattMenke2 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the the feedback!

FLEDGE_implementation_overview.md Outdated Show resolved Hide resolved
### Starting Worklet Executors
Once all interest groups are loaded, Chrome starts loading the seller worklet, and all bidder worklets participating in an auction.  To load a worklet, Chrome first checks if there is already a matching worklet “executor” (Same worklet origin, same javascript URL, wasm URL, trusted signals URL, same frame - frame match is required by the DevTools hooks. "Frame" here means the frame runAdAuction() was called in.  It may be for a different auction / component auction, however).  If so, the executor is reused.  Note that different executors do not currently share any network fetches or Javascript contexts, although they do share the same global HTTP cache, so it’s generally a good idea to try and use the same URLs for all interest groups, to maximize executor reuse.  Also, interest groups that share an executor are guaranteed to be run in the priority order they were sorted into (this may change if trusted signals fetches are split up, though).  Interest groups that don’t share an executor are run on the basis of whichever has everything it needs to run first, runs first.

Otherwise, Chrome requests a bidder or seller worklet process for the associated buyer/seller origin.  Buyers and sellers do not share processes, even if the origin is the same, though a single buyer or seller origin will globally use a single process shared by all of its executors. There are separate Chrome-wide limits on the number of buyer processes (10) and seller processes (3).  These numbers are not optimized, and subject to change.  On mobile, Chrome will generally reuse the single renderer process, instead of using more secure, isolated processes, due to resource constraints.  Within a process, all Protect Audience worklets use a single Javascript thread.  Once a process is assigned, Chrome creates an executor for the worklet, which starts loading the javascript and wasm URLs.  Because bidders share processes based on origin, this process means that all of a single bidder origin’s interest groups are assigned an executor (newly created or reused) at once.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated to mention bidder vs seller threads.

What chunks are you referring to?

FLEDGE_implementation_overview.md Outdated Show resolved Hide resolved
FLEDGE_implementation_overview.md Outdated Show resolved Hide resolved
## Phase 1 Load Interest Groups
Immediately after runAdAuction() is invoked, all interest groups, k-anon data, and win history will be loaded from the SQLite database.  No worklets will be loaded until after this is complete, for all interestGroupBuyers participating in an auction.  Interest groups are loaded on a per-buyer basis, and remain grouped by buyer for the entire auction.  Interest groups that cannot participate in the auction (due to, e.g., no biddingLogicURL) are removed.  If there are no interest groups that can bid in the auction, and no additional bids, the auction completes without a winner, bypassing future stages.

For each bidder origin, Chrome determines a tentative priority - using each interest group’s fixed priority, or priority vector, if present.  Chrome then sorts the interest groups based on priority, removing any with priority vectors and negative priorities.  Interest groups with matching priorities are grouped by joining origin (to improve performance in case ExecutionMode is groupByOrigin).  Groups with matching joining origins and priority are randomly shuffled.  For each bidder origin, Chrome checks if any interest group participating in the auction has “enableBiddingSignalsPrioritization” set.  If not, Chrome applies the auction’s per-buyer size limit to the bidder’s interest groups.  Either way, the interest groups are now in a priority order that will affect the order in which other resources will be fetched, and worklets will be run in.  None of this affects additional bids.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

each bidder origin

Suggest s/bidder/buyer for consistency with PA terminology.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did a little replacing here. I guess in the explainer, at least, we generally use "buyer" for AuctionConfig fields, which affect all IGs owned by the same "buyer", while we often use "bidder" when referring to interest groups. This document is probably still pretty inconsistent, and some cases it's ambiguous which the text should be referring to.

@dmdabbs
Copy link
Contributor

dmdabbs commented Mar 22, 2024

Hello @MattMenke2 and team. There's really useful implementation info here that even engaged folks are just discovering because it remains an open PR. Would you kindly please consider committing it?

Copy link
Collaborator

@JensenPaul JensenPaul left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. I left a bunch of comments but none of them are particularly substantial.

PA_implementation_overview.md Outdated Show resolved Hide resolved
@@ -0,0 +1,66 @@
# Protected Audience Implementation Overview
This document is intended to give a rough overview of the Protected Audience implementation in Chrome, with a focus towards performance-relevant design decisions, and timeouts.  The purpose is to both explain how these work, and help consumers figure out if different timeouts/timeout behavior would be useful.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Github doesn't seem to work well with long lines, so it may be worth wrapping all lines to 80 or 100 columns. I don't feel strongly about this so feel free to resolve my comment if you don't think it's worth it.

Copy link
Contributor Author

@MattMenke2 MattMenke2 Mar 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Manually formatting and then reformatting each block every PR is just more effort than I'm willing to invest.

PA_implementation_overview.md Outdated Show resolved Hide resolved
PA_implementation_overview.md Outdated Show resolved Hide resolved
PA_implementation_overview.md Outdated Show resolved Hide resolved
PA_implementation_overview.md Outdated Show resolved Hide resolved
PA_implementation_overview.md Outdated Show resolved Hide resolved
PA_implementation_overview.md Outdated Show resolved Hide resolved
PA_implementation_overview.md Outdated Show resolved Hide resolved
PA_implementation_overview.md Outdated Show resolved Hide resolved
MattMenke2 and others added 2 commits March 25, 2024 11:19
Co-authored-by: Paul Jensen <JensenPaul@users.noreply.github.com>
MattMenke2 and others added 2 commits March 25, 2024 11:23
Co-authored-by: Paul Jensen <JensenPaul@users.noreply.github.com>
@JensenPaul JensenPaul merged commit c00e746 into WICG:main Mar 28, 2024
2 checks passed
github-actions bot added a commit that referenced this pull request Mar 28, 2024
SHA: c00e746
Reason: push, by JensenPaul

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
@dmdabbs
Copy link
Contributor

dmdabbs commented Mar 28, 2024

Thank you @JensenPaul

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants