Commit bd77ef3b authored by Denis Bilenko's avatar Denis Bilenko

examples/portforwarder.py: add __docstring__, treat multiple signals as "exit now" request.

Do not handle QUIT, let Ctrl-\ work. Do not print stacktrace if target cannot be connected to.
parent a13c14e9
"""Port forwarder with graceful exit.
Run the example as
python portforwarder.py :8080 gevent.org:80
Then direct your browser to http://localhost:8080 or do "telnet localhost 8080".
When the portforwarder receives TERM or INT signal (type Ctrl-C),
it closes the listening socket and waits for all existing
connections to finish. The existing connections will remain unaffected.
The program will exit once the last connection has been closed.
"""
import sys import sys
import signal import signal
import gevent import gevent
...@@ -13,14 +26,20 @@ class PortForwarder(StreamServer): ...@@ -13,14 +26,20 @@ class PortForwarder(StreamServer):
def handle(self, source, address): def handle(self, source, address):
log('%s:%s accepted', *address[:2]) log('%s:%s accepted', *address[:2])
dest = create_connection(self.dest) try:
forwarder1 = gevent.spawn(forward, source, dest) dest = create_connection(self.dest)
forwarder2 = gevent.spawn(forward, dest, source) except IOError, ex:
gevent.joinall([forwarder1, forwarder2], count=1) log('%s:%s failed to connect to %s:%s: %s', address[0], address[1], self.dest[0], self.dest[1], ex)
return
gevent.spawn(forward, source, dest)
gevent.spawn(forward, dest, source)
def close(self): def close(self):
print 'Closing listener socket' if self.closed:
StreamServer.close(self) sys.exit('Multiple exit signals received - aborting.')
else:
log('Closing listener socket')
StreamServer.close(self)
def forward(source, dest): def forward(source, dest):
...@@ -56,7 +75,6 @@ def main(): ...@@ -56,7 +75,6 @@ def main():
server = PortForwarder(source, dest) server = PortForwarder(source, dest)
log('Starting port forwarder %s:%s -> %s:%s', *(server.address[:2] + dest)) log('Starting port forwarder %s:%s -> %s:%s', *(server.address[:2] + dest))
gevent.signal(signal.SIGTERM, server.close) gevent.signal(signal.SIGTERM, server.close)
gevent.signal(signal.SIGQUIT, server.close)
gevent.signal(signal.SIGINT, server.close) gevent.signal(signal.SIGINT, server.close)
server.start() server.start()
gevent.run() gevent.run()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment