Bug 231664 - Guarantee order of WebSocket events in case of being resumed
Summary: Guarantee order of WebSocket events in case of being resumed
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: WebCore Misc. (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: youenn fablet
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2021-10-13 02:00 PDT by youenn fablet
Modified: 2021-10-19 11:42 PDT (History)
10 users (show)

See Also:


Attachments
Patch (3.04 KB, patch)
2021-10-13 02:30 PDT, youenn fablet
no flags Details | Formatted Diff | Diff
Patch (12.20 KB, patch)
2021-10-14 04:51 PDT, youenn fablet
ews-feeder: commit-queue-
Details | Formatted Diff | Diff
Patch (12.67 KB, patch)
2021-10-14 05:13 PDT, youenn fablet
no flags Details | Formatted Diff | Diff
Patch (16.39 KB, patch)
2021-10-14 23:09 PDT, youenn fablet
no flags Details | Formatted Diff | Diff
Patch (23.31 KB, patch)
2021-10-18 05:21 PDT, youenn fablet
no flags Details | Formatted Diff | Diff
Patch (23.79 KB, patch)
2021-10-18 06:57 PDT, youenn fablet
no flags Details | Formatted Diff | Diff
Patch (26.25 KB, patch)
2021-10-19 02:00 PDT, youenn fablet
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description youenn fablet 2021-10-13 02:00:52 PDT
Guarantee order of WebSocket events in case of being resumed
Comment 1 youenn fablet 2021-10-13 02:30:46 PDT
Created attachment 441050 [details]
Patch
Comment 2 Alex Christensen 2021-10-13 09:06:04 PDT
What motivated this change?
Comment 3 Chris Dumez 2021-10-13 09:17:23 PDT
Comment on attachment 441050 [details]
Patch

Odds are that we should update WebSocket to dispatch events asynchronously and use the HTML event loop. Then we wouldn't need such to worry about suspending / resuming (since the HTML event loop properly suspends when in bfcache).
Comment 4 youenn fablet 2021-10-13 09:49:25 PDT
(In reply to Chris Dumez from comment #3)
> Comment on attachment 441050 [details]
> Patch
> 
> Odds are that we should update WebSocket to dispatch events asynchronously
> and use the HTML event loop. Then we wouldn't need such to worry about
> suspending / resuming (since the HTML event loop properly suspends when in
> bfcache).

Good point, I'll do that instead.
Comment 5 youenn fablet 2021-10-14 04:51:56 PDT
Created attachment 441203 [details]
Patch
Comment 6 youenn fablet 2021-10-14 05:13:31 PDT
Created attachment 441205 [details]
Patch
Comment 7 youenn fablet 2021-10-14 23:09:12 PDT
Created attachment 441336 [details]
Patch
Comment 8 youenn fablet 2021-10-18 05:21:33 PDT
Created attachment 441590 [details]
Patch
Comment 9 youenn fablet 2021-10-18 06:57:39 PDT
Created attachment 441597 [details]
Patch
Comment 10 youenn fablet 2021-10-19 02:00:37 PDT
Created attachment 441702 [details]
Patch
Comment 11 Chris Dumez 2021-10-19 07:38:21 PDT
Comment on attachment 441702 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=441702&action=review

Nice, r=me with fixes.

> Source/WebCore/Modules/websockets/WebSocket.cpp:554
> +        ASSERT(scriptExecutionContext());

Please do an early return, there is no such guarantee with the event loop as the event loop is shared with other contexts of the same origin.

> Source/WebCore/Modules/websockets/WebSocket.cpp:568
> +        ASSERT(scriptExecutionContext());

ditto.

> Source/WebCore/Modules/websockets/WebSocket.cpp:598
> +        ASSERT(scriptExecutionContext());

ditto.

> Source/WebCore/Modules/websockets/WebSocket.cpp:632
> +        ASSERT(scriptExecutionContext());

ditto.
Comment 12 youenn fablet 2021-10-19 09:13:34 PDT
(In reply to Chris Dumez from comment #11)
> Comment on attachment 441702 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=441702&action=review
> 
> Nice, r=me with fixes.
> 
> > Source/WebCore/Modules/websockets/WebSocket.cpp:554
> > +        ASSERT(scriptExecutionContext());
> 
> Please do an early return, there is no such guarantee with the event loop as
> the event loop is shared with other contexts of the same origin.
> 
> > Source/WebCore/Modules/websockets/WebSocket.cpp:568
> > +        ASSERT(scriptExecutionContext());
> 
> ditto.
> 
> > Source/WebCore/Modules/websockets/WebSocket.cpp:598
> > +        ASSERT(scriptExecutionContext());
> 
> ditto.
> 
> > Source/WebCore/Modules/websockets/WebSocket.cpp:632
> > +        ASSERT(scriptExecutionContext());
> 
> ditto.

I think all these ASSERTs are correct since we either do early return on m_state being closed or m_channel being null and WebSocket::stop does set m_state to closed and m_channel to nullptr.
Comment 13 youenn fablet 2021-10-19 09:14:42 PDT
I guess I can remove these ASSERTs since we are not doing them consistently now after enqueuing a task.
Comment 14 Chris Dumez 2021-10-19 09:28:31 PDT
(In reply to youenn fablet from comment #12)
> (In reply to Chris Dumez from comment #11)
> > Comment on attachment 441702 [details]
> > Patch
> > 
> > View in context:
> > https://bugs.webkit.org/attachment.cgi?id=441702&action=review
> > 
> > Nice, r=me with fixes.
> > 
> > > Source/WebCore/Modules/websockets/WebSocket.cpp:554
> > > +        ASSERT(scriptExecutionContext());
> > 
> > Please do an early return, there is no such guarantee with the event loop as
> > the event loop is shared with other contexts of the same origin.
> > 
> > > Source/WebCore/Modules/websockets/WebSocket.cpp:568
> > > +        ASSERT(scriptExecutionContext());
> > 
> > ditto.
> > 
> > > Source/WebCore/Modules/websockets/WebSocket.cpp:598
> > > +        ASSERT(scriptExecutionContext());
> > 
> > ditto.
> > 
> > > Source/WebCore/Modules/websockets/WebSocket.cpp:632
> > > +        ASSERT(scriptExecutionContext());
> > 
> > ditto.
> 
> I think all these ASSERTs are correct since we either do early return on
> m_state being closed or m_channel being null and WebSocket::stop does set
> m_state to closed and m_channel to nullptr.

Maybe I misread your code. I just wanted to point out that tasks posted on the HTML event loop can fire after the script execution is gone (and thus after stop() has been called).
So in general, asserting that the script execution context exists in a task posted on the HTML event loop is incorrect. It may be correct here in your code due to some other logic but in general it isn't.
Comment 15 youenn fablet 2021-10-19 09:34:31 PDT
(In reply to Chris Dumez from comment #14)
> (In reply to youenn fablet from comment #12)
> > (In reply to Chris Dumez from comment #11)
> > > Comment on attachment 441702 [details]
> > > Patch
> > > 
> > > View in context:
> > > https://bugs.webkit.org/attachment.cgi?id=441702&action=review
> > > 
> > > Nice, r=me with fixes.
> > > 
> > > > Source/WebCore/Modules/websockets/WebSocket.cpp:554
> > > > +        ASSERT(scriptExecutionContext());
> > > 
> > > Please do an early return, there is no such guarantee with the event loop as
> > > the event loop is shared with other contexts of the same origin.
> > > 
> > > > Source/WebCore/Modules/websockets/WebSocket.cpp:568
> > > > +        ASSERT(scriptExecutionContext());
> > > 
> > > ditto.
> > > 
> > > > Source/WebCore/Modules/websockets/WebSocket.cpp:598
> > > > +        ASSERT(scriptExecutionContext());
> > > 
> > > ditto.
> > > 
> > > > Source/WebCore/Modules/websockets/WebSocket.cpp:632
> > > > +        ASSERT(scriptExecutionContext());
> > > 
> > > ditto.
> > 
> > I think all these ASSERTs are correct since we either do early return on
> > m_state being closed or m_channel being null and WebSocket::stop does set
> > m_state to closed and m_channel to nullptr.
> 
> Maybe I misread your code. I just wanted to point out that tasks posted on
> the HTML event loop can fire after the script execution is gone (and thus
> after stop() has been called).
> So in general, asserting that the script execution context exists in a task
> posted on the HTML event loop is incorrect. It may be correct here in your
> code due to some other logic but in general it isn't.

OK, let's keep the code like this then.
I wonder whether we should add an option in queueTaskKeepingObjectAlive to actually not call the callback if the ActiveDOMObject is stopped, it seems that is the behavior most call sites will want.
Comment 16 Chris Dumez 2021-10-19 09:36:19 PDT
(In reply to youenn fablet from comment #15)
> (In reply to Chris Dumez from comment #14)
> > (In reply to youenn fablet from comment #12)
> > > (In reply to Chris Dumez from comment #11)
> > > > Comment on attachment 441702 [details]
> > > > Patch
> > > > 
> > > > View in context:
> > > > https://bugs.webkit.org/attachment.cgi?id=441702&action=review
> > > > 
> > > > Nice, r=me with fixes.
> > > > 
> > > > > Source/WebCore/Modules/websockets/WebSocket.cpp:554
> > > > > +        ASSERT(scriptExecutionContext());
> > > > 
> > > > Please do an early return, there is no such guarantee with the event loop as
> > > > the event loop is shared with other contexts of the same origin.
> > > > 
> > > > > Source/WebCore/Modules/websockets/WebSocket.cpp:568
> > > > > +        ASSERT(scriptExecutionContext());
> > > > 
> > > > ditto.
> > > > 
> > > > > Source/WebCore/Modules/websockets/WebSocket.cpp:598
> > > > > +        ASSERT(scriptExecutionContext());
> > > > 
> > > > ditto.
> > > > 
> > > > > Source/WebCore/Modules/websockets/WebSocket.cpp:632
> > > > > +        ASSERT(scriptExecutionContext());
> > > > 
> > > > ditto.
> > > 
> > > I think all these ASSERTs are correct since we either do early return on
> > > m_state being closed or m_channel being null and WebSocket::stop does set
> > > m_state to closed and m_channel to nullptr.
> > 
> > Maybe I misread your code. I just wanted to point out that tasks posted on
> > the HTML event loop can fire after the script execution is gone (and thus
> > after stop() has been called).
> > So in general, asserting that the script execution context exists in a task
> > posted on the HTML event loop is incorrect. It may be correct here in your
> > code due to some other logic but in general it isn't.
> 
> OK, let's keep the code like this then.
> I wonder whether we should add an option in queueTaskKeepingObjectAlive to
> actually not call the callback if the ActiveDOMObject is stopped, it seems
> that is the behavior most call sites will want.

We used to make this assumption and it was wrong. It is not uncommon that frames script each other and APIs usually still work in detached iframes if the caller is still in a valid script execution context. This is the reason why we made this change (and it helped pass more WPT tests).
Comment 17 EWS 2021-10-19 11:41:21 PDT
Committed r284472 (243231@main): <https://commits.webkit.org/243231@main>

All reviewed patches have been landed. Closing bug and clearing flags on attachment 441702 [details].
Comment 18 Radar WebKit Bug Importer 2021-10-19 11:42:18 PDT
<rdar://problem/84425230>