On 09:49 pm, [email protected] wrote:
>for a multiprocess server, I'd like to set SO_REUSEPORT on a TCP
>listening socket.
You might find that https://stackoverflow.com/questions/10077745
/twistedweb-on-multicore-multiprocessor obviates the need for this
option (and
thus your follow-up features as well).
Jean-Paul,
yes, I am aware of this (awesome) answer;) This works, but has 2
slightly
undesirable aspects:
1) it requires to have a master process that creates the socket and
starts workers
which "adopt" the port. I'd like to be able to fire up workers
independently .. with
no master at all.
There are ways around this but they're a bit more work (eg, workers
listen on a unix socket and hand out the port to new workers that start
up and ask for it).
2) the distribution of incoming connections to workers isn't completely
uniformly
distributed across workers.
This problem is explained here (they report up to 3:1 ratios of
connections per worker):
https://lwn.net/Articles/542629/
https://lwn.net/Articles/542718/
and I could verify this during some experiments (though not such
extreme non-uniformity)
Huh. I didn't know about that. That's too bad.
Not that Twisted shouldn't offer some way to gain more control over
this kind
of platform-specific option. But, until it does...
I guess that means there is no "recommended" way currently;)
Correct.
Would you mind giving a tip on how to make use of a CustomPort deriving
of Port? How to "plug" that into Twisted?
I have two suggestions, one of which I hope you'll like and the other of
which you might not. :)
First, endpoints are the intended extension point for this sort of thing
now. You can write a plugin for the parser so that `serverFromString`
will give out server endpoints for your port type (giving an appropriate
string description). Applications won't be able to tell what's going on
because the server endpoint interface is just `.listen(factory)ยด.
Second, please don't subclass `Port`. It's true there are no
underscores anywhere in its name (`twisted.internet.tcp.Port`) making it
part of Twisted's public API. Nevertheless, it's very much a reactor
implementation detail. It's a mistake that it's public. To compounded
this, the exactly interface between a class and its subclasses is hazy
and gross at best. I'd discourage you (and everyone else) from
subclassing *most* things in Twisted these days (lots of our APIs are
still subclassing-oriented so it's not always possible to avoid, of
course).
In this case, I think you might actually be able to re-use all of the
important parts of `Port` without subclassing it. You can create a
bare-bones implementation of `IListeningPort` that creates a socket and
sets the flags you want on it. Then, use `reactor.adoptStreamPort` to
get the reactor to create and initialize a new `Port` with your socket.
This leaves you with a little code to duplicate (basically
`createInternetSocket`) but a pretty small amount - and the upside is
that you're totally isolated from the internals of `Port`, from the
accidentally-public implementation details of `Port`, and even from the
implementation detail of whether the reactor even *uses* `Port` or not.
All you rely on is `reactor.adoptStreamPort` which is a nice,
documented, tested, intentionally-public interface. :)
(For SSL, then you can wrap your own twisted.protocols.tls wrapper
around the factory - which is all the reactor's listenSSL does these
days, anyway).
Hope this helps,
Jean-Paul
_______________________________________________
Twisted-Python mailing list
[email protected]
http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python