GNU bug report logs - #40355
[PATCH] Implement caching for libravatar lookup

Previous Next

Package: emacs;

Reported by: Philip K <philip <at> warpmail.net>

Date: Tue, 31 Mar 2020 18:04:02 UTC

Severity: normal

Tags: fixed, patch

Fixed in version 28.1

Done: Lars Ingebrigtsen <larsi <at> gnus.org>

Bug is archived. No further changes may be made.

Full log


View this message in rfc822 format

From: Philip K <philip <at> warpmail.net>
To: 40355 <at> debbugs.gnu.org
Subject: bug#40355: [PATCH] Implement caching for libravatar lookup
Date: Tue, 31 Mar 2020 20:03:36 +0200
Checking if a domain has an avatar server associated with it requires
at most two (synchronous) DNS queries, at least to ultimately default
to "libravatar.org". Caching the results of domain lookups reduced the
evaluation time (on my machine) from ~0.3s to an instantaneous
evaluation.

* lisp/image/gravatar.el (gravatar--service-libravatar): Check if
  domain has already been resolved before staring DNS queries
(gravatar-libravatar-cache): New variable.
---
 lisp/image/gravatar.el | 40 +++++++++++++++++++++++++++++++---------
 1 file changed, 31 insertions(+), 9 deletions(-)

diff --git a/lisp/image/gravatar.el b/lisp/image/gravatar.el
index a9cd540aa4..2572f9136f 100644
--- a/lisp/image/gravatar.el
+++ b/lisp/image/gravatar.el
@@ -138,14 +138,24 @@ gravatar-service
   :link '(url-link "https://gravatar.com/")
   :group 'gravatar)
 
-(defun gravatar--service-libravatar (addr)
-  "Find domain that hosts avatars for email address ADDR."
+(defvar gravatar-libravatar-cache (make-hash-table :test 'equal)
+  "Cache for `gravatar--service-libravatar'.")
+
+(defun gravatar--service-libravatar (addr &optional cache)
+  "Find domain that hosts avatars for email address ADDR.
+The optional argument CACHE must either be a hash table to
+memorise avatar server resolutions in, or nil, in which case it
+will default to `gravatar-libravatar-cache'."
   ;; implements https://wiki.libravatar.org/api/
   (save-match-data
     (if (not (string-match ".+@\\(.+\\)" addr))
         "https://seccdn.libravatar.org/avatar"
-      (let ((domain (match-string 1 addr)))
+      (let ((domain (downcase (match-string 1 addr))))
         (catch 'found
+          (setq cache (or cache gravatar-libravatar-cache))
+          (let ((cache (gethash domain cache)))
+            (when (and cache (time-less-p (current-time) (cdr cache)))
+              (throw 'found (car cache))))
           (dolist (record '(("_avatars-sec" . "https")
                             ("_avatars" . "http")))
             (let* ((query (concat (car record) "._tcp." domain))
@@ -173,12 +183,24 @@ gravatar--service-libravatar
                                (<= 1 (dns-get 'port rec) 65535)
                                (string-match-p "\\`[-.0-9A-Za-z]+\\'"
                                                (dns-get 'target rec)))
-                      (throw 'found (format "%s://%s:%s/avatar"
-                                            (cdr record)
-                                            (dns-get 'target rec)
-                                            (dns-get 'port rec))))
-                    (setq sum (- sum (dns-get 'weight rec)))))))
-            "https://seccdn.libravatar.org/avatar"))))))
+                      (let ((url (format "%s://%s:%s/avatar"
+                                         (cdr record)
+                                         (dns-get 'target rec)
+                                         (dns-get 'port rec)))
+                            (timeout (if (time-less-p
+                                          (seconds-to-time (dns-get 'ttl rec))
+                                          (days-to-time 1))
+                                         (days-to-time 1)
+                                       (seconds-to-time (dns-get 'ttl rec)))))
+                        (puthash domain
+                                 (cons url (time-add (current-time) timeout))
+                                 cache)
+                        (throw 'found url)))
+                    (setq sum (- sum (dns-get 'weight rec))))))))
+          (car (puthash domain
+                        (cons "https://seccdn.libravatar.org/avatar"
+                              (time-add (current-time) (days-to-time 30)))
+                        cache)))))))
 
 (defun gravatar-hash (mail-address)
   "Return the Gravatar hash for MAIL-ADDRESS."
-- 
2.20.1





This bug report was last modified 4 years and 274 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.