tirsdag den 6. januar 2009

A small trick for socket timouts in Plone

A few times I have had the need for a socket to timout in Plone. Eg when calling an external site that might be down.

You can set the timeout in Plone, but that is not a good idea as you sometime need long running processes to end properly, eg for packing etc.

A workaround is spwaning seperate threads and callback routines. But that is a bother to set up.

Suddenly it stroke me today that it would be possible to change the timout temporarily for a single thread:



import socket
import feedparser

def parseUrl(self, url):
"Fetch the url"
orig_timout = socket.getdefaulttimeout() # get original timeout
# give it a 20 second timout
socket.setdefaulttimeout(20) # set to 20 seconds
try:
result = feedparser.parse(url)['entries']
except:
result = []
socket.setdefaulttimeout(orig_timout) # set back to original
endresult = []
for r in result:
r2 = {}
r2.update(r)
endresult.append(r2)
# sort for latest first
decorated = [(r['updated_parsed'], r) for r in endresult]
decorated.sort()
decorated.reverse()
sorted = [d[-1] for d in decorated]
return sorted


Sweet and simple ...

4 kommentarer:

Ramas sagde ...

You should also reset to original timeout in exception handler.

Max M sagde ...

Why is that necessary? It is set after the exception handler anyway.

psucorp sagde ...

I'm pretty sure you're setting the default timeout globally, not per thread, so you've got a race condition there.

Erik Rose

Max M sagde ...

No.

Zope typically has 4 "threads" running. But each thread is its own python proces. They are not an actual OS thread.

So actually you only set the timout for one process.