Asynchronous DNS queries in Python
When you have an application that’s event-driven (like twisted), you’ve gotta eliminate all potentially blocking operations, or you risk putting your entire app to sleep while you wait for the blocking operation to complete. The XMPP server I’m working on has to send out DNS queries all the time, and these could take a while. I had to figure out how to make these queries asynchronous, so that they wouldn’t block the entire server. There are adns bindings, but the GNU adns library is licensed under the GPL (I’m trying to stick to more liberal licenses) and not straightforward to install on Windows. There’s a DNS toolkit library for python, but it doesn’t support asynchronous lookups natively. Enter the asyncore module. The following should allow you to query DNS and then get callbacks to handle_read() when the data is available.
import asyncore, socket from dns import resolver, rdatatype, rdataclass, message class AsyncDNS(asyncore.dispatcher): def __init__(self): asyncore.dispatcher.__init__(self) self.r = resolver.Resolver() self.query = '' self.create_socket(socket.AF_INET, socket.SOCK_DGRAM) self.connect((self.r.nameservers[0], self.r.port)) def makeQuery(self, server): self.query = message.make_query('_xmpp-server._tcp.%s' % server, rdatatype.SRV, rdataclass.IN).to_wire() def writable(self): return (len(self.query) > 0) def handle_read(self): data = self.recv(4096) answer = message.from_wire(data) print answer.answer[0].to_text() def handle_write(self): self.send(self.query) self.query = '' def handle_accept(self): pass def handle_connect(self): pass def handle_bind(self): pass def handle_close(self): self.close() if __name__ == "__main__": d = AsyncDNS() d.makeQuery('livejournal.com') asyncore.loop()
Trackback URL for this post:
Archives
| Sun | Mon | Tue | Wed | Thu | Fri | Sat |
|---|---|---|---|---|---|---|
| 26 | 27 | 28 | 29 | 30 | 31 | 1 |
| 2 | 3 | 4 | 5 | 6 | 7 | 8 |
| 9 | 10 | 11 | 12 | 13 | 14 | 15 |
| 16 | 17 | 18 | 19 | 20 | 21 | 22 |
| 23 | 24 | 25 | 26 | 27 | 28 | 29 |
| 30 | 1 | 2 | 3 | 4 | 5 | 6 |



Comments
Post new comment