0

compute pressure: Change HasChangeInData to ShouldDispatch

Implementation of specification change [1].

In the new update algorithm, if sampleInterval is not set, the update
will be sent to the client only on pressure state change per source.
If sampleInterval is set, the update will be sent at sampleInterval
rate, independently of pressure state value.

[1] https://github.com/w3c/compute-pressure/pull/311

Bug: 402532202
Change-Id: Ie5f16f64c6f802d635b20b3235b5a4b334b6f727
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6346590
Reviewed-by: Reilly Grant <reillyg@chromium.org>
Commit-Queue: Arnaud Mandy <arnaud.mandy@intel.com>
Cr-Commit-Position: refs/heads/main@{#1431798}
This commit is contained in:
Arnaud Mandy
2025-03-12 15:50:42 -07:00
committed by Chromium LUCI CQ
parent 4b3e92bb07
commit 31bf92fb01
3 changed files with 43 additions and 14 deletions
third_party/blink
renderer
web_tests

@ -152,7 +152,7 @@ void PressureObserver::OnUpdate(ExecutionContext* execution_context,
return;
}
if (!HasChangeInData(source, state)) {
if (!ShouldDispatch(source, state)) {
return;
}
@ -208,16 +208,16 @@ void PressureObserver::QueuePressureRecord(ExecutionContext* execution_context,
PressureRecord* record) {
// This should happen infrequently since `records_` is supposed
// to be emptied at every callback invoking or takeRecords().
if (records_.size() >= kMaxQueuedRecords)
if (records_.size() >= kMaxQueuedRecords) {
records_.erase(records_.begin());
}
records_.push_back(record);
CHECK_LE(records_.size(), kMaxQueuedRecords);
last_record_map_[ToSourceIndex(source)] = record;
if (pending_report_to_callback_.IsActive())
if (pending_report_to_callback_.IsActive()) {
return;
}
pending_report_to_callback_ = PostCancellableTask(
*execution_context->GetTaskRunner(TaskType::kMiscPlatformAPI), FROM_HERE,
WTF::BindOnce(&PressureObserver::ReportToCallback,
@ -272,20 +272,25 @@ bool PressureObserver::PassesRateTest(
const DOMHighResTimeStamp& timestamp) const {
const auto& last_record = last_record_map_[ToSourceIndex(source)];
if (!last_record)
if (!last_record) {
return true;
}
const double time_delta_milliseconds = timestamp - last_record->time();
return time_delta_milliseconds >= static_cast<double>(sample_interval_);
}
// https://w3c.github.io/compute-pressure/#dfn-has-change-in-data
bool PressureObserver::HasChangeInData(V8PressureSource::Enum source,
V8PressureState::Enum state) const {
// https://w3c.github.io/compute-pressure/#dfn-should-dispach
bool PressureObserver::ShouldDispatch(V8PressureSource::Enum source,
V8PressureState::Enum state) const {
const auto& last_record = last_record_map_[ToSourceIndex(source)];
if (!last_record)
if (sample_interval_ != 0) {
return true;
}
if (!last_record) {
return true;
}
return last_record->state() != state;
}

@ -85,7 +85,7 @@ class MODULES_EXPORT PressureObserver final : public ScriptWrappable {
bool PassesRateTest(V8PressureSource::Enum, const DOMHighResTimeStamp&) const;
// Verifies if there is data change in between last update and new one.
bool HasChangeInData(V8PressureSource::Enum, V8PressureState::Enum) const;
bool ShouldDispatch(V8PressureSource::Enum, V8PressureState::Enum) const;
// Verifies if there is data changes in a defined time span is not too high.
bool PassesRateObfuscation(V8PressureSource::Enum) const;

@ -17,7 +17,7 @@ pressure_test(async (t) => {
});
const syncObserver = new SyncPressureObserver(t);
await syncObserver.observer().observe('cpu', {sampleInterval: 100});
await syncObserver.observer().observe('cpu');
await update_virtual_pressure_source('cpu', 'critical');
await syncObserver.waitForUpdate();
@ -32,6 +32,30 @@ pressure_test(async (t) => {
assert_equals(syncObserver.changes()[1][0].state, 'nominal');
assert_equals(syncObserver.changes().length, 2);
}, 'Changes that fail the "has change in data" test are discarded.');
}, 'Changes that fail the "should dispatch" test are discarded.');
pressure_test(async (t) => {
await create_virtual_pressure_source('cpu');
t.add_cleanup(async () => {
await remove_virtual_pressure_source('cpu');
});
const syncObserver = new SyncPressureObserver(t);
await syncObserver.observer().observe('cpu', {sampleInterval: 100});
await update_virtual_pressure_source('cpu', 'critical');
await syncObserver.waitForUpdate();
assert_equals(syncObserver.changes()[0][0].state, 'critical');
await update_virtual_pressure_source('cpu', 'critical');
await syncObserver.waitForUpdate();
assert_equals(syncObserver.changes()[1][0].state, 'critical');
await update_virtual_pressure_source('cpu', 'nominal');
await syncObserver.waitForUpdate();
assert_equals(syncObserver.changes()[2][0].state, 'nominal');
assert_equals(syncObserver.changes().length, 3);
}, 'Updates should be received even when no changes when sampleInterval is set.');
mark_as_done();