msg204809 - (view) |
Author: Charles-François Natali (neologix) * |
Date: 2013-11-30 13:44 |
Initially, BaseSelector was simply designed as the base implementation used by concrete ones like SelectSelector & Co.
Then BaseSelector evolved to be an ABC, but the problem is that it's really not usable as such: the register() and unregister() methods are not abstract, and instead store the fileobj -> key association in a private dictionary (_fd_to_key). Since this attribute is private, it cannot be used by third-party selectors implementation which might want to implement the ABC. Also, such implementations might not want to use a dictionay internally, and generally, inheritance should be avoided in this type of situations (since it breaks encapsulation).
In short, BaseSelector mixes up the type definition (ABC) and base implementation, which cannot be reused by subclasses anyway.
The attached patch cleans things up by making BaseSelector.{register,unregister,get_map} methods abstract (raising NotImplementedError by default).
Together with select(), those methods are the bare minimum that a conform selector implementation should provide.
get_key() still has a default implementation (atop get_map()), and so does modify() (atop register()/unregister()).
The concrete base implementation (on top of which are built SelectSelector & friends) is moved in a private _BaseSelectorImpl.
I think that's a cleaner design.
The only problem is that it makes some methods abstract, so I had to update test_telnetlib and asyncio/test_utils because they are implementing BaseSelector for mock tests.
BTW, is there a consensus on ABC names? Like AbstractSelector vs BaseSelector?
|
msg204812 - (view) |
Author: Antoine Pitrou (pitrou) * |
Date: 2013-11-30 14:09 |
I'm wondering, is there a reason we made BaseSelector a public API?
|
msg204817 - (view) |
Author: Charles-François Natali (neologix) * |
Date: 2013-11-30 15:14 |
> I'm wondering, is there a reason we made BaseSelector a public API?
The idead was to have an ABC so that users can implement their own
selector, and pass it to e.g. asyncio or anything alse expecting a
selector.
Other than that, the only use is as a documentation (i.e. to show
which methods are supported by all selectors implementations).
|
msg204819 - (view) |
Author: Antoine Pitrou (pitrou) * |
Date: 2013-11-30 15:17 |
> The idead was to have an ABC so that users can implement their own
> selector, and pass it to e.g. asyncio or anything alse expecting a
> selector.
> Other than that, the only use is as a documentation (i.e. to show
> which methods are supported by all selectors implementations).
The problem for documentation use is that we're christening it as an
official API, and thus it becomes more difficult to refactor the
inheritance hierarchy.
|
msg204820 - (view) |
Author: Charles-François Natali (neologix) * |
Date: 2013-11-30 15:23 |
> The problem for documentation use is that we're christening it as an
> official API, and thus it becomes more difficult to refactor the
> inheritance hierarchy.
So what would you suggest?
|
msg204821 - (view) |
Author: Antoine Pitrou (pitrou) * |
Date: 2013-11-30 15:28 |
> > The problem for documentation use is that we're christening it as an
> > official API, and thus it becomes more difficult to refactor the
> > inheritance hierarchy.
>
> So what would you suggest?
Hmmm... Well I guess your proposal makes sense :-) Aka. having a
documented ABC, and then a private base implementation.
Otherwise, you can also document the methods without saying precisely to
which class they belong, which I started doing on asyncio, but
apparently it confuses some people.
|
msg204861 - (view) |
Author: Guido van Rossum (gvanrossum) * |
Date: 2013-11-30 23:45 |
LGTM, although I wish that you had time to implement the comment "TODO: Subclasses can probably optimize this even further" rather than just shuffling the existing code around. :-)
|
msg204888 - (view) |
Author: Charles-François Natali (neologix) * |
Date: 2013-12-01 07:59 |
> Guido van Rossum added the comment:
>
> LGTM, although I wish that you had time to implement the comment "TODO: Subclasses can probably optimize this even further" rather than just shuffling the existing code around. :-)
I will look a this, but I rather take care of the API than
implementation details :-)
Also, I'm not sure that modify() is actually a performance-critical
code-path: do you have any semi-realistic asyncio-based benchmark I
could use?
|
msg204895 - (view) |
Author: STINNER Victor (vstinner) * |
Date: 2013-12-01 09:35 |
> I think that's a cleaner design.
For common containers like Sequence or Mapping, ABC are useful. But I don't expect new implementations of BaseSelector. Is it just for purity? :-p
|
msg204896 - (view) |
Author: STINNER Victor (vstinner) * |
Date: 2013-12-01 09:36 |
(I'm not opposed to the change, I'm just asking.)
|
msg204898 - (view) |
Author: Giampaolo Rodola' (giampaolo.rodola) * |
Date: 2013-12-01 09:43 |
In those protocols where client and server exchange a lot of commands and responses in a single session, such as FTP, modify() is going to be called many times.
I don't have actual numbers but I remember that using epoll.modify() was one of those relatively small optimizations which all put together led to current pyftpdlib performances. For poll() and epoll() pollers I see no reason not to use the specialized modify().
That aside, what actually *does* make a big difference and it is very important is to "unregister" a fd for writing (EVENT_WRITE) when there's no more data to send, and that's something that should be done at a higher level (transport.write() and anywhere else some data is sent).
|
msg204901 - (view) |
Author: Roundup Robot (python-dev) |
Date: 2013-12-01 10:04 |
New changeset f48f302f54aa by Charles-François Natali in branch 'default':
Issue #19842: Refactor BaseSelector to make it an actual usable ABC.
http://hg.python.org/cpython/rev/f48f302f54aa
|
msg204902 - (view) |
Author: Charles-François Natali (neologix) * |
Date: 2013-12-01 10:12 |
> STINNER Victor added the comment:
>
>> I think that's a cleaner design.
>
> For common containers like Sequence or Mapping, ABC are useful. But I don't expect new implementations of BaseSelector. Is it just for purity? :-p
There are already implementations in the test suite, but the main
reason is for documentation purposes (i.e. to document clearly which
methods are available, and which are optional).
IMO, ABC make documentation more clear, and also make it easier for
third-party implementations.
I don't have a strong opinion on this, my real concern is really just
the documentation, so if you can propose a documentation patch that
makes things clear, I'm perfectly fine with removing BaseSelector from
the API :-)
|
msg205325 - (view) |
Author: Éric Araujo (eric.araujo) * |
Date: 2013-12-05 22:32 |
Do I understand right that BaseSelector.register means something else entirely than ABC.register? Is it a concern?
|
msg205327 - (view) |
Author: Guido van Rossum (gvanrossum) * |
Date: 2013-12-05 22:39 |
Well, registration is a very common pattern and you can't really require everyone to use an inferior word just because ABCMeta uses it.
There's a simple work-around:
abc.ABCMeta.register(selectors.BaseSelector, C)
|
msg205381 - (view) |
Author: Guido van Rossum (gvanrossum) * |
Date: 2013-12-06 15:57 |
This is done AFAICT.
|
|
Date |
User |
Action |
Args |
2022-04-11 14:57:54 | admin | set | github: 64041 |
2013-12-06 15:57:13 | gvanrossum | set | status: open -> closed resolution: fixed messages:
+ msg205381
stage: patch review -> resolved |
2013-12-06 13:44:41 | martin.panter | set | nosy:
+ martin.panter
|
2013-12-05 22:39:36 | gvanrossum | set | messages:
+ msg205327 |
2013-12-05 22:32:49 | eric.araujo | set | nosy:
+ eric.araujo messages:
+ msg205325
|
2013-12-01 10:12:49 | neologix | set | messages:
+ msg204902 |
2013-12-01 10:04:59 | python-dev | set | nosy:
+ python-dev messages:
+ msg204901
|
2013-12-01 09:43:12 | giampaolo.rodola | set | messages:
+ msg204898 |
2013-12-01 09:36:45 | vstinner | set | messages:
+ msg204896 |
2013-12-01 09:35:35 | vstinner | set | nosy:
+ vstinner messages:
+ msg204895
|
2013-12-01 07:59:59 | neologix | set | messages:
+ msg204888 |
2013-11-30 23:45:12 | gvanrossum | set | messages:
+ msg204861 |
2013-11-30 15:43:44 | giampaolo.rodola | set | nosy:
+ giampaolo.rodola
|
2013-11-30 15:28:05 | pitrou | set | messages:
+ msg204821 |
2013-11-30 15:23:24 | neologix | set | messages:
+ msg204820 |
2013-11-30 15:17:19 | pitrou | set | messages:
+ msg204819 |
2013-11-30 15:14:20 | neologix | set | messages:
+ msg204817 |
2013-11-30 14:09:49 | pitrou | set | messages:
+ msg204812 |
2013-11-30 13:44:36 | neologix | create | |