[notmuch] [PATCH] Calls to notmuch get queued and executed asynchronously.
authorJames Vasile <james@hackervisions.org>
Tue, 23 Feb 2010 16:32:51 +0000 (11:32 +1900)
committerW. Trevor King <wking@tremily.us>
Fri, 7 Nov 2014 17:36:15 +0000 (09:36 -0800)
8f/f7102473dd278438d7a3f991bf88f8852f7118 [new file with mode: 0644]

diff --git a/8f/f7102473dd278438d7a3f991bf88f8852f7118 b/8f/f7102473dd278438d7a3f991bf88f8852f7118
new file mode 100644 (file)
index 0000000..aebb225
--- /dev/null
@@ -0,0 +1,171 @@
+Return-Path: <james@hackervisions.org>\r
+X-Original-To: notmuch@notmuchmail.org\r
+Delivered-To: notmuch@notmuchmail.org\r
+Received: from localhost (localhost [127.0.0.1])\r
+       by olra.theworths.org (Postfix) with ESMTP id 5E55B431FBC\r
+       for <notmuch@notmuchmail.org>; Tue, 23 Feb 2010 08:33:06 -0800 (PST)\r
+X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
+X-Spam-Flag: NO\r
+X-Spam-Score: -1.249\r
+X-Spam-Level: \r
+X-Spam-Status: No, score=-1.249 tagged_above=-999 required=5\r
+       tests=[AWL=-1.350, BAYES_50=0.001, RDNS_DYNAMIC=0.1] autolearn=no\r
+Received: from olra.theworths.org ([127.0.0.1])\r
+       by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
+       with ESMTP id oqouYxszil63 for <notmuch@notmuchmail.org>;\r
+       Tue, 23 Feb 2010 08:33:04 -0800 (PST)\r
+Received: from hackervisions.org (67-207-143-141.slicehost.net\r
+       [67.207.143.141])\r
+       by olra.theworths.org (Postfix) with ESMTP id 2E31B431FAE\r
+       for <notmuch@notmuchmail.org>; Tue, 23 Feb 2010 08:33:04 -0800 (PST)\r
+Received: from john-marshall.sflc.info ([216.27.154.200]\r
+       helo=wyzanski.hackervisions.org)\r
+       by hv with esmtpsa (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.69)\r
+       (envelope-from <james@hackervisions.org>)\r
+       id 1Njxh0-00031D-BS; Tue, 23 Feb 2010 11:33:02 -0500\r
+Date: Tue, 23 Feb 2010 11:32:51 -0500\r
+Message-ID: <87vddnlxos.wl%james@hackervisions.org>\r
+From: James Vasile <james@hackervisions.org>\r
+To: notmuch@notmuchmail.org\r
+X-Mailer: Wanderlust/2.15.6\r
+User-Agent: SEMI/1.14.6 (Maruoka) FLIM/1.14.9 (=?UTF-8?B?R29qxY0=?=)\r
+       APEL/10.7 Emacs/23.1 (i486-pc-linux-gnu) MULE/6.0 (HANACHIRUSATO)\r
+MIME-Version: 1.0 (generated by SEMI 1.14.6 - "Maruoka")\r
+Content-Type: text/plain; charset=US-ASCII\r
+Subject: [notmuch] [PATCH] Calls to notmuch get queued and executed\r
+       asynchronously.\r
+X-BeenThere: notmuch@notmuchmail.org\r
+X-Mailman-Version: 2.1.13\r
+Precedence: list\r
+List-Id: "Use and development of the notmuch mail system."\r
+       <notmuch.notmuchmail.org>\r
+List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
+       <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
+List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
+List-Post: <mailto:notmuch@notmuchmail.org>\r
+List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
+List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
+       <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
+X-List-Received-Date: Tue, 23 Feb 2010 16:33:06 -0000\r
+\r
+Added notmuch-enqueue-asynch to replace calls to\r
+notmuch-call-notmuch-process.  Calls to notmuch are then queued and\r
+executed asynchronously.  If the db is busy and we get an error saying\r
+it was locked, keep trying until the db is no longer busy.  Errors go\r
+in a buffer as per usual.\r
+\r
+The only caveat here is that if the db is permanently locked (i.e. the\r
+lock is broken), we just keep on trying forever.  Maybe there should\r
+probably be a maximum number of tries or a timeout, but since 'notmuch\r
+new' can take a long time, it's difficult to come up with a reasonable\r
+limit.\r
+---\r
+ notmuch.el |   57 ++++++++++++++++++++++++++++++++++++++++++++++++++++-----\r
+ 1 files changed, 52 insertions(+), 5 deletions(-)\r
+\r
+diff --git a/notmuch.el b/notmuch.el\r
+index 6482170..7fc63e9 100644\r
+--- a/notmuch.el\r
++++ b/notmuch.el\r
+@@ -302,7 +302,7 @@ pseudoheader summary"\r
+   "Add a tag to the current message."\r
+   (interactive\r
+    (list (notmuch-select-tag-with-completion "Tag to add: ")))\r
+-  (apply 'notmuch-call-notmuch-process\r
++  (apply 'notmuch-enqueue-asynch\r
+        (append (cons "tag"\r
+                      (mapcar (lambda (s) (concat "+" s)) toadd))\r
+                (cons (notmuch-show-get-message-id) nil)))\r
+@@ -315,7 +315,7 @@ pseudoheader summary"\r
+   (let ((tags (notmuch-show-get-tags)))\r
+     (if (intersection tags toremove :test 'string=)\r
+       (progn\r
+-        (apply 'notmuch-call-notmuch-process\r
++        (apply 'notmuch-enqueue-asynch\r
+                (append (cons "tag"\r
+                              (mapcar (lambda (s) (concat "-" s)) toremove))\r
+                        (cons (notmuch-show-get-message-id) nil)))\r
+@@ -1374,6 +1374,53 @@ Complete list of currently available key bindings:\r
+   (let ((message-id (notmuch-search-find-thread-id)))\r
+     (notmuch-reply message-id)))\r
\r
++(defun join-string-list (string-list)\r
++    "Concatenates a list of strings and puts spaces between the\r
++elements."\r
++    (mapconcat 'identity string-list " "))\r
++\r
++(defvar notmuch-asynch-queue nil)\r
++(defun notmuch-call-notmuch-process-asynch (&rest args)\r
++  "Asynchronously invoke \"notmuch\" with the given list of arguments.\r
++\r
++Error output from the process will be presented to the user as an\r
++error and will also appear in a buffer named \"*notmuch <arguments>*\"."\r
++  (when args\r
++    (let ((process-connection-type nil)\r
++        (buffer-name (format "*notmuch %s*" (join-string-list args))))\r
++      (when (get-buffer buffer-name)\r
++      (kill-buffer (get-buffer buffer-name)))\r
++      (let* ((process-buffer (get-buffer-create buffer-name))\r
++           (process (apply 'start-process "notmuch-process" process-buffer\r
++                           notmuch-command args)))\r
++      (set-process-sentinel process 'notmuch-call-notmuch-process-asynch-sentinel)))))\r
++(defun notmuch-enqueue-asynch (&rest args)\r
++  "Add a call to notmuch to the queue of notmuch calls.\r
++\r
++args is a list of arguments to notmuch.  ex: (\"tag\" \"+list\"\r
++\"to:mylist@example.com\")\r
++\r
++Calls to notmuch are queued and called asynchronously."\r
++  (setq notmuch-asynch-queue (append notmuch-asynch-queue (list args)))\r
++  (when (= (length notmuch-asynch-queue) 1)\r
++    (apply 'notmuch-call-notmuch-process-asynch (pop notmuch-asynch-queue))))\r
++  \r
++(defun notmuch-call-notmuch-process-asynch-sentinel (process event)\r
++  "Handle the exit of a notmuch asynch process.\r
++\r
++When notmuch is done processing, display the error or kill the\r
++error buffer.  If the db was busy on the last attempt to execute\r
++command, try it again."\r
++  (with-current-buffer (process-buffer process)\r
++    (goto-char (point-min))\r
++    (if (= (process-exit-status process) 0)\r
++      (kill-buffer (buffer-name (process-buffer process)))\r
++      (if (search-forward "Unable to acquire database write lock" nil t)\r
++          (apply 'notmuch-call-notmuch-process-asynch (cdr (process-command process)))\r
++          (error (format "%s: %s" (join-string-list (process-command process))\r
++                         (buffer-string))))))\r
++  (apply 'notmuch-call-notmuch-process-asynch (pop notmuch-asynch-queue)))\r
++\r
+ (defun notmuch-call-notmuch-process (&rest args)\r
+   "Synchronously invoke \"notmuch\" with the given list of arguments.\r
\r
+@@ -1420,7 +1467,7 @@ The tag is added to messages in the currently selected thread\r
+ which match the current search terms."\r
+   (interactive\r
+    (list (notmuch-select-tag-with-completion "Tag to add: ")))\r
+-  (notmuch-call-notmuch-process "tag" (concat "+" tag) (notmuch-search-find-thread-id))\r
++  (notmuch-enqueue-asynch "tag" (concat "+" tag) (notmuch-search-find-thread-id))\r
+   (notmuch-search-set-tags (delete-dups (sort (cons tag (notmuch-search-get-tags)) 'string<))))\r
\r
+ (defun notmuch-search-remove-tag (tag)\r
+@@ -1430,7 +1477,7 @@ The tag is removed from messages in the currently selected thread\r
+ which match the current search terms."\r
+   (interactive\r
+    (list (notmuch-select-tag-with-completion "Tag to remove: " (notmuch-search-find-thread-id))))\r
+-  (notmuch-call-notmuch-process "tag" (concat "-" tag) (notmuch-search-find-thread-id))\r
++  (notmuch-enqueue-asynch "tag" (concat "-" tag) (notmuch-search-find-thread-id))\r
+   (notmuch-search-set-tags (delete tag (notmuch-search-get-tags))))\r
\r
+ (defun notmuch-search-archive-thread ()\r
+@@ -1511,7 +1558,7 @@ characters as well as `_.+-'.\r
+       (unless (string-match-p "^[-+][-+_.[:word:]]+$" (car words))\r
+         (error "Action must be of the form `+thistag -that_tag'"))\r
+       (setq words (cdr words))))\r
+-    (apply 'notmuch-call-notmuch-process "tag"\r
++    (apply 'notmuch-enqueue-asynch "tag"\r
+          (append action-split (list notmuch-search-query-string) nil))))\r
\r
+ ;;;###autoload\r
+-- \r
+1.6.3.3\r
+\r