Subject: Re: bug#22493: 25.1.50; open-gnutls-stream doesn't respect :nowait, so the connections are synchronous

From: Eli Zaretskii <[email-masked]>
Date: Wed, 03 Feb 2016 17:51:53 +0200

> From: Lars Ingebrigtsen <[email-masked]>
> Cc: [email-masked]
> Date: Wed, 03 Feb 2016 12:10:21 +1100
> 
> >> Sure.  But the wait is much shorter.
> >
> > If it really is, then I must be missing something, because I don't see
> > how it could.  Can you show some timings, comparing the "old" and the
> > "new" methods for making a GnuTLS connection?
> 
> You don't see how taking the DNS resolution out of the "stop everything
> Emacs is doing" bit makes Emacs stop everything it's doing for a shorter
> while?

Of course I do.  But this thread is not about async DNS, it's about
async GnuTLS initialization.  I'm asking how attempting to do that in
the background, _after_ DNS resolution ended, makes the wait shorter.

IOW, I have nothing against using getaddrinfo_a where it's available
(or emulate it where it isn't).  But I don't see any visible
advantages to backgrounding the GnuTLS negotiation, because the way
you did it, it runs in the main thread, and so doesn't save us any
waiting time, AFAIU.  All it does is tremendously increase complexity
of starting a TLS connection.

> > And if somehow it indeed is shorter, the same effect can be achieved
> > by running the GnuTLS negotiation from an idle timer, something that
> > would most probably avoid most or all of the complexities on the C
> > level.  Have you considered this alternative?
> 
> Sure, but we were talking about the DNS resolution...

No, we weren't.  This is about the parts of open-gnutls-stream, which
runs _after_ the DNS resolution.  The changes which I reviewed and
commented on, and which bother me, are those in gnutls.el and
elsewhere that are related to the initial GnuTLS negotiation.

> > This will have to be optional, since Emacs might not become idle for a
> > prolonged time.  IOW, only certain applications will want to benefit
> > from such a background handshake, some will need to wait for its
> > completion.  So if you make this be a background thing by default, you
> > might break existing users that don't expect the negotiation to return
> > before it's completed or failed.
> 
> Sure.  The optional part here is that the user says :nowait when they
> don't want to wait, so I'm not sure I'm getting your objection here,
> either.

An application may wish to make DNS resolution asynchronous, but might
not rely on Emacs becoming idle for GnuTLS initialization.  IOW, we
need a separate option for that.

> If the user has requested a TLS socket, then it's nonsensical to try
> sending data on it before it's completed the negotiation.

So make the sending function wait for the end of the negotiation.

> > One final comment: I think this change will need addition of tests to
> > the test suite, to exercise the affected APIs, so we could make sure
> > we don't introduce any bugs in the existing functionalities.
> 
> Unfortunately, there are virtually no network tests in the suite.  At
> least I couldn't find any.

I know.  We need to add them.  Such a radical change in the core
infrastructure used all over the place cannot be trusted without some
minimal testing of the popular paradigms of its usage.  E.g., does
synchronous URL retrieval still work? what about asynchronous one?
what about SMTP with TLS? etc. etc.  There's a potential here to break
a lot of functionality out there.