Open Bug 1743857 Opened 3 years ago Updated 5 months ago

SpecialPowers.spawn tasks might not run before subsequent JSWindowActor message handlers for messages sent after the spawn

Categories

(Core :: IPC, task)

task

Tracking

()

People

(Reporter: mconley, Unassigned)

References

Details

I'm filing this in Core :: IPC because this is where SpecialPowers.spawn was introduced in bug 1532795.

I recently ran into this setup with an intermittent test failure I was investigating:

// Suppose this is script running in the parent process in a browser mochitest.
let setup = SpecialPowers.spawn(browser, [expectedIndex], async index => {
  await ContentTaskUtils.waitForEvent(
    content,
    "IndexUpdated",
    false,
    e => e.detail == index
  );
});
await BrowserTestUtils.synthesizeKey("KEY_ArrowRight", {}, browser);
await setup;

The actual scenario being tested here isn't the interesting part - it's the model that's being used: an event listener is setup inside of a SpecialPowers.spawn task, and then BrowserTestUtils.synthesizeKey is called. Both of these use IPC to communicate with the underlying content process, so by message ordering guarantees, I assumed that the event handler would always be set up before the key event is dispatched.

However, SpecialPowers does an extra step before the task message is sent down to the content process. SpecialPowers is designed to be used in both content processes and the parent process, and SpecialPowersChild is actually what you're talking to in mochitests when you refer to SpecialPowers - even for script running in the parent process. SpecialPowers.spawn causes a message to be sent to SpecialPowersParent, which finds the appropriate actor for the passed in browser, and sends the message to it to run the task.

So in the above case, that first SpecialPowers.spawn causes two messages to be sent - a message from the parent process SpecialPowersChild to the parent process SpecialPowersParent, and then the message from that SpecialPowersParent to the underlying content processes' SpecialPowersChild.

That extra step of messaging the SpecialPowersParent is a non-obvious extra step, and breaks my mental model where message ordering guaranteed that the task would run first before the synthesizing of the key.

I'm not sure what the solution is here, but filing this bug to see if there's a way to make this better. If there isn't, then this bug should perhaps be used for writing developer documentation to make this sort of thing more obvious.

I ran into this same trouble before, a solution I can think of is adding another variant of SpecialPowers.spawn which returns two Promises.

Gijs mentioned in Matrix - the other option might be to have SpecialPowersChild recognize when it's spawn is being called in the parent process, and to access the parent actor directly to send the task down to the appropriate content process, rather than queuing a same-process message.

See Also: → 1803992
See Also: → 1892091
You need to log in before you can comment on or make changes to this bug.