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

Spec percent-scripts-timeout #1341

Merged
merged 41 commits into from
Nov 26, 2024
Merged
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
b0aa11e
Reserved.once specification.
Nov 1, 2024
633def4
Some metrics stuff, but it's a bit off for re-run, so need to think some
Oct 30, 2024
055b0f5
Fix handwaveyness of fetch metrics.
Nov 5, 2024
0ed6ce3
Fix the re-run thing, and a bit of prep for later.
Nov 5, 2024
0a71b5b
Fix formatting.
Nov 5, 2024
5167149
Fix bug + misc found in feedback.
Nov 6, 2024
afddb46
Merge branch 'reserved-once2' into more-metric1-b
Nov 6, 2024
3cbf3f9
Typo fix.
Nov 6, 2024
22426a1
Wire timeout from most script helpers.
Nov 6, 2024
98197a9
Start on actual computation.
Nov 6, 2024
36c79a2
k-anon only. The impl gets it wrong.
Nov 6, 2024
72f1b03
Merge branch 'more-metric1-b' into more-metrics2
Nov 6, 2024
0e4697f
generateBid computation.
Nov 6, 2024
03fc7ab
report*
Nov 6, 2024
a427a2b
And add the base value itself.
Nov 6, 2024
89f62b9
Fix participating IG count computation.
Nov 6, 2024
fa06d95
Merge branch 'more-metric1-b' into more-metrics2
Nov 6, 2024
f5a3249
Back to always.
Nov 6, 2024
00d698c
Merge branch 'more-metric1-b' into more-metrics2
Nov 6, 2024
0b1b2c3
Fix the reportAdditionalWin case.
Nov 6, 2024
4caa43a
Improve report-win enum at suggestion.
Nov 6, 2024
9d452c1
Merge branch 'main' into reserved-once2
Nov 7, 2024
956b1de
Merge branch 'reserved-once2' into more-metric1-b
Nov 7, 2024
4343fc5
Merge branch 'more-metric1-b' into more-metrics2
Nov 7, 2024
0f5a97b
Fix edit mishap
Nov 7, 2024
e363f8c
Merge branch 'main' into more-metric1-b
Nov 18, 2024
5f1dc7b
Apply feedback
Nov 18, 2024
c9fb6d1
Apply feedback
Nov 19, 2024
136ca90
+ PA contributions type
Nov 19, 2024
c5e3ba4
More feedback
Nov 19, 2024
5b376a5
More phrasing tweaks.
Nov 19, 2024
64f0e34
Merge branch 'more-metric1-b' into more-metrics2 (and use increment in
Nov 20, 2024
318c480
More add -> increment
Nov 20, 2024
f16bcef
Merge branch 'main' into more-metric1-b
Nov 20, 2024
0d9fb70
Merge branch 'more-metric1-b' into more-metrics2
Nov 20, 2024
af730a8
Some feedback
Nov 25, 2024
bb5466a
Fix the error case Qingxin pointed out.
Nov 25, 2024
c8fec8f
Explain 110%
Nov 25, 2024
fd5dd85
Fix the parse error case Qingxin pointed out, lack of timeout on
Nov 25, 2024
0d71e23
Fix the lack of timeout on ScriptExecution.
Nov 25, 2024
2012e65
More feedback
Nov 26, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 89 additions & 29 deletions spec.bs
Original file line number Diff line number Diff line change
Expand Up @@ -2372,10 +2372,14 @@ or "component-auction", a [=currency tag=] |componentAuctionExpectedCurrency|, a
1. [=Add a sample to an averager=] given |metrics|'s [=per participant metrics/code fetch time
averager=] and |decisionLogicFetcher|'s [=script fetcher/fetch duration=].
1. Let « |scoreAdResult|, |debugWinReportUrl|, |debugLossReportUrl|, |realTimeContributions|,
|paContributions| » be the result of [=evaluating a scoring script=] with |decisionLogicScript|,
|adMetadata|, |bidValue|'s [=bid with currency/value=], |auctionConfig|, |reportingContext|,
|sameOriginTrustedScoringSignals|, |crossOriginTrustedScoringSignals|, |browserSignals|,
|directFromSellerSignalsForSeller|, and |auctionConfig|'s [=auction config/seller timeout=].
|paContributions|, |executionMetrics| » be the result of [=evaluating a scoring script=] with
|decisionLogicScript|, |adMetadata|, |bidValue|'s [=bid with currency/value=], |auctionConfig|,
|reportingContext|, |sameOriginTrustedScoringSignals|, |crossOriginTrustedScoringSignals|,
|browserSignals|, |directFromSellerSignalsForSeller|, and |auctionConfig|'s [=auction config/
seller timeout=].
1. Increment |metrics|'s [=per participant metrics/script executions attempted=] by 1.
1. If |executionMetrics|'s [=execution metrics/script timed out=] is true, increment |metrics|'s
[=per participant metrics/script timeouts occurred=] by 1.
1. If |generatedBid|'s [=generated bid/for k-anon auction=] is true:

Note: Non-k-anonymous bids do not participate in reporting (except for platform real-time
Expand Down Expand Up @@ -2918,13 +2922,17 @@ and a [=global object=] |global|:
|sellerReportingScriptFetcher|.
1. [=Add a sample to an averager=] given |metrics|'s [=per participant metrics/code fetch time
averager=] and |sellerReportingScriptFetcher|'s [=script fetcher/fetch duration=].
1. Let « |sellerSignals|, |reportUrl|, |reportingBeaconMap|, ignored, |paContributions| » be the
result of [=evaluating a reporting script=] with |sellerReportingScript|, "`reportResult`",
|reportingContext|, |config|'s [=auction config/seller=], |config|'s
1. Let « |sellerSignals|, |reportUrl|, |reportingBeaconMap|, ignored, |paContributions|,
|executionMetrics| » be the result of [=evaluating a reporting script=] with
|sellerReportingScript|, "`reportResult`", |reportingContext|,
|config|'s [=auction config/seller=], |config|'s
[=auction config/seller Private Aggregation coordinator=], |config|'s [=auction config/
config idl=]'s {{AuctionAdConfig/reportingTimeout}}, and
« |config|'s [=auction config/config idl=], |browserSignals|, |directFromSellerSignals| ».
1. Let |reportingResult| be a [=reporting result=] with the following [=struct/items=]:
1. Set |metrics|'s [=per participant metrics/script executions attempted=] to 1.
1. If |executionMetrics|'s [=execution metrics/script timed out=] is true, set |metrics|'s
[=per participant metrics/script timeouts occurred=] to 1.
1. Let |reportingResult| be a [=reporting result=] with the following [=struct/items=]:
: [=reporting result/report url=]
:: |reportUrl|
: [=reporting result/reporting beacon map=]
Expand Down Expand Up @@ -3021,14 +3029,18 @@ a {{ReportingBrowserSignals}} |browserSignals|, a [=direct from seller signals=]
1. Let |reportFunctionName| be "`reportWin`".
1. If |winner|'s [=generated bid/provided as additional bid=] is true:
1. Set |reportFunctionName| be "`reportAdditionalBidWin`".
1. Let « ignored, |resultUrl|, |reportingBeaconMap|, |reportingMacroMap|, |paContributions| » be
the result of [=evaluating a reporting script=] with |buyerReportingScript|,
|reportFunctionName|, |reportingContext|, |ig|'s [=interest group/owner=], |ig|'s [=interest
group/Private Aggregation coordinator=], |leadingBidInfo|'s [=leading bid info/auction config=]'s
1. Let « ignored, |resultUrl|, |reportingBeaconMap|, |reportingMacroMap|, |paContributions|,
|executionMetrics| » be the result of [=evaluating a reporting script=] with
|buyerReportingScript|, |reportFunctionName|, |reportingContext|, |ig|'s
[=interest group/owner=], |ig|'s [=interest group/
Private Aggregation coordinator=], |leadingBidInfo|'s [=leading bid info/auction config=]'s
[=auction config/config idl=]'s {{AuctionAdConfig/reportingTimeout}}, and
« |leadingBidInfo|'s [=leading bid info/auction config=]'s [=auction config/config idl=]'s
{{AuctionAdConfig/auctionSignals}}, |perBuyerSignalsForBuyer|, |sellerSignals|,
|reportWinBrowserSignals|, |directFromSellerSignals| ».
1. Set |metrics|'s [=per participant metrics/script executions attempted=] to 1.
1. If |executionMetrics|'s [=execution metrics/script timed out=] is true, set |metrics|'s
[=per participant metrics/script timeouts occurred=] to 1.
1. [=Commit private aggregation contributions=] given |paContributions|, |winner|'s [=generated
bid/reporting id=] and |reportingContext|.
1. Set |leadingBidInfo|'s [=leading bid info/buyer reporting result=] to a [=reporting result=]
Expand Down Expand Up @@ -3719,6 +3731,10 @@ auction in a multi-party auction).
|ig|'s [=interest group/owner=], [=worklet function/generate-bid=].
1. [=Merge samples to an averager=] given |metrics|'s [=per participant metrics/code fetch time
averager=] and |executionMetrics|'s [=execution metrics/code fetch time averager=].
1. Set |metrics|'s [=per participant metrics/script executions attempted=] to
|metrics|'s [=per participant metrics/participating interest group count=].
1. If |executionMetrics|'s [=execution metrics/script timed out=] is true, increment |metrics|'s
[=per participant metrics/script timeouts occurred=] by 1.
1. [=set/Insert=] |id| into |reportingContext|'s [=reporting context/bidder participants=].
1. [=Commit private aggregation contributions=] given |paContributions|, |id| and
|reportingContext|.
Expand Down Expand Up @@ -4124,6 +4140,9 @@ A signal base value is one of the following:
auction, after considering prioritization and capabilities. Interest groups included in this might
not actually get to bid if the cumulative timeout expires, or the script fails to load, etc; or
might decide not to bid, but they would have gotten a chance if nothing went wrong.
: "<dfn><code>percent-scripts-timeout</code></dfn>"
:: The numeric value is percentage of executions of this script that hit their individual timeout,
out of all executions that were expected to happen.

