>From 1aa19dfed950c209ad5a2ddf48e2b828b50c07ee Mon Sep 17 00:00:00 2001 From: Matt Domsch <Matt_Domsch@xxxxxxxx> Date: Wed, 12 May 2010 13:52:51 -0500 Subject: [PATCH] mirrorlist_client: a better way to handle socket timeouts blocking sockets, calling recv(), may block forever if the server end doesn't send anything for some reason. Don't let that happen. Python has a socket.settimeout() capability. We'll use that to let any individual operation (except the select()) take up to 5 seconds (they should all be in the microsecond range, so this is very generous), and let select() continue to wait for 60 seconds for the server to respond at all. If a timeout happens, an exception is raised, which is caught by the caller and a HTTP 503 returned to the web client. --- mirrorlist-server/mirrorlist_client.wsgi | 17 ++++++++--------- 1 files changed, 8 insertions(+), 9 deletions(-) diff --git a/mirrorlist-server/mirrorlist_client.wsgi b/mirrorlist-server/mirrorlist_client.wsgi index 15b3a15..3508f19 100755 --- a/mirrorlist-server/mirrorlist_client.wsgi +++ b/mirrorlist-server/mirrorlist_client.wsgi @@ -13,14 +13,14 @@ import cStringIO from datetime import datetime, timedelta socketfile = '/var/run/mirrormanager/mirrorlist_server.sock' -request_timeout = 60 # seconds +select_timeout = 60 # seconds +timeout = 5 # seconds def get_mirrorlist(d): - try: - s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) - s.connect(socketfile) - except: - raise + # any exceptions or timeouts raised here get handled by the caller + s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + s.settimeout(timeout) + s.connect(socketfile) p = pickle.dumps(d) del d @@ -33,8 +33,7 @@ def get_mirrorlist(d): del p # wait for other end to start writing - expiry = datetime.utcnow() + timedelta(seconds=request_timeout) - rlist, wlist, xlist = select.select([s],[],[],request_timeout) + rlist, wlist, xlist = select.select([s],[],[],select_timeout) if len(rlist) == 0: s.shutdown(socket.SHUT_RD) raise socket.timeout @@ -48,7 +47,7 @@ def get_mirrorlist(d): readlen = 0 p = '' - while readlen < resultsize and datetime.utcnow() < expiry: + while readlen < resultsize: p += s.recv(resultsize - readlen) readlen = len(p) results = pickle.loads(p) -- 1.7.0.1 -- Matt Domsch Technology Strategist Dell | Office of the CTO _______________________________________________ infrastructure mailing list infrastructure@xxxxxxxxxxxxxxxxxxxxxxx https://admin.fedoraproject.org/mailman/listinfo/infrastructure