Gnus development mailing list
 help / color / mirror / Atom feed
From: Robert Pluim <rpluim@gmail.com>
To: "Adam Sjøgren" <asjo@koldfront.dk>
Cc: ding@gnus.org,  emacs-devel@gnu.org
Subject: Re: Rendering regression in Gnus with gnus-treat-from-gravatar
Date: Tue, 14 Apr 2020 15:14:11 +0200	[thread overview]
Message-ID: <m21roqmcpo.fsf@gmail.com> (raw)
In-Reply-To: <m27dymm0a5.fsf@gmail.com> (Robert Pluim's message of "Sat, 11 Apr 2020 18:53:38 +0200")

>>>>> On Sat, 11 Apr 2020 18:53:38 +0200, Robert Pluim <rpluim@gmail.com> said:

    Robert> OK, so itʼs the DNS. The libravatar method does a bunch of DNS
    Robert> queries, and those can be slow, and they're done for every article.

    Robert> I guess we need to see if we can make those DNS lookups asynchronous.

The following does at least make rendering of the article complete
straight away, although you might end up waiting a little longer for
the gravatar to actually appear. Iʼm assuming your emacs has thread
support.

(the inhibit-redisplay is there because otherwise this crashes on
macOS, where apparently you can only call certain OS window system
functions from the main thread).

diff --git a/lisp/image/gravatar.el b/lisp/image/gravatar.el
index ff59a72ac8..b9ad16bb28 100644
--- a/lisp/image/gravatar.el
+++ b/lisp/image/gravatar.el
@@ -149,7 +149,7 @@ gravatar--service-libravatar
           (dolist (record '(("_avatars-sec" . "https")
                             ("_avatars" . "http")))
             (let* ((query (concat (car record) "._tcp." domain))
-                   (result (dns-query query 'SRV)))
+                   (result (dns-query-cached query 'SRV)))
               (when result
                 (throw 'found (format "%s://%s/avatar"
                                       (cdr record)
@@ -189,17 +189,41 @@ gravatar-get-data
          (search-forward "\n\n" nil t)
          (buffer-substring (point) (point-max)))))
 
-;;;###autoload
-(defun gravatar-retrieve (mail-address callback &optional cbargs)
+(defvar gravatar-retrieve-params nil)
+(defvar gravatar-thread nil)
+(defvar gravatar-exit-thread nil)
+(defvar gravatar-mutex nil)
+(defvar gravatar-cond-var nil)
+
+(defun gravatar-retrieve-thread ()
   "Asynchronously retrieve a gravatar for MAIL-ADDRESS.
 When finished, call CALLBACK as (apply CALLBACK GRAVATAR CBARGS),
 where GRAVATAR is either an image descriptor, or the symbol
 `error' if the retrieval failed."
-  (let ((url (gravatar-build-url mail-address)))
-    (if (url-cache-expired url gravatar-cache-ttl)
-        (url-retrieve url #'gravatar-retrieved (list callback cbargs) t)
-      (with-current-buffer (url-fetch-from-cache url)
-        (gravatar-retrieved () callback cbargs)))))
+  (while (not gravatar-exit-thread)
+    (with-mutex gravatar-mutex
+      (condition-wait gravatar-cond-var)
+      (let ((inhibit-redisplay t)
+            (mail-address (nth 0 gravatar-retrieve-params))
+            (callback (nth 1 gravatar-retrieve-params))
+            (cbargs (nth 2 gravatar-retrieve-params)))
+        (let ((url (gravatar-build-url mail-address)))
+          (if (url-cache-expired url gravatar-cache-ttl)
+              (url-retrieve url #'gravatar-retrieved (list callback cbargs) t)
+            (with-current-buffer (url-fetch-from-cache url)
+              (gravatar-retrieved () callback cbargs)))))
+      (thread-yield))))
+
+;;;###autoload
+(defun gravatar-retrieve (mail-address callback &optional cbargs)
+  (unless gravatar-thread
+    (setq gravatar-mutex (make-mutex)
+          gravatar-cond-var (make-condition-variable gravatar-mutex)
+          gravatar-thread (make-thread #'gravatar-retrieve-thread)))
+  (with-mutex gravatar-mutex
+    (setq gravatar-retrieve-params
+          (list mail-address callback cbargs))
+    (condition-notify gravatar-cond-var)))
 
 ;;;###autoload
 (defun gravatar-retrieve-synchronously (mail-address)


  reply	other threads:[~2020-04-14 13:15 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <877dym5fes.fsf@tullinup.koldfront.dk>
2020-04-11 14:15 ` Robert Pluim
2020-04-11 15:16   ` Adam Sjøgren
2020-04-11 16:53     ` Robert Pluim
2020-04-14 13:14       ` Robert Pluim [this message]
2020-04-14 15:46         ` Eli Zaretskii
2020-04-14 17:32         ` Adam Sjøgren
2020-04-15  8:15           ` Robert Pluim
2020-04-15  9:41             ` Eli Zaretskii
2020-04-15 10:13               ` Robert Pluim
2020-04-15 11:38                 ` Eli Zaretskii
2020-04-15 11:55                   ` Robert Pluim
2020-04-15 12:01                     ` Eli Zaretskii
2020-04-15 13:54                       ` Robert Pluim
2020-04-15 14:12                         ` Eli Zaretskii
2020-04-15 14:20                           ` Robert Pluim
2020-04-22 14:25       ` Tassilo Horn
2020-04-22 14:39         ` Tassilo Horn
2020-04-22 14:56           ` Robert Pluim
2020-04-22 17:32             ` Tassilo Horn
2020-04-22 14:59         ` Robert Pluim
2020-04-22 17:01           ` Tassilo Horn
2020-04-22 17:23             ` Robert Pluim

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=m21roqmcpo.fsf@gmail.com \
    --to=rpluim@gmail.com \
    --cc=asjo@koldfront.dk \
    --cc=ding@gnus.org \
    --cc=emacs-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).