</dl>

Expand Down Expand Up @@ -4212,6 +4231,9 @@ metrics collected from a single execution of a worklet function:
<dl dfn-for="execution metrics">
: <dfn>code fetch time averager</dfn>
:: An [=averager=].
: <dfn>script timed out</dfn>
:: A [=boolean=], initially false. This refers to the script hitting its own time out, and does
not include the cumulative timeout affecting buyers.
</dl>

A <dfn>per participant metrics</dfn> is a [=struct=] with the following [=struct/items=],
Expand All @@ -4221,6 +4243,10 @@ representing metrics aggregated over a particular participant (e.g. bidder or se
:: A {{long}}, initially 0.
: <dfn>code fetch time averager</dfn>
:: An [=averager=].
: <dfn>script timeouts occurred</dfn>
:: A {{long}}, initially 0.
: <dfn>script executions attempted</dfn>
:: A {{long}}, initially 0.
</dl>

<h4 dfn-type=dfn>Private Aggregation contributions</h4>
Expand Down Expand Up @@ -4582,6 +4608,26 @@ They return a {{double}}.
participant metrics/code fetch time averager=].
1. If |signalBaseValue| is "<code>[=signal base value/participating-ig-count=]</code>":
1. Return |bidAndScoreMetrics|'s [=per participant metrics/participating interest group count=].
1. If |signalBaseValue| is "<code>[=signal base value/percent-scripts-timeout=]</code>":
1. Return the result of [=computing a percentage metric=] given |metrics|'s [=per participant
metrics/script timeouts occurred=] and |metrics|'s [=per participant metrics/script executions
attempted=].

</div>

<div algorithm>
To <dfn>compute a percentage metric</dfn> given {{long}}s |numerator| and |denominator|:
1. If |denominator| is 0, return 0.
1. Let |result| be 100.0 * |numerator| / |denominator|, performing the computation with
{{double}}s.
1. If |result| &gt; 110.0, set |result| to 110.0
qingxinwu marked this conversation as resolved.
Show resolved Hide resolved

Note: Since [=perform storage maintenance|Interest Group Storage Maintenance=] happens
periodically, metrics measuring storage utilization <span class="allow-2119">may</span> report
values that exceed 100%. The 110% cap exists to make it easier to allocate histogram bucket space
for those metrics, by providing a predictable upper bound.

1. Return |result|.

</div>

