Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 85310a5

Browse files
committed
Issue #20505: Remove resolution and _granularity from selectors and asyncio
* Remove selectors.BaseSelector.resolution attribute * Remove asyncio.BaseEventLoop._granularity attribute
1 parent c489e83 commit 85310a5

9 files changed

Lines changed: 10 additions & 74 deletions

File tree

Doc/library/asyncio-eventloop.rst

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -118,19 +118,6 @@ Which clock is used depends on the (platform-specific) event loop
118118
implementation; ideally it is a monotonic clock. This will generally be
119119
a different clock than :func:`time.time`.
120120

121-
The granularity of the event loop depends on the resolution of the
122-
:meth:`~BaseEventLoop.time` method and the resolution of the selector. It is
123-
usually between 1 ms and 16 ms. For example, a granularity of 1 ms means that
124-
in the best case, the difference between the expected delay and the real
125-
elapsed time is between -1 ms and +1 ms: a call scheduled in 1 nanosecond may
126-
be called in 1 ms, and a call scheduled in 100 ms may be called in 99 ms.
127-
128-
The granularity is the best difference in theory. In practice, it depends on
129-
the system load and the the time taken by tasks executed by the event loop.
130-
For example, if a task blocks the event loop for 1 second, all tasks scheduled
131-
in this second will be delayed. The :ref:`Handle correctly blocking functions
132-
<asyncio-handle-blocking>` section explains how to avoid such issue.
133-
134121

135122
.. method:: BaseEventLoop.call_later(delay, callback, *args)
136123

Doc/library/selectors.rst

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,6 @@ below:
9898
:class:`BaseSelector` and its concrete implementations support the
9999
:term:`context manager` protocol.
100100

101-
.. attribute:: resolution
102-
103-
Resolution of the selector in seconds.
104-
105101
.. method:: register(fileobj, events, data=None)
106102

107103
Register a file object for selection, monitoring it for I/O events.

Lib/asyncio/base_events.py

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,6 @@ def __init__(self):
9696
self._default_executor = None
9797
self._internal_fds = 0
9898
self._running = False
99-
self._granularity = time.get_clock_info('monotonic').resolution
10099

101100
def _make_socket_transport(self, sock, protocol, waiter=None, *,
102101
extra=None, server=None):
@@ -634,21 +633,11 @@ def _run_once(self):
634633
else:
635634
logger.log(level, 'poll took %.3f seconds', t1-t0)
636635
else:
637-
t0 = self.time()
638636
event_list = self._selector.select(timeout)
639-
dt = self.time() - t0
640-
if timeout and not event_list and dt < timeout:
641-
print("%s.select(%.3f ms) took %.3f ms (granularity=%.3f ms, resolution=%.3f ms)"
642-
% (self._selector.__class__.__name__,
643-
timeout * 1e3,
644-
dt * 1e3,
645-
self._granularity * 1e3,
646-
self._selector.resolution * 1e3),
647-
file=sys.__stderr__)
648637
self._process_events(event_list)
649638

650639
# Handle 'later' callbacks that are ready.
651-
now = self.time() + self._granularity
640+
now = self.time()
652641
while self._scheduled:
653642
handle = self._scheduled[0]
654643
if handle._when > now:

Lib/asyncio/proactor_events.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,6 @@ def __init__(self, proactor):
365365
self._selector = proactor # convenient alias
366366
self._self_reading_future = None
367367
self._accept_futures = {} # socket file descriptor => Future
368-
self._granularity = max(proactor.resolution, self._granularity)
369368
proactor.set_loop(self)
370369
self._make_self_pipe()
371370

Lib/asyncio/selector_events.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ def __init__(self, selector=None):
3636
selector = selectors.DefaultSelector()
3737
logger.debug('Using selector: %s', selector.__class__.__name__)
3838
self._selector = selector
39-
self._granularity = max(selector.resolution, self._granularity)
4039
self._make_self_pipe()
4140

