Bug 215584 - [webkitcorepy] Move Timeout to webkitcorepy
Summary: [webkitcorepy] Move Timeout to webkitcorepy
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Tools / Tests (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Jonathan Bedard
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2020-08-17 14:18 PDT by Jonathan Bedard
Modified: 2020-08-28 08:21 PDT (History)
7 users (show)

See Also:


Attachments
Patch (25.41 KB, patch)
2020-08-17 14:30 PDT, Jonathan Bedard
no flags Details | Formatted Diff | Diff
Patch (26.31 KB, patch)
2020-08-18 11:10 PDT, Jonathan Bedard
no flags Details | Formatted Diff | Diff
Patch (26.29 KB, patch)
2020-08-19 16:07 PDT, Jonathan Bedard
no flags Details | Formatted Diff | Diff
Patch for landing (26.33 KB, patch)
2020-08-20 07:11 PDT, Jonathan Bedard
no flags Details | Formatted Diff | Diff
Patch (5.00 KB, patch)
2020-08-20 10:39 PDT, Jonathan Bedard
no flags Details | Formatted Diff | Diff
Patch (8.65 KB, patch)
2020-08-24 09:57 PDT, Jonathan Bedard
no flags Details | Formatted Diff | Diff
Patch (8.69 KB, patch)
2020-08-24 11:00 PDT, Jonathan Bedard
no flags Details | Formatted Diff | Diff
Patch (8.67 KB, patch)
2020-08-24 12:27 PDT, Jonathan Bedard
no flags Details | Formatted Diff | Diff
Patch (8.71 KB, patch)
2020-08-24 13:42 PDT, Jonathan Bedard
no flags Details | Formatted Diff | Diff
Patch (11.89 KB, patch)
2020-08-24 15:24 PDT, Jonathan Bedard
no flags Details | Formatted Diff | Diff
Patch (15.07 KB, patch)
2020-08-25 09:06 PDT, Jonathan Bedard
no flags Details | Formatted Diff | Diff
Patch (9.13 KB, patch)
2020-08-25 10:30 PDT, Jonathan Bedard
no flags Details | Formatted Diff | Diff
Patch (11.02 KB, patch)
2020-08-25 16:41 PDT, Jonathan Bedard
no flags Details | Formatted Diff | Diff
Patch (13.77 KB, patch)
2020-08-26 09:28 PDT, Jonathan Bedard
dewei_zhu: review+
Details | Formatted Diff | Diff
Patch (13.75 KB, patch)
2020-08-26 21:17 PDT, Jonathan Bedard
no flags Details | Formatted Diff | Diff
Patch (4.97 KB, patch)
2020-08-27 07:16 PDT, Jonathan Bedard
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Jonathan Bedard 2020-08-17 14:18:03 PDT
Webkitpy has a timeout class which uses alarms to raise an exception.

This is a useful idea, although many functions which may block have their own native timeouts. To work around this, we should allow our timeout class to be disabled for a blocks that a program may use a more appropriate timeout for APIs which support it.
Comment 1 Radar WebKit Bug Importer 2020-08-17 14:18:56 PDT
<rdar://problem/67270713>
Comment 2 Jonathan Bedard 2020-08-17 14:30:27 PDT
Created attachment 406744 [details]
Patch
Comment 3 Jonathan Bedard 2020-08-17 15:11:39 PDT
(In reply to Jonathan Bedard from comment #2)
> Created attachment 406744 [details]
> Patch

Before landing this, want to be clear that this isn't a 100% move, while the new class is a drop in replacement to the old one, they aren't identical.
Comment 4 dewei_zhu 2020-08-17 16:02:20 PDT
Comment on attachment 406744 [details]
Patch

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

> Tools/Scripts/libraries/webkitcorepy/webkitcorepy/timeout.py:36
> +    _process_to_timeout_map = {}

How about using `collections.defaultdict(list)` to avoid boundary check?

> Tools/Scripts/libraries/webkitcorepy/webkitcorepy/timeout.py:121
> +    def sleep(cls, t):

Nit: maybe call it 'seconds' to be clearer here.

> Tools/Scripts/libraries/webkitcorepy/webkitcorepy/timeout.py:161
> +                for i in range(len(self._process_to_timeout_map[os.getpid()]) - 1):
> +                    if self.data.alarm_time < self._process_to_timeout_map[os.getpid()][i + 1].alarm_time:
> +                        self._process_to_timeout_map[os.getpid()].insert(i, self.data)
> +                        break

It looks like we are doing a linear search on an sorted array, we can just use `bisect.insort` https://docs.python.org/3/library/bisect.html

> Tools/Scripts/libraries/webkitcorepy/webkitcorepy/timeout.py:167
> +            if current_timeout and current_timeout.alarm_time < self.data.alarm_time:
> +                for i in range(len(self._process_to_timeout_map[os.getpid()]) - 1):
> +                    if self.data.alarm_time < self._process_to_timeout_map[os.getpid()][i + 1].alarm_time:
> +                        self._process_to_timeout_map[os.getpid()].insert(i, self.data)
> +                        break
> +                self._process_to_timeout_map[os.getpid()].append(self.data)
> +
> +            # This is the most urgent timeout
> +            else:
> +                self._process_to_timeout_map[os.getpid()] = [self.data] + self._process_to_timeout_map.get(os.getpid(), [])
> +

This logic can be simplified to 
`bisect.insort(self._process_to_timeout_map[os.getpid()], self.data)`
if we use defaultdict for self._process_to_timeout_map and implement `__cmp__` for Data class.
For bisect.insort, you can refer to https://docs.python.org/3/library/bisect.html, it's basically upper_bound in cpp.

> Tools/Scripts/libraries/webkitcorepy/webkitcorepy/tests/timeout_unittest.py:31
> +

Do we have a test case that an exception is raised in a Timeout context, and we expect the `_process_to_timeout_map` to be updated correctly?

> Tools/Scripts/libraries/webkitcorepy/webkitcorepy/tests/timeout_unittest.py:71
> +        with mocks.Time:
> +            with OutputCapture() as capturer:
> +                with Timeout(1):
> +                    Timeout.check()
> +                    self.assertRaises(Timeout.Exception, time.sleep, 1)
> +

To avoid code getting too nested, I think we can just do
```
with mocks.Time, OutputCapture() as capturer, Timeout(1):
    ...
```
or 
```
with mocks.Time, OutputCapture() as capturer:
    with Timeout(1):
        ....
```
Comment 5 Jonathan Bedard 2020-08-17 22:11:37 PDT
Comment on attachment 406744 [details]
Patch

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

>> Tools/Scripts/libraries/webkitcorepy/webkitcorepy/tests/timeout_unittest.py:31
>> +
> 
> Do we have a test case that an exception is raised in a Timeout context, and we expect the `_process_to_timeout_map` to be updated correctly?

This is a good point.

I've added a test that covers the "what happens when an exception has already been triggered and caught" case.
Comment 6 Jonathan Bedard 2020-08-18 11:10:05 PDT
Created attachment 406793 [details]
Patch
Comment 7 Jonathan Bedard 2020-08-19 16:07:38 PDT
Created attachment 406883 [details]
Patch
Comment 8 Jonathan Bedard 2020-08-20 07:11:35 PDT
Created attachment 406928 [details]
Patch for landing
Comment 9 EWS 2020-08-20 07:34:02 PDT
Committed r265942: <https://trac.webkit.org/changeset/265942>

All reviewed patches have been landed. Closing bug and clearing flags on attachment 406928 [details].
Comment 10 Jonathan Bedard 2020-08-20 10:39:06 PDT
Reopening to attach new patch.
Comment 11 Jonathan Bedard 2020-08-20 10:39:07 PDT
Created attachment 406945 [details]
Patch
Comment 12 Jonathan Bedard 2020-08-20 17:22:15 PDT
(In reply to Jonathan Bedard from comment #11)
> Created attachment 406945 [details]
> Patch

(Will be waiting to land this until next week)
Comment 13 Aakash Jain 2020-08-21 15:55:10 PDT
(In reply to EWS from comment #9)
> Committed r265942: <https://trac.webkit.org/changeset/265942>
For some reason, this seems to have broke ios-wk2 tests, see Bug 215742
Comment 14 Jonathan Bedard 2020-08-21 20:59:32 PDT
(In reply to Aakash Jain from comment #13)
> (In reply to EWS from comment #9)
> > Committed r265942: <https://trac.webkit.org/changeset/265942>
> For some reason, this seems to have broke ios-wk2 tests, see Bug 215742

I’ll be revisiting this Monday. This is ultimately about the way that python’s multiprocess does forking, will take quite a bit of trial and error to track down.
Comment 15 Jonathan Bedard 2020-08-24 09:57:11 PDT
Created attachment 407107 [details]
Patch
Comment 16 Jonathan Bedard 2020-08-24 11:00:02 PDT
Created attachment 407113 [details]
Patch
Comment 17 Jonathan Bedard 2020-08-24 12:27:09 PDT
Created attachment 407122 [details]
Patch
Comment 18 Jonathan Bedard 2020-08-24 13:42:44 PDT
Created attachment 407130 [details]
Patch
Comment 19 Jonathan Bedard 2020-08-24 15:24:39 PDT
Created attachment 407140 [details]
Patch
Comment 20 Jonathan Bedard 2020-08-25 09:06:37 PDT
Created attachment 407196 [details]
Patch
Comment 21 Jonathan Bedard 2020-08-25 10:30:40 PDT
Created attachment 407205 [details]
Patch
Comment 22 Jonathan Bedard 2020-08-25 16:41:49 PDT
Created attachment 407249 [details]
Patch
Comment 23 Jonathan Bedard 2020-08-25 21:51:37 PDT
Comment on attachment 407249 [details]
Patch

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

> Tools/Scripts/webkitpy/xcode/simulated_device.py:642
> +        with Timeout(timeout, handler=RuntimeError(u'Timed out waiting for process to open {} on {}'.format(bundle_id, self.udid)), patch=False):

Took quite a bit of trial and error, but I found the original issue with the change, apparent mock.patch breaks future forking on MacOS, which is super surprising. The ultimate solution will be fixing our multiprocessing code, but that's not a change for this patch. All we need to do is opt out of patching time.sleep when booting simulators.
Comment 24 Jonathan Bedard 2020-08-26 09:28:20 PDT
Created attachment 407305 [details]
Patch
Comment 25 Jonathan Bedard 2020-08-26 21:17:40 PDT
Created attachment 407374 [details]
Patch
Comment 26 EWS 2020-08-26 22:43:07 PDT
Committed r266224: <https://trac.webkit.org/changeset/266224>

All reviewed patches have been landed. Closing bug and clearing flags on attachment 407374 [details].
Comment 27 Jonathan Bedard 2020-08-27 07:16:12 PDT
Reopening to attach new patch.
Comment 28 Jonathan Bedard 2020-08-27 07:16:13 PDT
Created attachment 407396 [details]
Patch
Comment 29 EWS 2020-08-28 08:21:35 PDT
Committed r266277: <https://trac.webkit.org/changeset/266277>

All reviewed patches have been landed. Closing bug and clearing flags on attachment 407396 [details].