Expand Down Expand Up @@ -5531,7 +5577,8 @@ of the following global objects:
1. Let |crossOriginTrustedBiddingSignalsJS| be |crossOriginTrustedBiddingSignals|
[=converted to ECMAScript values=].
1. Let |startTime| be |settings|'s [=environment settings object/current monotonic time=].
1. Let |result| be the result of [=evaluating a script=] with |realm|, |script|, "`generateBid`",
1. Let (|result|, |executionMetrics|'s [=execution metrics/script timed out=]) be the
result of [=evaluating a script=] with |realm|, |script|, "`generateBid`",
« |igJS|, |auctionSignalsJS|, |perBuyerSignalsJS|, |sameOriginTrustedBiddingSignalsJS|,
|browserSignalsJS|, |directFromSellerSignalsJS|, |crossOriginTrustedBiddingSignalsJS| »,
and |timeout|.
Expand Down Expand Up @@ -5614,7 +5661,9 @@ of the following global objects:
1. Let |directFromSellerSignalsJs| be |directFromSellerSignalsForSeller|
[=converted to ECMAScript values=].
1. Let |startTime| be |settings|'s [=environment settings object/current monotonic time=].
1. Let |scoreAdResult| be the result of [=evaluating a script=] with |realm|, |script|, "`scoreAd`",
1. Let |executionMetrics| be a new [=execution metrics=].
1. Let (|scoreAdResult|, |executionMetrics|'s [=execution metrics/script timed out=]) be
the result of [=evaluating a script=] with |realm|, |script|, "`scoreAd`",
«|adMetadata|, |bidValue|, |auctionConfigJS|, |sameOriginTrustedScoringSignalsJS|,
|browserSignalsJS|, |directFromSellerSignalsJs|, |crossOriginTrustedScoringSignalsJS|»,
and |timeout|.
Expand All @@ -5636,7 +5685,7 @@ of the following global objects:
1. Let |paContributions| be the result of [=extracting private aggregation contributions=] given
|global|.
1. Return « |scoreAdResult|, |debugWinReportUrl|, |debugLossReportUrl|, |realTimeContributions|,
|paContributions| ».
|paContributions|, |executionMetrics| ».
</div>

<div algorithm>
Expand All @@ -5654,9 +5703,12 @@ of the following global objects:
and |privateAggregationCoordinator|.
1. Let |argumentsJS| be the result of [=converting a Web IDL arguments list to an ECMAScript
arguments list|converting=] |arguments| to an ECMAScript arguments list. If this
[=exception/throws=] an exception, return « "null", null, null, null ».
1. Let |result| be the result of [=evaluating a script=] with |realm|, |script|,
|functionName|, |argumentsJS|, and |timeout|.
[=exception/throws=] an exception, return « "null", null, null, null, a new [=Private
Aggregation Contributions=], |executionMetrics| ».
1. Let |executionMetrics| be a new [=execution metrics=].
1. Let (|result|, |executionMetrics|'s [=execution metrics/script timed out=]) be the
result of [=evaluating a script=] with |realm|, |script|, |functionName|, |argumentsJS|,
and |timeout|.
1. If |result| is an [=ECMAScript/abrupt completion=], return « "null", null, null, null ».
1. Let |resultJSON| be "null".
1. If |functionName| is "`reportResult`", then set |resultJSON| to the result of
Expand All @@ -5673,20 +5725,23 @@ of the following global objects:
|global|.
1. Return « |resultJSON|, |reportURL|,
|global|'s [=InterestGroupReportingScriptRunnerGlobalScope/reporting beacon map=], |macroMap|,
|paContributions| ».
|paContributions|, |executionMetrics| ».
</div>

<div algorithm>
To <dfn>evaluate a script</dfn> with a [=ECMAScript/realm=] |realm|, [=string=] |script|, [=string=]
|functionName|, a [=list=] |arguments|, and an integer millisecond [=duration=] |timeout|, run these steps.
They return a [=ECMAScript/Completion Record=], which is either an [=ECMAScript/abrupt completion=] (in
the case of a parse failure or execution error), or a [=ECMAScript/normal completion=] populated with the
[=ECMAScript/ECMAScript language value=] result of invoking |functionName|.
They return a tuple of a [=ECMAScript/Completion Record=], which is either an [=ECMAScript/abrupt
completion=] (in the case of a parse failure or execution error), or a [=ECMAScript/normal
completion=] populated with the [=ECMAScript/ECMAScript language value=] result of invoking
|functionName|, and a [=boolean=] stating whether the script was interrupted due to reaching
|timeout|.

1. [=Assert=] that these steps are running [=in parallel=].

1. If |timeout| &le; 0, [=immediately=] interrupt the execution and set |finalCompletion| to a
new [=ECMAScript/throw completion=] given null.
1. If |timeout| &le; 0, return (new [=ECMAScript/throw completion=] given null, true).
Copy link
Collaborator

Choose a reason for hiding this comment

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

need to update line 5745 below as well to return an extra false?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

.... good catch, though this needs more work: the timeout applies to top-level execution as well. I am gonna need an extra moment on that.

(Actually it also affects WebIDL conversions of return values, since otherwise one could smuggle entire computation into them, but I am not sure how one even hooks that)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Fixed, but kinda hand-wavish. PTAL.

Copy link
Collaborator

@qingxinwu qingxinwu Nov 26, 2024

Choose a reason for hiding this comment

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

for webIDL conversion you mentioned, is it https://github.com/WICG/turtledove/blob/main/spec.bs#L5620, or something else?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yeah. That can run arbitrary code[1] (so it probably ought to be explicit about what context it runs in).
Same for scoreAd. Compare to:

https://source.chromium.org/chromium/chromium/src/+/main:content/services/auction_worklet/seller_worklet.cc;drc=b41d6ee12deac18fac89f4d27c2a662e311406fc;l=1232

(which I think I owe refactor of, but it's a little easier to read for this purpose than the bidder equivalent since the business stuff isn't hidden in the binding. Notice how it uses the same time limit; the v8_helper also provides the context).

[1] We have a couple other places this used where we start with more restricted types (sometimes infra types) where nothing funky can happen, as it's doing some sort of "round a double to int" type deals. It's where the source is an Object that JS gets... JS.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Copy link
Collaborator

@qingxinwu qingxinwu Nov 26, 2024

Choose a reason for hiding this comment

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

does the js->idl conversion need the script's context? It does not seem so, IIUC. Then we can probably return the remaining timeout after script execution, and apply it to the js->IDL conversion step?
Not suggesting to do it in this PR, but wondering whether and how we fix it in spec.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think the context isn't explicit in the way the WebIDL and ES262 specs works, e.g. it calls ops like this:
https://tc39.es/ecma262/multipage/abstract-operations.html#sec-tonumber

Compare to:
https://source.chromium.org/chromium/chromium/src/+/main:v8/include/v8-value.h;drc=6ac7875f61c72fa111bc501039e4673693be6b64;l=384

...so I suppose returning the remaining timeout and having a similar thing about timeouts on those spec is appropriate.

Copy link
Collaborator

Choose a reason for hiding this comment

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

sounds good.


1. Let |timedOut| be false.

1. Let |global| be |realm|'s [=realm/global object=], and run these steps in |realm|'s [=realm/agent=]:

Expand All @@ -5696,7 +5751,7 @@ of the following global objects:
unlike traditional [=scripts=] on the web platform.

1. If |result| is a list of errors, return
Completion { \[[Type]]: `throw`, \[[Value]]: |result|, \[[Target]]: `empty` }.
(Completion { \[[Type]]: `throw`, \[[Value]]: |result|, \[[Target]]: `empty` }, false).

1. [=Assert=]: |result| is a [=ECMAScript/Script Record=].

Expand All @@ -5706,6 +5761,11 @@ of the following global objects:

1. Let |evaluationStatus| be the result of [$ScriptEvaluation$](result).

In |timeout| milliseconds, if the invocation of [$ScriptEvaluation$] has not completed,
[=immediately=] interrupt the execution, set |finalCompletion| to a new
[=ECMAScript/throw completion=] given null, set |timedOut| to true, and jump to the step
labeled <i><a href="#evaluate-script-return">return</a></i>.

1. If |evaluationStatus| is an [=ECMAScript/abrupt completion=], jump to the step labeled <i>
<a href="#evaluate-script-return">return</a></i>.

Expand All @@ -5716,9 +5776,9 @@ of the following global objects:
1. Set |finalCompletion| be [=ECMAScript/Completion Record|Completion=]([$Call$](F, `undefined`,
|arguments|)).

In |timeout| milliseconds, if the invocation of [$Call$] has not completed,
[=immediately=] interrupt the execution and set |finalCompletion| to a new
[=ECMAScript/throw completion=] given null.
In |timeout| milliseconds minus the execution time of [$ScriptEvaluation$], if the invocation
of [$Call$] has not completed, [=immediately=] interrupt the execution, set |finalCompletion|
to a new [=ECMAScript/throw completion=] given null, and set |timedOut| to true.

1. <i id=evaluate-script-return>Return</i>: at this point |finalCompletion| will be set to a
[=ECMAScript/Completion Record=].
Expand All @@ -5727,7 +5787,7 @@ of the following global objects:
execution context|running JavaScript execution context=], and remove it from the
[=ECMAScript/execution context stack|JavaScript execution context stack=].

1. Return |finalCompletion|.
1. Return (|finalCompletion|, timedOut).
</div>

## Global scopes ## {#global-scopes}
Expand Down