lib/sup/poll.rb in sup-0.13.1 vs lib/sup/poll.rb in sup-0.13.2
- old
+ new
@@ -20,11 +20,11 @@
Executes immediately after a poll for new messages completes.
Variables:
num: the total number of new messages added in this poll
num_inbox: the number of new messages added in this poll which
appear in the inbox (i.e. were not auto-archived).
- num_total: the total number of messages
+ num_total: the total number of messages
num_inbox_total: the total number of new messages in the inbox.
num_inbox_total_unread: the total number of unread messages in the inbox
from_and_subj: an array of (from email address, subject) pairs
from_and_subj_inbox: an array of (from email address, subject) pairs for
only those messages appearing in the inbox
@@ -33,11 +33,11 @@
def initialize
@delay = $config[:poll_interval] || 300
@mutex = Mutex.new
@thread = nil
@last_poll = nil
- @polling = false
+ @polling = Mutex.new
@poll_sources = nil
@mode = nil
@should_clear_running_totals = false
clear_running_totals # defines @running_totals
UpdateManager.register self
@@ -55,19 +55,19 @@
num, numi, from_and_subj, from_and_subj_inbox, loaded_labels = @mode.poll
clear_running_totals if @should_clear_running_totals
@running_totals[:num] += num
@running_totals[:numi] += numi
@running_totals[:loaded_labels] += loaded_labels || []
-
-
+
+
if HookManager.enabled? "after-poll"
hook_args = { :num => num, :num_inbox => numi,
:num_total => @running_totals[:num], :num_inbox_total => @running_totals[:numi],
- :from_and_subj => from_and_subj, :from_and_subj_inbox => from_and_subj_inbox,
+ :from_and_subj => from_and_subj, :from_and_subj_inbox => from_and_subj_inbox,
:num_inbox_total_unread => lambda { Index.num_results_for :labels => [:inbox, :unread] } }
- HookManager.run("after-poll", hook_args)
+ HookManager.run("after-poll", hook_args)
else
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."
@@ -75,25 +75,31 @@
end
end
def poll
- return if @polling
- @polling = true
- @poll_sources = SourceManager.usual_sources
- num, numi = poll_with_sources
- @polling = false
- [num, numi]
+ if @polling.try_lock
+ @poll_sources = SourceManager.usual_sources
+ num, numi = poll_with_sources
+ @polling.unlock
+ [num, numi]
+ else
+ debug "poll already in progress."
+ return
+ end
end
def poll_unusual
- return if @polling
- @polling = true
- @poll_sources = SourceManager.unusual_sources
- num, numi = poll_with_sources
- @polling = false
- [num, numi]
+ if @polling.try_lock
+ @poll_sources = SourceManager.unusual_sources
+ num, numi = poll_with_sources
+ @polling.unlock
+ [num, numi]
+ else
+ debug "poll_unusual already in progress."
+ return
+ end
end
def start
@thread = Redwood::reporting_thread("periodic poll") do
while true
@@ -155,54 +161,62 @@
end
loaded_labels = loaded_labels - LabelManager::HIDDEN_RESERVED_LABELS - [:inbox, :killed]
yield "Done polling; loaded #{total_num} new messages total"
@last_poll = Time.now
- @polling = false
end
[total_num, total_numi, from_and_subj, from_and_subj_inbox, loaded_labels]
end
## like Source#poll, but yields successive Message objects, which have their
## labels and locations set correctly. The Messages are saved to or removed
## from the index after being yielded.
def poll_from source, opts={}
- begin
- source.poll do |sym, args|
- case sym
- when :add
- m = Message.build_from_source source, args[:info]
- old_m = Index.build_message m.id
- m.labels += args[:labels]
- m.labels.delete :inbox if source.archived?
- m.labels.delete :unread if source.read?
- m.labels.delete :unread if m.source_marked_read? # preserve read status if possible
- m.labels.each { |l| LabelManager << l }
- m.labels = old_m.labels + (m.labels - [:unread, :inbox]) if old_m
- m.locations = old_m.locations + m.locations if old_m
- HookManager.run "before-add-message", :message => m
- yield :add, m, old_m, args[:progress] if block_given?
- Index.sync_message m, true
+ debug "trying to acquiring poll lock for: #{source}.."
+ if source.poll_lock.try_lock
+ debug "lock acquired for: #{source}."
+ begin
+ source.poll do |sym, args|
+ case sym
+ when :add
+ m = Message.build_from_source source, args[:info]
+ old_m = Index.build_message m.id
+ m.labels += args[:labels]
+ m.labels.delete :inbox if source.archived?
+ m.labels.delete :unread if source.read?
+ m.labels.delete :unread if m.source_marked_read? # preserve read status if possible
+ m.labels.each { |l| LabelManager << l }
+ m.labels = old_m.labels + (m.labels - [:unread, :inbox]) if old_m
+ m.locations = old_m.locations + m.locations if old_m
+ HookManager.run "before-add-message", :message => m
+ yield :add, m, old_m, args[:progress] if block_given?
+ Index.sync_message m, true
- ## We need to add or unhide the message when it either did not exist
- ## before at all or when it was updated. We do *not* add/unhide when
- ## the same message was found at a different location
- if !old_m or not old_m.locations.member? m.location
- UpdateManager.relay self, :added, m
+ ## We need to add or unhide the message when it either did not exist
+ ## before at all or when it was updated. We do *not* add/unhide when
+ ## the same message was found at a different location
+ if !old_m or not old_m.locations.member? m.location
+ UpdateManager.relay self, :added, m
+ end
+ when :delete
+ Index.each_message :location => [source.id, args[:info]] do |m|
+ m.locations.delete Location.new(source, args[:info])
+ yield :delete, m, [source,args[:info]], args[:progress] if block_given?
+ Index.sync_message m, false
+ #UpdateManager.relay self, :deleted, m
+ end
end
- when :delete
- Index.each_message :location => [source.id, args[:info]] do |m|
- m.locations.delete Location.new(source, args[:info])
- yield :delete, m, [source,args[:info]], args[:progress] if block_given?
- Index.sync_message m, false
- #UpdateManager.relay self, :deleted, m
- end
end
- end
- source.go_idle
- rescue SourceError => e
- warn "problem getting messages from #{source}: #{e.message}"
+ rescue SourceError => e
+ warn "problem getting messages from #{source}: #{e.message}"
+
+ ensure
+ source.go_idle
+ source.poll_lock.unlock
+ end
+ else
+ debug "source #{source} is already being polled."
end
end
def handle_idle_update sender, idle_since; @should_clear_running_totals = false; end
def handle_unidle_update sender, idle_since; @should_clear_running_totals = true; clear_running_totals; end