Hi!
I have developed a simple twisted tcp server which does ldap lookups as a result of user input. I would like to limit the number of connections each listener (I have 4, each on its own port) accepts. I guess people usually want to accept as many connections as possible, but I would like to limit them.
From what I've read (a single post from 2009):
"As you observed, doing this on the server accepts and then immediately closes the connection. There is no way to not accept the connection. This is a limitation of the underlying platform APIs."
Is this still the case? We can't limit the number of accepted connections?
Regards, Miha.
Hi,
On 9 December 2012 02:17, Miha Valencic miha.valencic@gmail.com wrote:
Hi!
I have developed a simple twisted tcp server which does ldap lookups as a result of user input. I would like to limit the number of connections each listener (I have 4, each on its own port) accepts. I guess people usually want to accept as many connections as possible, but I would like to limit them.
From what I've read (a single post from 2009): "As you observed, doing this on the server accepts and then immediately closes the connection. There is no way to not accept the connection. This is a limitation of the underlying platform APIs."
Is this still the case? We can't limit the number of accepted connections?
Just to summarize:
* twisted.protocols.policies.LimitTotalConnectionsFactory is not what you want since the server is still listening on the port? LimitTotalConnectionsFactory is only returning a different protocol to handle the overflow.... closing the new connection is a way to handle the overflow.
* After a number of connections the server should stop listening on the port... and then tor re-start listening after the connections are closed?
Cheers,
Hi Adi!
Let me say upfront, that I'm not seeing any problems as of now. I am asking this question out of engineering curiosity mostly and to know whta to do if the problem would arose.
On Sun, Dec 9, 2012 at 10:44 AM, Adi Roiban adi@roiban.ro wrote:
Hi, Just to summarize:
- twisted.protocols.policies.LimitTotalConnectionsFactory is not what
you want since the server is still listening on the port? LimitTotalConnectionsFactory is only returning a different protocol to handle the overflow.... closing the new connection is a way to handle the overflow.
I've never heard of LimitTotalConnectionsFactory before. This particular mode of operation is desirable, since the client is connected and disconnected. I was aiming more towards a usual approach within webservers, where they have a certain amount of tcp workers, and size of the waiting queue. That way the client does not get disconnected, but waits a little and then gets a result. You know how to webserver sometimes times out...
But, really, thinking about it, this factory is the right after all. Akin to "http 550 service unavailable" when the service is not able to respond to requests. If I understand the description correctly, defining custom protocol that write "unavailable" and closes connection, setting this protocol as a overflowProtocol would have the exact behaviour I am after.
- After a number of connections the server should stop listening on
the port... and then tor re-start listening after the connections are closed?
No, the server shouldn't accept() the socket after n connections are opened(). But see previous paragraph.
Regards, Miha.
On 12/09/2012 05:31 AM, Miha Valencic wrote:
No, the server shouldn't accept() the socket after n connections are opened(). But see previous paragraph.
You can stop accept()ing by calling stopReading() on the returned port object:
port = reactor.listenTCP(....) port.stopReading()
And start again by calling startReading().
However: - When you are accept()ing, it will accept() a few at a time. - Even if you stop accept()ing, the OS will still do TCP handshakes, approximately up to a limit determined by one of the arguments passed to listenTCP. - After hitting the limit, clients will get connection refused, IIRC.
In general it's better to do a protocol-level solution, as Adi Roiban suggested.
Itamar, I agree. After reading Adi Roiban's proposed solution I think it is the correct way to handle such scenarios.
Regards, Miha.
On Sun, Dec 9, 2012 at 1:57 PM, Itamar Turner-Trauring itamar@itamarst.org wrote:
On 12/09/2012 05:31 AM, Miha Valencic wrote:
No, the server shouldn't accept() the socket after n connections are opened(). But see previous paragraph.
You can stop accept()ing by calling stopReading() on the returned port object:
port = reactor.listenTCP(....) port.stopReading()
And start again by calling startReading().
However:
- When you are accept()ing, it will accept() a few at a time.
- Even if you stop accept()ing, the OS will still do TCP handshakes,
approximately up to a limit determined by one of the arguments passed to listenTCP.
- After hitting the limit, clients will get connection refused, IIRC.
In general it's better to do a protocol-level solution, as Adi Roiban suggested.
Twisted-Python mailing list Twisted-Python@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
On 9 December 2012 14:57, Itamar Turner-Trauring itamar@itamarst.org wrote:
On 12/09/2012 05:31 AM, Miha Valencic wrote:
No, the server shouldn't accept() the socket after n connections are opened(). But see previous paragraph.
You can stop accept()ing by calling stopReading() on the returned port object:
port = reactor.listenTCP(....) port.stopReading()
And start again by calling startReading().
[snip]
Many thanks for you explanation.
Checking the documentation I can read that reactor.listenTCP returns an IListeningPort [1] Checking IListeningPort I can read that it has no stopReading() , startReading() methods [2]
Can you please advise how and when to use startReading vs startListening ?
Many thanks!
[1] http://twistedmatrix.com/documents/12.2.0/api/twisted.internet.interfaces.IR... [2] http://twistedmatrix.com/documents/12.2.0/api/twisted.internet.interfaces.IL...
On 12/09/2012 08:14 AM, Adi Roiban wrote:
Many thanks for you explanation.
Checking the documentation I can read that reactor.listenTCP returns an IListeningPort [1] Checking IListeningPort I can read that it has no stopReading() , startReading() methods [2]
Can you please advise how and when to use startReading vs startListening ?
A port object is also typically a IReadWriteFileDescriptor or whatever the interface is, though perhaps not on IOCP, or some other hypothetical future reactor. startListening() does the opposite of stopListening(), it's completely different than stop/startReading - the former pair are permanent 'open or close the socket', vs. the latter 'unregister socket from event loop temporarily'.
In any case, as I said, doing stopReading() on a TCP port is not particularly useful, much better to handle it in factory and protocol level.
On 9 December 2012 15:23, Itamar Turner-Trauring itamar@itamarst.org wrote:
On 12/09/2012 08:14 AM, Adi Roiban wrote:
Many thanks for you explanation.
Checking the documentation I can read that reactor.listenTCP returns an IListeningPort [1] Checking IListeningPort I can read that it has no stopReading() , startReading() methods [2]
Can you please advise how and when to use startReading vs startListening ?
A port object is also typically a IReadWriteFileDescriptor or whatever the interface is, though perhaps not on IOCP, or some other hypothetical future reactor. startListening() does the opposite of stopListening(), it's completely different than stop/startReading - the former pair are permanent 'open or close the socket', vs. the latter 'unregister socket from event loop temporarily'.
In any case, as I said, doing stopReading() on a TCP port is not particularly useful, much better to handle it in factory and protocol level.
Many thanks! That answered my question.
On 9 December 2012 15:14, Adi Roiban adi@roiban.ro wrote:
On 9 December 2012 14:57, Itamar Turner-Trauring itamar@itamarst.org wrote:
On 12/09/2012 05:31 AM, Miha Valencic wrote:
No, the server shouldn't accept() the socket after n connections are opened(). But see previous paragraph.
You can stop accept()ing by calling stopReading() on the returned port object:
port = reactor.listenTCP(....) port.stopReading()
And start again by calling startReading().
[snip]
Many thanks for you explanation.
Checking the documentation I can read that reactor.listenTCP returns an IListeningPort [1] Checking IListeningPort I can read that it has no stopReading() , startReading() methods [2]
Can you please advise how and when to use startReading vs startListening ?
I would like to rephrase my previous question:
I understood that stopListening() is closing the listening socket, while stopReading does not closed the listening socket, but rather stops from handling new connection using the attached factory ... and new connections are queued in the backlog.
What interfaces defines startReading/stopReading for a TCP Port?
Thanks!
On 9 December 2012 12:31, Miha Valencic miha.valencic@gmail.com wrote:
Hi Adi!
Let me say upfront, that I'm not seeing any problems as of now. I am asking this question out of engineering curiosity mostly and to know whta to do if the problem would arose.
On Sun, Dec 9, 2012 at 10:44 AM, Adi Roiban adi@roiban.ro wrote:
Hi, Just to summarize:
- twisted.protocols.policies.LimitTotalConnectionsFactory is not what
you want since the server is still listening on the port? LimitTotalConnectionsFactory is only returning a different protocol to handle the overflow.... closing the new connection is a way to handle the overflow.
I've never heard of LimitTotalConnectionsFactory before. This particular mode of operation is desirable, since the client is connected and disconnected. I was aiming more towards a usual approach within webservers, where they have a certain amount of tcp workers, and size of the waiting queue. That way the client does not get disconnected, but waits a little and then gets a result. You know how to webserver sometimes times out...
But, really, thinking about it, this factory is the right after all. Akin to "http 550 service unavailable" when the service is not able to respond to requests. If I understand the description correctly, defining custom protocol that write "unavailable" and closes connection, setting this protocol as a overflowProtocol would have the exact behaviour I am after.
Yes. You can implement a simple HTTP protocol which always returns 503 or some other code.
- After a number of connections the server should stop listening on
the port... and then tor re-start listening after the connections are closed?
No, the server shouldn't accept() the socket after n connections are opened(). But see previous paragraph.
I think that we are talking about different "accepts", but LimitTotalConnectionsFactory should do your job.
Cheers