-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[9101] tcp: adding support for SO_REUSEPORT #759
Conversation
a092dfe
to
3854807
Compare
Codecov Report
@@ Coverage Diff @@
## trunk #759 +/- ##
==========================================
- Coverage 89.62% 88.52% -1.11%
==========================================
Files 844 844
Lines 147851 147868 +17
Branches 13065 13067 +2
==========================================
- Hits 132518 130897 -1621
- Misses 12919 14505 +1586
- Partials 2414 2466 +52 |
9e29d84
to
63b13fe
Compare
I couldn't validate codecov tests since it requires linux >= 3.9 and not available on windows. However it does work on my local machine. In order to go through codecov, I would have to remove the test. |
@wdauchy Hi! Do you have a ticket on https://twistedmatrix.com/trac that we can reference it against? When we have a ticket number, we can sync it to our buildbot builders (of which some have a kernel version greater than 3.9) so we can run it against the full test suite. Please file a ticket, or add it to the description, and add the 'review' tag to the trac ticket with a link to this PR, then we can move this along :) |
@wdauchy Oh, I found the ticket. http://twistedmatrix.com/trac/ticket/9101 :) |
Running tests on builders... |
@hawkowl thanks for the update; is there anything else I can do to help? From what I have seen, failing tests are either on windows or ubuntu 12.04 which has linux 3.2 |
@hawkowl ping? |
@wdauchy Sorry, there was a problem on our build infra that prevented the tests from going green. Re-running... |
create the socket on our side to use our own options this will avoid the need to bind each carbon process to a different port and balance the traffic with iptables rules this requires linux >= 3.9 patches are on their way to support reuseport directly in twisted see twisted/twisted#759 for the tcp part, udp will fillow Signed-off-by: William Dauchy <w.dauchy@criteo.com>
create the socket on our side to use our own options this will avoid the need to bind each carbon process to a different port and balance the traffic with iptables rules this requires linux >= 3.9 patches are on their way to support reuseport directly in twisted see twisted/twisted#759 for the tcp part, udp will fillow Signed-off-by: William Dauchy <w.dauchy@criteo.com>
create the socket on our side to use our own options this will avoid the need to bind each carbon process to a different port and balance the traffic with iptables rules this requires linux >= 3.9 patches are on their way to support reuseport directly in twisted see twisted/twisted#759 for the tcp part, udp will fillow Signed-off-by: William Dauchy <w.dauchy@criteo.com>
create the socket on our side to use our own options this will avoid the need to bind each carbon process to a different port and balance the traffic with iptables rules this requires linux >= 3.9 patches are on their way to support reuseport directly in twisted see twisted/twisted#759 for the tcp part, udp will fillow Signed-off-by: William Dauchy <w.dauchy@criteo.com>
create the socket on our side to use our own options this will avoid the need to bind each carbon process to a different port and balance the traffic with iptables rules this requires linux >= 3.9 patches are on their way to support reuseport directly in twisted see twisted/twisted#759 for the tcp part, udp will fillow Signed-off-by: William Dauchy <w.dauchy@criteo.com>
@hawkowl how does it sound to you? is there anything I can improve? |
@wdauchy I think it might be better implemented how we do the other TCP options: https://github.com/wdauchy/twisted/blob/66929c6d2843e23a6bc16deff0ae8d55e979ac2e/src/twisted/internet/tcp.py#L302 , is that possible? It would reduce the API changes a lot (which I think is a bit excessive). You needn't implement it in iocpreactor, as Windows doesn't support it, so you can just do a |
66929c6
to
0dfe419
Compare
@hawkowl thanks for your review. I will remove the iocpreactor part as soon as possible; I indeed did not catch it was windows specific; that is understood now. |
Someone with more time than me should do the research into how to get consistent behavior between platforms, and add an API that does that, rather than trying to make the exact flags (which mean different things anyway) apply on both platforms. |
this makes it possible to listen to the same tcp port using different processes available on linux >= 3.9 avoid windows test since it is not supported Signed-off-by: William Dauchy <w.dauchy@criteo.com>
this makes it possible to listen to the same tcp port (over ssl) using different processes Signed-off-by: William Dauchy <w.dauchy@criteo.com>
0dfe419
to
d84cdf9
Compare
@hawkowl @glyph so on windows we may set SO_REUSEADDR in case of multiListen set and SO_EXCLUSIVEADDRUSE otherwise For now, I put back the IOCP interfaces, since it was breaking the endpoints interface; I did not saw a clean way to avoid it. |
create the socket on our side to use our own options this will avoid the need to bind each carbon process to a different port and balance the traffic with iptables rules this requires linux >= 3.9 patches are on their way to support reuseport directly in twisted see twisted/twisted#759 for the tcp part, udp will fillow Signed-off-by: William Dauchy <w.dauchy@criteo.com>
create the socket on our side to use our own options this will avoid the need to bind each carbon process to a different port and balance the traffic with iptables rules this requires linux >= 3.9 patches are on their way to support reuseport directly in twisted see twisted/twisted#759 for the tcp part, udp will fillow Signed-off-by: William Dauchy <w.dauchy@criteo.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for working on this! I've recently had the occasion to have to shim in reuseport support into Twisted for an example, and that was pretty painful -- so it would be wonderful to have it in the core.
I've listed a few things that would be better done in a different way.
@@ -961,6 +964,8 @@ def createInternetSocket(self): | |||
s = base.BasePort.createInternetSocket(self) | |||
if platformType == "posix" and sys.platform != "cygwin": | |||
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) | |||
if self.listenMultiple and hasattr(socket, "SO_REUSEPORT"): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should probably fail if listenMultiple has been requested and we cannot do it, since it literally changes semantics (e.g., we can't run the program twice).
@@ -463,11 +463,15 @@ def __init__(self, reactor, port, backlog, interface): | |||
|
|||
@param interface: The hostname to bind to | |||
@type interface: str | |||
|
|||
@param listenMultiple: allow multiple processes to listen to the same port | |||
@type listenMultiple: bool |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This feature is called:
- listenMultiple (in some places)
- multiListen (in others)
- SO_REUSEPORT (by the kernel level documentation that someone will read and wonder "does Twisted support it)
I suggest collapsing all of these into a single name "reuseport" (lose the SO), thus keeping close to the kernel terminology and not inventing our own.
@@ -728,7 +728,7 @@ def lookupZone(name, timeout=None): | |||
|
|||
class IReactorTCP(Interface): | |||
|
|||
def listenTCP(port, factory, backlog=50, interface=''): | |||
def listenTCP(port, factory, backlog=50, interface='', listenMultiple=False): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is changing an interface to add a new optional parameter.
This is a backwards incompatible change -- since someone external to Twisted who has written their own reactor is now no longer complying with this interface.
If we want to do a backwards incompatible change, we should go by the appropriate process -- probably following the "exceptions" section in https://twistedmatrix.com/documents/current/core/development/policy/compatibility-policy.html#procedure-for-exceptions-to-this-policy
An alternative is to add reuse port in a separate interface (e.g., :code:IReactorTCPListenMulti
), which we would only add to the reactor if we detected SO_REUSEPORT in socket)
Also -- presumably we would like to be able to REUSEPORT on IPv6 as well?
(Either way, whether we do a backwards incompatible change or if we add a new interface,
it would be worthwhile to chunk those into one change.)
OTOH -- I'm not that sure we need the support in listenSSL -- since that functionality can easily be accomplished with the txsni plugin (and we probably want to get away from SSL having to lock-step with TCP)
FYI -- there has been no response on this for about 6 months. I am going to continue working on this in #994 . Once it is green on buildbot, I will close this one with a link. |
@moshez sorry for the lack of reply. |
FWIW, this Stack Overflow reply does an excellent job of covering different OS's various |
Has this been abandoned? I would really like to get support for SO_REUSEPORT. |
The last update on this PR was in 2017/2018. |
@wbarnha The original author definitely seems uninterested in addressing the feedback and conflicts, so I'm going to go ahead and close this PR. If you'd like to see this feature, open a new PR to address #9101 (maybe have a look at #994 too, to see if there's anything useful to be gleaned there?), and feel free to base it on this code. |
Feel free to follow-up indeed. I thought someone had done the work since then. |
this makes it possible to listen to the same tcp port using different
processes under linux >= v3.9