From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Dima Kogan Newsgroups: gmane.emacs.devel Subject: Re: Clarification about auto-revert-mode and inotify Date: Fri, 24 Oct 2014 00:02:30 -0700 Message-ID: <87tx2sg8tx.fsf@secretsauce.net> References: <87vbnd9aab.fsf@secretsauce.net> <83a94pbgum.fsf@gnu.org> <83ppdl9uwn.fsf@gnu.org> <83a94p9naw.fsf@gnu.org> <837fzsakhw.fsf@gnu.org> <834muw9n5j.fsf@gnu.org> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Trace: ger.gmane.org 1414205549 7960 80.91.229.3 (25 Oct 2014 02:52:29 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Sat, 25 Oct 2014 02:52:29 +0000 (UTC) Cc: Eli Zaretskii , emacs-devel@gnu.org To: Stefan Monnier Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Sat Oct 25 04:52:21 2014 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1XhrSm-0002yp-On for ged-emacs-devel@m.gmane.org; Sat, 25 Oct 2014 04:52:21 +0200 Original-Received: from localhost ([::1]:51699 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XhrSm-0002oF-DP for ged-emacs-devel@m.gmane.org; Fri, 24 Oct 2014 22:52:20 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:56390) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XhrSe-0002oA-6q for emacs-devel@gnu.org; Fri, 24 Oct 2014 22:52:18 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XhrSP-0000Im-Qm for emacs-devel@gnu.org; Fri, 24 Oct 2014 22:52:12 -0400 Original-Received: from out1-smtp.messagingengine.com ([66.111.4.25]:51463) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XhrSP-0000IV-H3 for emacs-devel@gnu.org; Fri, 24 Oct 2014 22:51:57 -0400 Original-Received: from compute6.internal (compute6.nyi.internal [10.202.2.46]) by mailout.nyi.internal (Postfix) with ESMTP id 0A6792071A for ; Fri, 24 Oct 2014 22:51:56 -0400 (EDT) Original-Received: from frontend1 ([10.202.2.160]) by compute6.internal (MEProxy); Fri, 24 Oct 2014 22:51:56 -0400 DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=secretsauce.net; h=x-sasl-enc:references:from:to:cc:subject:date:in-reply-to :message-id:mime-version:content-type; s=mesmtp; bh=/dSpbvFuml5Z Oan+9yXoH8c+2zQ=; b=PosAghZaOsFcA64qtyNY+nl1ZZ3DV2X9RAD7LYmuIcK8 oIlcD/fK650dW1u+DoE71X/iwPrh0qvE3+/qz7KL53pM2pZr4XPkhe46hortBxEO nyvic4t3IuxSd5oPRKNNlu9A8HXcdjTeD3rVD2EEnl9MdaTwNT0rfMgN3Jsv8k4= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d= messagingengine.com; h=x-sasl-enc:references:from:to:cc:subject :date:in-reply-to:message-id:mime-version:content-type; s= smtpout; bh=/dSpbvFuml5ZOan+9yXoH8c+2zQ=; b=orAAu7d+zPKv5DGpg/cB 3kT0h/vscqXmZWfrQiv9Gxt2ol4KR9cHTwV7sDAGwG0kchCpl2vQGDqFIcoW7tdS wBw+36f2FY9PcZ9Fu+vXwsQqFh4UxnWYxsgfVX9sT/dis4WCj6IWrnLLa7OEWEOD hGPUAslLkBgcEBGsbVEa3VY= X-Sasl-enc: R6JqZEMmYOaJG4gGeaDAr7jR5xXClVMEPFkFXkgFUs2x 1414205515 Original-Received: from shorty.local (unknown [23.243.192.221]) by mail.messagingengine.com (Postfix) with ESMTPA id AFF96C0000A; Fri, 24 Oct 2014 22:51:55 -0400 (EDT) Original-Received: from ip6-localhost ([::1] helo=shorty.local) by shorty.local with esmtp (Exim 4.82_1-5b7a7c0-XX) (envelope-from ) id 1XhrSM-0008QY-6S; Fri, 24 Oct 2014 19:51:54 -0700 In-reply-to: X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 66.111.4.25 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:175805 Archived-At: --=-=-= Content-Type: text/plain Hi. This thread really lost its focus, so let me try to bring it back. My goals with this thread and patch are what Stefan listed, with some extra points: - *very* low resource use when the system is idle. - prompt updates after a "one time" change FOR LOCAL FILES - keep Emacs responsive even in case of constant updates or many auto-revertable buffers I'm making an assumption that it would be good to have this in stock emacs, and not in some odd configuration many of us would never use, like checking an event-driven flag 100 times every second. I do agree that making things universally as responsive as a 'tail -f' would take more work, mainly because each revert can be a heavy operation. Right now I just want to take care of the low-hanging fruit, so the above list is good. Notifications (inotify, etc) are a good way to make this work, so I only care about the case where notifications are available: local files only. The patch I attached mostly achieves the goals outlined above, with the exception of the cost incurred by the per-buffer timers. I'm attaching another verion of this patch that does not use any timers at all. It keeps a counter, incrementing during each 'auto-revert-buffers' call. When an file notification fires, the buffer is updated immediately, and the current value of the counter is saved. Net time an notification fires, the immediate update happens ONLY if the counter is different from the value stored. So there's one global variable (the counter), and a per-buffer variable for each buffer of interest (the stored counter value). If there are specific objections to this patch, performance or otherwise, please tell me. Also, it appears that both gfile and inotify notification systems are misbehaving in emacs right now, so serious tests of this patch probably wouldn't yield good results yet. Conceptual criticism probably would have to do for now (this wasn't a problem the last time :) ). I'm looking at the notification issues now; more on that in a bit. dima --=-=-= Content-Type: text/x-diff Content-Disposition: inline; filename=0001-auto-revert-mode-can-now-revert-immediately-in-respo.patch >From 567d8469dfb143786890c65de58bf2ce887e9ebd Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Fri, 24 Oct 2014 19:44:43 -0700 Subject: [PATCH] auto-revert-mode can now revert immediately in response to a change event If we have file notifications, we want to update the auto-revert buffers immediately when a notification occurs. Since file updates can happen very often, we want to skip some revert operations so that we don't spend all our time reverting the buffer. We do this by reverting immediately in response to the first in a flurry of notifications. We suppress subsequent notifications until the next time `auto-revert-buffers' is called (this happens on a timer with a period set by `auto-revert-interval'). --- lisp/autorevert.el | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/lisp/autorevert.el b/lisp/autorevert.el index f1074e2..7de6ec1 100644 --- a/lisp/autorevert.el +++ b/lisp/autorevert.el @@ -531,6 +531,34 @@ will use an up-to-date value of `auto-revert-interval'" ;; Fallback to file checks. (set (make-local-variable 'auto-revert-use-notify) nil)))) + + +;; If we have file notifications, we want to update the auto-revert buffers +;; immediately when a notification occurs. Since file updates can happen very +;; often, we want to skip some revert operations so that we don't spend all our +;; time reverting the buffer. +;; +;; We do this by reverting immediately in response to the first in a flurry of +;; notifications. We suppress subsequent notifications until the next time +;; `auto-revert-buffers' is called (this happens on a timer with a period set by +;; `auto-revert-interval'). +(defvar auto-revert-buffers-counter 1 + "Incremented each time `auto-revert-buffers' is called") +(defvar auto-revert-buffers-counter-lockedout 0 + "Buffer-local value to indicate whether we should immediately +update the buffer on a notification event or not. If + + (= auto-revert-buffers-counter-lockedout + auto-revert-buffers-counter) + +then the updates are locked out, and we wait until the next call +of `auto-revert-buffers' to revert the buffer. If no lockout is +present, then we revert immediately and set the lockout, so that +no more reverts are possible until the next call of +`auto-revert-buffers'") +(make-variable-buffer-local 'auto-revert-buffers-counter-lockedout) + + (defun auto-revert-notify-handler (event) "Handle an EVENT returned from file notification." (with-demoted-errors @@ -566,6 +594,14 @@ will use an up-to-date value of `auto-revert-interval'" (file-name-nondirectory buffer-file-name))))) ;; Mark buffer modified. (setq auto-revert-notify-modified-p t) + + ;; Revert the buffer now if we're not locked out + (when (/= auto-revert-buffers-counter-lockedout + auto-revert-buffers-counter) + (auto-revert-handler) + (setq auto-revert-buffers-counter-lockedout + auto-revert-buffers-counter)) + ;; No need to check other buffers. (cl-return))))))))) @@ -686,6 +722,10 @@ are checked first the next time this function is called. This function is also responsible for removing buffers no longer in Auto-Revert mode from `auto-revert-buffer-list', and for canceling the timer when no buffers need to be checked." + + (setq auto-revert-buffers-counter + (1+ auto-revert-buffers-counter)) + (save-match-data (let ((bufs (if global-auto-revert-mode (buffer-list) -- 2.0.0 --=-=-=--