Announcements and discussions for Gnus, the GNU Emacs Usenet newsreader
 help / color / mirror / Atom feed
From: "Adam Sjøgren" <asjo@koldfront.dk>
To: info-gnus-english@gnu.org
Subject: Re: Keeping IMAP connection alive when using it in mail-sources
Date: Tue, 10 Jan 2023 20:24:20 +0100	[thread overview]
Message-ID: <874jsyw5uj.fsf@tullinup.koldfront.dk> (raw)
In-Reply-To: <878riaw8vt.fsf@tullinup.koldfront.dk>

Adam writes:

> Eric writes:
>
>> Not with the code as it's written! There's a very definite
>> (imap-close buf) at the end of the mail source fetching, then the buffer
>> is deleted. I guess it wouldn't be a bad idea to add a keepalive option
>> to imap.el, but someone would have to do that!
>
> I guess changing mail-source-fetch-imap to check if the buffer already
> exists and if the connected process is still there, and then not closing
> imap and not killing the buffer at the end, would be the bare minimum.

I've tried doing that now.

Fetching news and mail now takes me 1.3 second, down from 2.2 seconds.

Nice!

Here's the modified version of mail-source-fetch-imap I cobbled
together - the handling of deleting the buffer if there is no process is
not so pretty:

(defun mail-source-fetch-imap (source callback)
  "Fetcher for imap sources."
  (mail-source-bind (imap source)
    (mail-source-run-script
     prescript
     `((?p . ,password) (?t . ,mail-source-crash-box)
       (?s . ,server) (?P . ,port) (?u . ,user))
     prescript-delay)
    (let ((from (format "%s:%s:%s" server user port))
	  (found 0)
          (imap-shell-program (or (list program) imap-shell-program)))
      (let ((buf (or (and (or (get-buffer-process " *imap source*")
                              (and (get-buffer " *imap source*")
                                   (kill-buffer " *imap source*")))
                          (get-buffer " *imap source*"))
                     (let ((newbuf (generate-new-buffer " *imap source*")))
	               (if (and (imap-open server port stream authentication newbuf)
	                        (imap-authenticate
		                 user (or (cdr (assoc from mail-source-password-cache))
                                          password)
                                 newbuf))
                           newbuf
                         (progn
                           (imap-close newbuf)
	                   ;; We nix out the password in case the error
	                   ;; was because of a wrong password being given.
	                   (setq mail-source-password-cache
	                         (delq (assoc from mail-source-password-cache)
		                       mail-source-password-cache))
	                   (error "IMAP error: %s" (imap-error-text newbuf))))))))
        (let ((mailbox-list (if (listp mailbox) mailbox (list mailbox))))
          (dolist (mailbox mailbox-list)
            (when (imap-mailbox-select mailbox nil buf)
	      (let ((coding-system-for-write
                     mail-source-imap-file-coding-system)
	            (mail-source-string (format "imap:%s:%s" server mailbox))
	            str remove)
                (message "Fetching from %s..." mailbox)
	        (with-temp-file mail-source-crash-box
	          ;; Avoid converting 8-bit chars from inserted strings to
	          ;; multibyte.
	          (mm-disable-multibyte)
	          ;; remember password
	          (with-current-buffer buf
		    (when (and imap-password
			       (not (member (cons from imap-password)
                                            mail-source-password-cache)))
		      (push (cons from imap-password) mail-source-password-cache)))
	          ;; if predicate is nil, use all uids
	          (dolist (uid (imap-search (or predicate "1:*") buf))
		    (when (setq str
			        (if (imap-capability 'IMAP4rev1 buf)
				    (caddar (imap-fetch uid "BODY.PEEK[]"
						        'BODYDETAIL nil buf))
			          (imap-fetch uid "RFC822.PEEK" 'RFC822 nil buf)))
		      (push uid remove)
		      (insert "From imap " (current-time-string) "\n")
		      (save-excursion
		        (insert str "\n\n"))
		      (while (let ((case-fold-search nil))
			       (re-search-forward "^From " nil t))
		        (replace-match ">From "))
		      (goto-char (point-max))))
	          (nnheader-ms-strip-cr))
	        (cl-incf found (mail-source-callback callback server))
	        (mail-source-delete-crash-box)
	        (when (and remove fetchflag)
	          (setq remove (nreverse remove))
	          (imap-message-flags-add
	           (imap-range-to-message-set (gnus-compress-sequence remove))
	           fetchflag nil buf))
	        (if dontexpunge
		    (imap-mailbox-unselect buf)
                  (imap-mailbox-close nil buf))))))
        (mail-source-run-script
         postscript
         `((?p . ,password) (?t . ,mail-source-crash-box)
           (?s . ,server) (?P . ,port) (?u . ,user)))
        found))))


-- 
 "A cat has nine lives, but a bullfrog croaks every         Adam Sjøgren
  day."                                                asjo@koldfront.dk



  reply	other threads:[~2023-01-10 19:26 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-01-08 18:10 Eric Abrahamsen
2023-01-10 18:18 ` Adam Sjøgren
2023-01-10 19:24   ` Adam Sjøgren [this message]
2023-01-10 20:08     ` Emanuel Berg
2023-01-14 21:29     ` Adam Sjøgren
2023-01-15 19:55       ` Adam Sjøgren
  -- strict thread matches above, loose matches on Subject: below --
2023-01-07 23:49 Adam Sjøgren

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=874jsyw5uj.fsf@tullinup.koldfront.dk \
    --to=asjo@koldfront.dk \
    --cc=info-gnus-english@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).