Subject: Re: [sup-devel] [PATCHv3] [issue14] poll updates accumulate while idle

From: William Morgan <[email-masked]>
Date: Thu, 14 Jan 2010 09:15:57 -0500

Reformatted excerpts from Eric Sherman's message of 2010-01-12:
> If you were to leave sup running for a long time, this patch would
> enable you to get a glance summary of new mail activity since sup was
> last touched, by letting the poll update message accumulate its totals
> while idle.

I like this. My only request is that idle_threshold be a hard-coded
constant in buffer.rb, since I'm trying to avoid config-bloat.
-- 
William <[email-masked]>
_______________________________________________
Sup-devel mailing list
[email-masked]
http://rubyforge.org/mailman/listinfo/sup-devel

---

From: Eric Sherman <[email-masked]>
Date: Tue, 12 Jan 2010 09:51:02 -0500

Excerpts from Eric Sherman's message of Mon Jan 04 07:14:33 -0500 2010:
> last touched, by letting the poll update message accumulate its tally
> while idle.
> 
> On keystrokes, BufferManager sends an :unidle update if the last
> keystroke occurred more than :idle_threshold seconds ago.  PollManager
> listens for :unidle updates to clear PollTally.  It is also cleared on
> each poll unless idle.
> 
> * :idle_threshold defaults to 60 seconds if not defined in config.yaml
> * presently no :idle update is sent when becoming idle
> * but we can check for idleness with BufferManager.idle?
> * after-poll behavior is unaffected
> ---
>  lib/sup.rb        |    3 ++-
>  lib/sup/buffer.rb |    5 +++++
>  lib/sup/poll.rb   |   24 ++++++++++++++++++++++--
>  3 files changed, 29 insertions(+), 3 deletions(-)
> 
> diff --git a/lib/sup.rb b/lib/sup.rb
> index 840b3fc..a6de0ab 100644
> --- a/lib/sup.rb
> +++ b/lib/sup.rb
> @@ -229,7 +229,8 @@ else
>      :confirm_top_posting => true,
>      :discard_snippets_from_encrypted_messages => false,
>      :default_attachment_save_dir => "",
> -    :sent_source => "sup://sent"
> +    :sent_source => "sup://sent",
> +    :idle_threshold => 60
>    }
>    begin
>      FileUtils.mkdir_p Redwood::BASE_DIR
> diff --git a/lib/sup/buffer.rb b/lib/sup/buffer.rb
> index c826ab9..8bf666b 100644
> --- a/lib/sup/buffer.rb
> +++ b/lib/sup/buffer.rb
> @@ -212,6 +212,7 @@ EOS
>      @in_x = ENV["TERM"] =~ /(xterm|rxvt|screen)/
>      @sigwinch_happened = false
>      @sigwinch_mutex = Mutex.new
> +    @idle_since = Time.now
>    end
>  
>    def sigwinch_happened!; @sigwinch_mutex.synchronize { @sigwinch_happened = true } end
> @@ -269,6 +270,8 @@ EOS
>          @focus_buf.mode.cancel_search!
>          @focus_buf.mark_dirty
>        end
> +      UpdateManager.relay self, :unidle, Time.at(@idle_since) if idle?
> +      @idle_since = Time.now
>        @focus_buf.mode.handle_input c
>      end
>    end
> @@ -761,6 +764,8 @@ EOS
>      @shelled = false
>    end
>  
> +  def idle?; Time.now.to_i - @idle_since.to_i >= ($config[:idle_threshold] || 60); end
> +
>  private
>  
>    def default_status_bar buf
> diff --git a/lib/sup/poll.rb b/lib/sup/poll.rb
> index 4f30505..48228ca 100644
> --- a/lib/sup/poll.rb
> +++ b/lib/sup/poll.rb
> @@ -37,6 +37,8 @@ EOS
>      @polling = false
>      @poll_sources = nil
>      @mode = nil
> +    PollTally.init
> +    UpdateManager.register self
>    end
>  
>    def poll_with_sources
> @@ -45,8 +47,10 @@ EOS
>  
>      BufferManager.flash "Polling for new messages..."
>      num, numi, from_and_subj, from_and_subj_inbox, loaded_labels = @mode.poll
> -    if num > 0
> -      BufferManager.flash "Loaded #{num.pluralize 'new message'}, #{numi} to inbox. Labels: #{loaded_labels.map{|l| l.to_s}.join(', ')}"
> +    PollTally.clear unless BufferManager.idle?
> +    PollTally.add :num => num, :num_inbox => numi, :loaded_labels => loaded_labels
> +    if PollTally.num > 0
> +      BufferManager.flash "Loaded #{PollTally.num.pluralize 'new message'}, #{PollTally.num_inbox} to inbox. Labels: #{PollTally.loaded_labels.map{|l| l.to_s}.join(', ')}"
>      else
>        BufferManager.flash "No new messages." 
>      end
> @@ -183,6 +187,22 @@ EOS
>      Index.add_message m
>      UpdateManager.relay self, :added, m
>    end
> +
> +  def handle_unidle_update sender, idle_since; PollTally.clear; end
> +end
> +
> +class PollTally
> +  include Singleton
> +  attr_reader :num, :num_inbox, :loaded_labels
> +
> +  def initialize; @num = 0; @num_inbox = 0; @loaded_labels = Set.new; end
> +  def clear; @num = 0; @num_inbox = 0; @loaded_labels.clear; end
> +
> +  def add opts={}
> +    @num += opts[:num]||0
> +    @num_inbox += opts[:num_inbox]||0
> +    @loaded_labels = Set.new(opts[:loaded_labels] || []) + @loaded_labels
> +  end
>  end
>  
>  end

What manner of reimplementation would increase this patch's likelihood for 
inclusion?  Or is my whole approach JustWrong for sup?

* @idle_since should probably be renamed to @no_keystrokes_since
* PollTally should probably be replaced by a hash

Aside from its ugliness I'm happy with the result: running poll totals 
while idle.

An alternative implementation with the above changes follows in reply, but 
it's probably still too ugly for inclusion.
_______________________________________________
Sup-devel mailing list
[email-masked]
http://rubyforge.org/mailman/listinfo/sup-devel

---

From: Eric Sherman <[email-masked]>
Date: Thu, 14 Jan 2010 09:21:45 -0500

> constant in buffer.rb, since I'm trying to avoid config-bloat.

Ok.  I've since separated the idleness out into its own patch submitted 
yesterday.  Is 60 seconds a sensible threshold?
_______________________________________________
Sup-devel mailing list
[email-masked]
http://rubyforge.org/mailman/listinfo/sup-devel

---

From: Eric Sherman <[email-masked]>
Date: Tue, 12 Jan 2010 09:56:21 -0500

On keystrokes, BufferManager sends an :unidle update if the last
keystroke occurred more than :idle_threshold seconds ago.  PollManager
listens for :unidle updates to clear @running_totals, which is also
cleared on each poll unless idle.

* :idle_threshold defaults to 60 seconds if not defined in config.yaml
* presently no :idle update is sent when becoming idle
* but we can check for idleness with BufferManager.idle?
* after-poll behavior is unaffected
---
 lib/sup.rb        |    3 ++-
 lib/sup/buffer.rb |    5 +++++
 lib/sup/poll.rb   |   13 +++++++++++--
 3 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/lib/sup.rb b/lib/sup.rb
index b83bbe7..e228772 100644
--- a/lib/sup.rb
+++ b/lib/sup.rb
@@ -230,7 +230,8 @@ else
     :discard_snippets_from_encrypted_messages => false,
     :default_attachment_save_dir => "",
     :sent_source => "sup://sent",
-    :poll_interval => 300
+    :poll_interval => 300,
+    :idle_threshold => 60
   }
   begin
     FileUtils.mkdir_p Redwood::BASE_DIR
diff --git a/lib/sup/buffer.rb b/lib/sup/buffer.rb
index c826ab9..2f5eaa8 100644
--- a/lib/sup/buffer.rb
+++ b/lib/sup/buffer.rb
@@ -212,6 +212,7 @@ EOS
     @in_x = ENV["TERM"] =~ /(xterm|rxvt|screen)/
     @sigwinch_happened = false
     @sigwinch_mutex = Mutex.new
+    @no_keystrokes_since = Time.now
   end
 
   def sigwinch_happened!; @sigwinch_mutex.synchronize { @sigwinch_happened = true } end
@@ -269,6 +270,8 @@ EOS
         @focus_buf.mode.cancel_search!
         @focus_buf.mark_dirty
       end
+      UpdateManager.relay self, :unidle, Time.at(@no_keystrokes_since) if idle?
+      @no_keystrokes_since = Time.now
       @focus_buf.mode.handle_input c
     end
   end
@@ -761,6 +764,8 @@ EOS
     @shelled = false
   end
 
+  def idle?; Time.now.to_i - @no_keystrokes_since.to_i >= ($config[:idle_threshold] || 60); end
+
 private
 
   def default_status_bar buf
diff --git a/lib/sup/poll.rb b/lib/sup/poll.rb
index f3e1224..ad51647 100644
--- a/lib/sup/poll.rb
+++ b/lib/sup/poll.rb
@@ -37,6 +37,8 @@ EOS
     @polling = false
     @poll_sources = nil
     @mode = nil
+    clear_running_totals
+    UpdateManager.register self
   end
 
   def poll_with_sources
@@ -45,8 +47,12 @@ EOS
 
     BufferManager.flash "Polling for new messages..."
     num, numi, from_and_subj, from_and_subj_inbox, loaded_labels = @mode.poll
-    if num > 0
-      BufferManager.flash "Loaded #{num.pluralize 'new message'}, #{numi} to inbox. Labels: #{loaded_labels.map{|l| l.to_s}.join(', ')}"
+    clear_running_totals unless BufferManager.idle?
+    @running_totals[:num] += num
+    @running_totals[:numi] += numi
+    @running_totals[:loaded_labels] += loaded_labels || []
+    if @running_totals[:num] > 0
+      BufferManager.flash "Loaded #{@running_totals[:num].pluralize 'new message'}, #{@running_totals[:numi]} to inbox. Labels: #{@running_totals[:loaded_labels].map{|l| l.to_s}.join(', ')}"
     else
       BufferManager.flash "No new messages." 
     end
@@ -183,6 +189,9 @@ EOS
     Index.add_message m
     UpdateManager.relay self, :added, m
   end
+
+  def handle_unidle_update sender, idle_since; clear_running_totals; end
+  def clear_running_totals; @running_totals = {:num => 0, :numi => 0, :loaded_labels => Set.new}; end
 end
 
 end
-- 
1.6.6

---

From: Eric Sherman <[email-masked]>
Date: Mon, 04 Jan 2010 07:14:33 -0500

def poll_with_sources
@@ -45,8 +47,10 @@ EOS

 end
-- 
1.6.5.7