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

Async Runner with Message Channel #458

Open
wants to merge 25 commits into
base: main
Choose a base branch
from

Conversation

flashdesignory
Copy link
Contributor

@flashdesignory flashdesignory commented Nov 20, 2024

As discussed in our sync, here is a combination of the AsyncRunner and Message Channel pr.

Relevant code snippet (udpated):

class AsyncRAFTestInvoker extends BaseRAFTestInvoker {
    static mc = new MessageChannel();
    _scheduleCallbacks(resolve) {
        let gotTimer = false;
        let gotMessage = false;
        let gotPromise = false;

        const tryTriggerAsyncCallback = () => {
            if (!gotTimer || !gotMessage || !gotPromise)
                return;

            this._asyncCallback();
            setTimeout(async () => {
                await this._reportCallback();
                resolve();
            }, 0);
        };

        requestAnimationFrame(async () => {
            await this._syncCallback();
            gotPromise = true;
            tryTriggerAsyncCallback();
        });

        requestAnimationFrame(() => {
            setTimeout(() => {
                gotTimer = true;
                tryTriggerAsyncCallback();
            });

            AsyncRAFTestInvoker.mc.port1.addEventListener(
                "message",
                function () {
                    gotMessage = true;
                    tryTriggerAsyncCallback();
                },
                { once: true }
            );
            AsyncRAFTestInvoker.mc.port1.start();
            AsyncRAFTestInvoker.mc.port2.postMessage("speedometer");
        });
    }
}

For testing purposes I kept an explicit type of "async" in the test file, but I opted all default suites into using it.

Initial testing shows that it should also fix the react specific issue.

Other issue solved by this pr: #83


export const ASYNC_TEST_INVOKER_LOOKUP = {
__proto__: null,
timer: AsyncTimerTestInvoker,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

If we don't want an AsyncTimerTestInvoker, I could simply assign the same AsyncRAFTestInvoker..

@flashdesignory flashdesignory marked this pull request as ready for review November 21, 2024 02:15
@@ -125,6 +125,7 @@ Suites.push({
name: "TodoMVC-JavaScript-ES5",
url: "resources/todomvc/vanilla-examples/javascript-es5/dist/index.html",
tags: ["todomvc"],
type: "async",

Choose a reason for hiding this comment

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

So in practice all the tests are now async?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This can be reverted. For testing I marked all default tests async.
How do we decide which tests should be async? I know React / Next.js had issues with not capturing all work. Those could be candidates to mark async?

Choose a reason for hiding this comment

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

Those being async sounds good, and perhaps everything in the future should be async by default.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll leave it unchanged (opting every single workload into async steps), until I get more feedback from other folks.

resources/tests.mjs Outdated Show resolved Hide resolved
@smaug----
Copy link

Looks reasonable. @julienw do you think you could have this in some public place for testing? I could do some profiling to check if there is anything unexpected happening.

@@ -24,7 +24,24 @@ export class TimerTestInvoker extends TestInvoker {
}
}

export class RAFTestInvoker extends TestInvoker {
Copy link
Member

Choose a reason for hiding this comment

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

I'd prefer removing the TimerTestInvoker entirely since we've moved to RAF-based measurement in 3 and we haven't seen any issue with it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

removed!

@flashdesignory flashdesignory requested a review from rniwa December 11, 2024 22:39
@rniwa
Copy link
Member

rniwa commented Dec 11, 2024

Can we split the change to remove measurementMethod into a separate PR? We should also update params.mjs and developer-mode.mjs.

@flashdesignory flashdesignory force-pushed the feature/async-runner-message-channel branch from b24aa1c to acc7522 Compare December 11, 2024 22:46
@flashdesignory
Copy link
Contributor Author

Can we split the change to remove measurementMethod into a separate PR? We should also update params.mjs and developer-mode.mjs.

ok, reverted for now. I agree a cleanup pr to remove this would be better.

@bgrins
Copy link
Contributor

bgrins commented Dec 17, 2024

@smaug---- I pushed this to https://feature-async-runner-message-channel--speedometer-preview.netlify.app/ for anyone who wants to test.

return `${this.#suite.name}.${this.#test.name}-sync-end`;
}

get asyncStartLabel() {
Copy link
Member

Choose a reason for hiding this comment

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

Do we really need to add all these getters now that we're only overriding _runSyncStep?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I can revert this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

@@ -24,7 +24,24 @@ export class TimerTestInvoker extends TestInvoker {
}
}

export class RAFTestInvoker extends TestInvoker {
class AsyncTimerTestInvoker extends TestInvoker {
Copy link
Member

Choose a reason for hiding this comment

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

Can we instead just delete TimerTestInvoker as we discussed in a separate PR?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We wanted to do this in a follow up pr, correct?
If that changed, i'm happy to remove it in this pr already.

@@ -75,7 +75,8 @@ export class SuiteRunner {
if (this.#client?.willRunTest)
await this.#client.willRunTest(this.#suite, test);

const testRunner = new TestRunner(this.#frame, this.#page, this.#params, this.#suite, test, this._recordTestResults);
const testRunnerClass = TEST_RUNNER_LOOKUP[this.#suite.type ?? "default"];
Copy link
Member

Choose a reason for hiding this comment

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

Instead of changing the test runner based on the suite type for some suites, can we initially add a toggle to developer menu so that we can try out async runner?

Copy link
Contributor

Choose a reason for hiding this comment

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

To my understanding the agreement in the meeting was to unconditionally enable the new runner for the preact workloads and add the global developer-mode menu in a separate PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

correct - below is the list on enabled suites (for now):

  • TodoMVC-React-Complex-DOM,
  • TodoMVC-React-Redux,
  • TodoMVC-Preact-Complex-DOM, (technically not react based, but it's similar)
  • NewsSite-Next,
  • React-Stockcharts-SVG

Copy link
Member

Choose a reason for hiding this comment

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

If we're doing that, we need before/after numbers across browsers.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll run crossbench for the ones on the list and post results here.

Copy link
Contributor Author

@flashdesignory flashdesignory Dec 18, 2024

Choose a reason for hiding this comment

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

Here are metrics for the next.js workload:
Screenshot 2024-12-18 at 5 54 40 PM

@rniwa rniwa added the major change A change with major implications on benchmark results or affect governance policy label Dec 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
major change A change with major implications on benchmark results or affect governance policy
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants