emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Asynchronous DNS


From: Lars Magne Ingebrigtsen
Subject: Asynchronous DNS
Date: Sat, 23 Jan 2016 14:50:54 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/25.1.50 (gnu/linux)

I talked about this a few years ago, but I didn't get very far, so I
thought I'd reopen the subject and actually implement something this
time.

The problem is a general one: Everything about network communication in
Emacs is asynchronous, except name resolution.  In many cases, this
isn't really that much of a problem, because whatever Emacs is doing has
to wait for the entire network process to finish (say, copying a file
over tramp), so that one part is synchronous isn't very noticeable.

The one place it's really noticeable is in eww.  You go to a page, and
then Emacs will freeze (sometimes for many seconds), and then Emacs will
unfreeze and start inserting images into the page.  The freeze bit is
when it's doing name resolution in `make-network-process' by calling
getaddrinfo or gethostbyname.

I see four ways of implementing an async name resolution function:

1) Add a new `resolve-name' function that would fork Emacs, call
getaddrinfo/gethostbyname, and do a callback once we get a reply.  The
problem is that a forked Emacs is a very strange thing, and is not
something we otherwise do.  I looked at this for a day last time, and I
couldn't get it to work, really.  Perhaps somebody else could, though.

2) Use one of the newer async C resolver libraries.  This would not be
available on all platforms, and would be Yet Another Dependency which
I'm sure everybody would rather that we avoid.

3) Create a tiny helper program in lib-src that would read names from
stdin and output resolves on stdout.  It would use
getaddrinfo/gethostbyname, and could very well be multithreaded, so that
it could do name resolution on parallel.

4) Pick the data out of res_init to find the DNS servers, and then just
use dns.el for name resolution.  This would be trivial to implement, but
may not respect the name resolutions settings on some operating systems.

In either case, I envision anything that wants async name resolution to
basically transform from

(make-network-process :host "foo.bar" ...)

to

(resolve-name "foo.bar"
  (lambda (status ip)
    (make-network-process :host "foo.bar" :ip ip ...)))

or something along those lines.  That is -- pass in a preresolved IP
address to `make-network-process'.

(Or list of addresses in the case of multihomed hosts, of course.
Details, details.)

So what do you think?  I'm up for implementing 3) or 4), but probably
not 1) or 2), but I think 1) would be the cleanest way to implement
this, if possible.

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





reply via email to

[Prev in Thread] Current Thread [Next in Thread]