class Dev::UI::Spinner::SpinGroup

Public Class Methods

new(auto_debrief: true) click to toggle source

Initializes a new spin group This lets you add Task objects to the group to multi-thread work

Options

  • :auto_debrief - Automatically debrief exceptions? Default to true

Example Usage

spin_group = Dev::UI::SpinGroup.new
spin_group.add('Title')   { |spinner| sleep 3.0 }
spin_group.add('Title 2') { |spinner| sleep 3.0; spinner.update_title('New Title'); sleep 3.0 }
spin_group.wait

Output:

# File lib/dev/ui/spinner/spin_group.rb, line 23
def initialize(auto_debrief: true)
  @m = Mutex.new
  @consumed_lines = 0
  @tasks = []
  @auto_debrief = auto_debrief
end

Public Instance Methods

add(title, &block) click to toggle source

Add a new task

Attributes

  • title - Title of the task

  • block - Block for the task, will be provided with an instance of the spinner

Example Usage:

spin_group = Dev::UI::SpinGroup.new
spin_group.add('Title') { |spinner| sleep 1.0 }
spin_group.wait
# File lib/dev/ui/spinner/spin_group.rb, line 142
def add(title, &block)
  @m.synchronize do
    @tasks << Task.new(title, &block)
  end
end
debrief() click to toggle source

Debriefs failed tasks is auto_debrief is true

# File lib/dev/ui/spinner/spin_group.rb, line 193
def debrief
  @m.synchronize do
    @tasks.each do |task|
      next if task.success

      e = task.exception
      out = task.stdout
      err = task.stderr

      Dev::UI::Frame.open('Task Failed: ' + task.title, color: :red) do
        if e
          puts "#{e.class}: #{e.message}"
          puts "\tfrom #{e.backtrace.join("\n\tfrom ")}"
        end

        Dev::UI::Frame.divider('STDOUT')
        out = "(empty)" if out.nil? || out.strip.empty?
        puts out

        Dev::UI::Frame.divider('STDERR')
        err = "(empty)" if err.nil? || err.strip.empty?
        puts err
      end
    end
    @tasks.all?(&:success)
  end
end
wait() click to toggle source

Tells the group you're done adding tasks and to wait for all of them to finish

Example Usage:

spin_group = Dev::UI::SpinGroup.new
spin_group.add('Title') { |spinner| sleep 1.0 }
spin_group.wait
# File lib/dev/ui/spinner/spin_group.rb, line 155
def wait
  idx = 0

  loop do
    all_done = true

    @m.synchronize do
      Dev::UI.raw do
        @tasks.each.with_index do |task, int_index|
          nat_index = int_index + 1
          task_done = task.check
          all_done = false unless task_done

          if nat_index > @consumed_lines
            print(task.render(idx, true) + "\n")
            @consumed_lines += 1
          else
            offset = @consumed_lines - int_index
            move_to   = Dev::UI::ANSI.cursor_up(offset) + "\r"
            move_from = "\r" + Dev::UI::ANSI.cursor_down(offset)

            print(move_to + task.render(idx, idx.zero?) + move_from)
          end
        end
      end
    end

    break if all_done

    idx = (idx + 1) % GLYPHS.size
    sleep(PERIOD)
  end

  debrief if @auto_debrief
end