4241
def _make_socket_transport(self, sock, protocol, waiter=None, *,

Lib/selectors.py

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,6 @@ class BaseSelector(metaclass=ABCMeta):
8383
performant implementation on the current platform.
8484
"""
8585

86-
@abstractproperty
87-
def resolution(self):
88-
"""Resolution of the selector in seconds"""
89-
return None
90-
9186
@abstractmethod
9287
def register(self, fileobj, events, data=None):
9388
"""Register a file object.
@@ -289,10 +284,6 @@ def __init__(self):
289284
self._readers = set()
290285
self._writers = set()
291286

292-
@property
293-
def resolution(self):
294-
return 1e-6
295-
296287
def register(self, fileobj, events, data=None):
297288
key = super().register(fileobj, events, data)
298289
if events & EVENT_READ:
@@ -345,10 +336,6 @@ def __init__(self):
345336
super().__init__()
346337
self._poll = select.poll()
347338

348-
@property
349-
def resolution(self):
350-
return 1e-3
351-
352339
def register(self, fileobj, events, data=None):
353340
key = super().register(fileobj, events, data)
354341
poll_events = 0
@@ -400,10 +387,6 @@ def __init__(self):
400387
super().__init__()
401388
self._epoll = select.epoll()
402389

403-
@property
404-
def resolution(self):
405-
return 1e-3
406-
407390
def fileno(self):
408391
return self._epoll.fileno()
409392

@@ -468,10 +451,6 @@ def __init__(self):
468451
super().__init__()
469452
self._kqueue = select.kqueue()
470453

471-
@property
472-
def resolution(self):
473-
return 1e-9
474-
475454
def fileno(self):
476455
return self._kqueue.fileno()
477456

Lib/test/test_asyncio/test_base_events.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,8 @@ def cb():
124124
self.loop.run_forever()
125125
dt = self.loop.time() - t0
126126

127-
self.assertGreaterEqual(dt, delay - self.loop._granularity, dt)
127+
# 50 ms: maximum granularity of the event loop
128+
self.assertGreaterEqual(dt, delay - 0.050, dt)
128129
# tolerate a difference of +800 ms because some Python buildbots
129130
# are really slow
130131
self.assertLessEqual(dt, 0.9, dt)

Lib/test/test_asyncio/test_events.py

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1170,28 +1170,19 @@ def _run_once():
11701170
orig_run_once = self.loop._run_once
11711171
self.loop._run_once_counter = 0
11721172
self.loop._run_once = _run_once
1173-
calls = []
11741173

11751174
@asyncio.coroutine
11761175
def wait():
11771176
loop = self.loop
1178-
calls.append(loop._run_once_counter)
1179-
yield from asyncio.sleep(loop._granularity * 10, loop=loop)
1180-
calls.append(loop._run_once_counter)
1181-
yield from asyncio.sleep(loop._granularity / 10, loop=loop)
1182-
calls.append(loop._run_once_counter)
1177+
yield from asyncio.sleep(1e-2, loop=loop)
1178+
yield from asyncio.sleep(1e-4, loop=loop)
11831179

11841180
self.loop.run_until_complete(wait())
1185-
calls.append(self.loop._run_once_counter)
1186-
self.assertEqual(calls, [1, 3, 5, 6])
1187-
1188-
def test_granularity(self):
1189-
granularity = self.loop._granularity
1190-
self.assertGreater(granularity, 0.0)
1191-
# Worst expected granularity: 1 ms on Linux (limited by poll/epoll
1192-
# resolution), 15.6 ms on Windows (limited by time.monotonic
1193-
# resolution)
1194-
self.assertLess(granularity, 0.050)
1181+
# The ideal number of call is 6, but on some platforms, the selector
1182+
# may sleep at little bit less than timeout depending on the resolution
1183+
# of the clock used by the kernel. Tolerate 2 useless calls on these
1184+
# platforms.
1185+
self.assertLessEqual(self.loop._run_once_counter, 8)
11951186

11961187

11971188
class SubprocessTestsMixin:

Lib/test/test_selectors.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -363,11 +363,6 @@ def test_select_interrupt(self):
363363
self.assertFalse(s.select(2))
364364
self.assertLess(time() - t, 2.5)
365365

366-
def test_resolution(self):
367-
s = self.SELECTOR()
368-
self.assertIsInstance(s.resolution, (int, float))
369-
self.assertGreater(s.resolution, 0.0)
370-
371366

372367
class ScalableSelectorMixIn:
373368

0 commit comments

Comments
 (0)