Using threads to show progress

It depends what you mean by "best".

The simplest solution, and hardest to get wrong, would be something like this:

  desc "Go through dictated exams and show IDs"
  task(:showSomeIDs => :environment) do
    interval = 0.1
    last_update = 0
    DictatedExam.all.each do |exam|
      if Time.now - last_update >= interval
        puts exam.id
        last_update = Time.now
      end
    end
  end

No threads involved at all. However, this has the problem that you could have
several items take much faster than that interval to process, and then one
takes a very long time -- in which case, the display would stop updating
(which is good), but it would currently show the wrong id, not the id which is
taking so long.

I don't know that this matters in this case, but if you did want a more
accurate update, you'd probably want some sort of thread. But I'd hide that
thread in a library, and I might not have it always poll.

···

On Thursday 17 December 2009 11:51:10 am Piyush Ranjan wrote:

So is using two threads is the best solution ?

Aldric Giacomoni wrote:

if __FILE__ == $0
Progress << "Feeding the cat"
33.times do |x|
   Progress << ["munch", x, 33]
   sleep(0.1)
end
Progress << "Put the cat out"
Progress << "Go to sleep"
20.times do |x|
   Progress << ["zzzzzzz", x, 20]
   sleep(0.2)
end
Progress << "Wakey wakey!"
end

From inside a loop, can I dynamically know over how many elements the
loop will iterate? I noticed the repetition of '33' and '20' ... :slight_smile:

It depends on what you're iterating over. If it's an Array, use
Array#size:

   myarray.each_with_index do |elem, i|
     Progress << ["Processing", i, myarray.size]
     ...
   end

Progress does here assume that you know the number of iterations in
advance (so it can show a progress bar). You could easily modify the
code so that

    Progress << ["munch", x]

it would just display the number x, rather than a bar.

  def bar(category, n, m=nil)
    if m
      @out << sprintf("%-20s[%-56s]", category, "*" * (56.0 * n / m))
    else
      @out << sprintf("%-20s %-56s", category, n.to_s)
    end
  end

···

--
Posted via http://www.ruby-forum.com/\.