Skip to content

Commit 636f995

Browse files
bdracojtcave
authored andcommitted
pythongh-106527: asyncio: optimize to add/remove readers and writers (python#106528)
1 parent 5b02245 commit 636f995

File tree

3 files changed

+48
-53
lines changed

3 files changed

+48
-53
lines changed

Lib/asyncio/selector_events.py

+29-35
Original file line numberDiff line numberDiff line change
@@ -274,9 +274,8 @@ def _ensure_fd_no_transport(self, fd):
274274
def _add_reader(self, fd, callback, *args):
275275
self._check_closed()
276276
handle = events.Handle(callback, args, self, None)
277-
try:
278-
key = self._selector.get_key(fd)
279-
except KeyError:
277+
key = self._selector.get_map().get(fd)
278+
if key is None:
280279
self._selector.register(fd, selectors.EVENT_READ,
281280
(handle, None))
282281
else:
@@ -290,30 +289,27 @@ def _add_reader(self, fd, callback, *args):
290289
def _remove_reader(self, fd):
291290
if self.is_closed():
292291
return False
293-
try:
294-
key = self._selector.get_key(fd)
295-
except KeyError:
292+
key = self._selector.get_map().get(fd)
293+
if key is None:
296294
return False
295+
mask, (reader, writer) = key.events, key.data
296+
mask &= ~selectors.EVENT_READ
297+
if not mask:
298+
self._selector.unregister(fd)
297299
else:
298-
mask, (reader, writer) = key.events, key.data
299-
mask &= ~selectors.EVENT_READ
300-
if not mask:
301-
self._selector.unregister(fd)
302-
else:
303-
self._selector.modify(fd, mask, (None, writer))
300+
self._selector.modify(fd, mask, (None, writer))
304301

305-
if reader is not None:
306-
reader.cancel()
307-
return True
308-
else:
309-
return False
302+
if reader is not None:
303+
reader.cancel()
304+
return True
305+
else:
306+
return False
310307

311308
def _add_writer(self, fd, callback, *args):
312309
self._check_closed()
313310
handle = events.Handle(callback, args, self, None)
314-
try:
315-
key = self._selector.get_key(fd)
316-
except KeyError:
311+
key = self._selector.get_map().get(fd)
312+
if key is None:
317313
self._selector.register(fd, selectors.EVENT_WRITE,
318314
(None, handle))
319315
else:
@@ -328,24 +324,22 @@ def _remove_writer(self, fd):
328324
"""Remove a writer callback."""
329325
if self.is_closed():
330326
return False
331-
try:
332-
key = self._selector.get_key(fd)
333-
except KeyError:
327+
key = self._selector.get_map().get(fd)
328+
if key is None:
334329
return False
330+
mask, (reader, writer) = key.events, key.data
331+
# Remove both writer and connector.
332+
mask &= ~selectors.EVENT_WRITE
333+
if not mask:
334+
self._selector.unregister(fd)
335335
else:
336-
mask, (reader, writer) = key.events, key.data
337-
# Remove both writer and connector.
338-
mask &= ~selectors.EVENT_WRITE
339-
if not mask:
340-
self._selector.unregister(fd)
341-
else:
342-
self._selector.modify(fd, mask, (reader, None))
336+
self._selector.modify(fd, mask, (reader, None))
343337

344-
if writer is not None:
345-
writer.cancel()
346-
return True
347-
else:
348-
return False
338+
if writer is not None:
339+
writer.cancel()
340+
return True
341+
else:
342+
return False
349343

350344
def add_reader(self, fd, callback, *args):
351345
"""Add a reader callback."""

Lib/test/test_asyncio/test_selector_events.py

+18-18
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ def test_sock_connect_resolve_using_socket_params(self, m_gai):
178178
sock.connect.assert_called_with(('127.0.0.1', 0))
179179

180180
def test_add_reader(self):
181-
self.loop._selector.get_key.side_effect = KeyError
181+
self.loop._selector.get_map.return_value = {}
182182
cb = lambda: True
183183
self.loop.add_reader(1, cb)
184184

@@ -192,8 +192,8 @@ def test_add_reader(self):
192192
def test_add_reader_existing(self):
193193
reader = mock.Mock()
194194
writer = mock.Mock()
195-
self.loop._selector.get_key.return_value = selectors.SelectorKey(
196-
1, 1, selectors.EVENT_WRITE, (reader, writer))
195+
self.loop._selector.get_map.return_value = {1: selectors.SelectorKey(
196+
1, 1, selectors.EVENT_WRITE, (reader, writer))}
197197
cb = lambda: True
198198
self.loop.add_reader(1, cb)
199199

@@ -208,8 +208,8 @@ def test_add_reader_existing(self):
208208

209209
def test_add_reader_existing_writer(self):
210210
writer = mock.Mock()
211-
self.loop._selector.get_key.return_value = selectors.SelectorKey(
212-
1, 1, selectors.EVENT_WRITE, (None, writer))
211+
self.loop._selector.get_map.return_value = {1: selectors.SelectorKey(
212+
1, 1, selectors.EVENT_WRITE, (None, writer))}
213213
cb = lambda: True
214214
self.loop.add_reader(1, cb)
215215

@@ -222,18 +222,18 @@ def test_add_reader_existing_writer(self):
222222
self.assertEqual(writer, w)
223223

224224
def test_remove_reader(self):
225-
self.loop._selector.get_key.return_value = selectors.SelectorKey(
226-
1, 1, selectors.EVENT_READ, (None, None))
225+
self.loop._selector.get_map.return_value = {1: selectors.SelectorKey(
226+
1, 1, selectors.EVENT_READ, (None, None))}
227227
self.assertFalse(self.loop.remove_reader(1))
228228

229229
self.assertTrue(self.loop._selector.unregister.called)
230230

231231
def test_remove_reader_read_write(self):
232232
reader = mock.Mock()
233233
writer = mock.Mock()
234-
self.loop._selector.get_key.return_value = selectors.SelectorKey(
234+
self.loop._selector.get_map.return_value = {1: selectors.SelectorKey(
235235
1, 1, selectors.EVENT_READ | selectors.EVENT_WRITE,
236-
(reader, writer))
236+
(reader, writer))}
237237
self.assertTrue(
238238
self.loop.remove_reader(1))
239239

@@ -243,12 +243,12 @@ def test_remove_reader_read_write(self):
243243
self.loop._selector.modify.call_args[0])
244244

245245
def test_remove_reader_unknown(self):
246-
self.loop._selector.get_key.side_effect = KeyError
246+
self.loop._selector.get_map.return_value = {}
247247
self.assertFalse(
248248
self.loop.remove_reader(1))
249249

250250
def test_add_writer(self):
251-
self.loop._selector.get_key.side_effect = KeyError
251+
self.loop._selector.get_map.return_value = {}
252252
cb = lambda: True
253253
self.loop.add_writer(1, cb)
254254

@@ -262,8 +262,8 @@ def test_add_writer(self):
262262
def test_add_writer_existing(self):
263263
reader = mock.Mock()
264264
writer = mock.Mock()
265-
self.loop._selector.get_key.return_value = selectors.SelectorKey(
266-
1, 1, selectors.EVENT_READ, (reader, writer))
265+
self.loop._selector.get_map.return_value = {1: selectors.SelectorKey(
266+
1, 1, selectors.EVENT_READ, (reader, writer))}
267267
cb = lambda: True
268268
self.loop.add_writer(1, cb)
269269

@@ -277,18 +277,18 @@ def test_add_writer_existing(self):
277277
self.assertEqual(cb, w._callback)
278278

279279
def test_remove_writer(self):
280-
self.loop._selector.get_key.return_value = selectors.SelectorKey(
281-
1, 1, selectors.EVENT_WRITE, (None, None))
280+
self.loop._selector.get_map.return_value = {1: selectors.SelectorKey(
281+
1, 1, selectors.EVENT_WRITE, (None, None))}
282282
self.assertFalse(self.loop.remove_writer(1))
283283

284284
self.assertTrue(self.loop._selector.unregister.called)
285285

286286
def test_remove_writer_read_write(self):
287287
reader = mock.Mock()
288288
writer = mock.Mock()
289-
self.loop._selector.get_key.return_value = selectors.SelectorKey(
289+
self.loop._selector.get_map.return_value = {1: selectors.SelectorKey(
290290
1, 1, selectors.EVENT_READ | selectors.EVENT_WRITE,
291-
(reader, writer))
291+
(reader, writer))}
292292
self.assertTrue(
293293
self.loop.remove_writer(1))
294294

@@ -298,7 +298,7 @@ def test_remove_writer_read_write(self):
298298
self.loop._selector.modify.call_args[0])
299299

300300
def test_remove_writer_unknown(self):
301-
self.loop._selector.get_key.side_effect = KeyError
301+
self.loop._selector.get_map.return_value = {}
302302
self.assertFalse(
303303
self.loop.remove_writer(1))
304304

Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Reduce overhead to add and remove :mod:`asyncio` readers and writers.

0 commit comments

Comments
 (0)