Class: ProgressTicker

Inherits:
Object
  • Object
show all
Defined in:
backend/app/lib/progress_ticker.rb

Instance Method Summary collapse

Constructor Details

#initialize(opts = {}, &block) ⇒ ProgressTicker

Returns a new instance of ProgressTicker.



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# File 'backend/app/lib/progress_ticker.rb', line 6

def initialize(opts = {}, &block)
  @frequency = opts[:frequency_seconds] || 5
  @ticks = 0

  @last_tick = Atomic.new(nil)
  @status_updates = Atomic.new([])
  @results = Atomic.new({})
  @finished = Atomic.new(false)

  context = RequestContext.dump
  @block = proc {|ticker|
    RequestContext.open(context) do
      block.call(ticker)
    end
  }
end

Instance Method Details

#each(&client) ⇒ Object



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'backend/app/lib/progress_ticker.rb', line 86

def each(&client)
  @tick_to_client_thread = Thread.new do
    client.call("[\n")
    while !@finished.value
      tick_for_client = @last_tick.value

      flush_statuses(client)

      if tick_for_client
        client.call(ASUtils.to_json(tick_for_client) + ",\n")
      end

      sleep @frequency
    end

    flush_statuses(client)
    flush_results(client)
  end

  # Start the computation
  begin
    @block.call(self)
  ensure
    self.finish!
    client.call("\n]")
    @tick_to_client_thread.join
  end
end

#finish!Object



57
58
59
60
# File 'backend/app/lib/progress_ticker.rb', line 57

def finish!
  @finished.update {|val| true}
  @tick_to_client_thread.join if @tick_to_client_thread
end

#finished?Boolean

Returns:

  • (Boolean)


63
64
65
# File 'backend/app/lib/progress_ticker.rb', line 63

def finished?
  @finished.value
end

#flush_results(client) ⇒ Object



77
78
79
80
81
82
83
# File 'backend/app/lib/progress_ticker.rb', line 77

def flush_results(client)
  results = @results.swap({})

  unless results.empty?
    client.call(ASUtils.to_json(results) + "\n")
  end
end

#flush_statuses(client) ⇒ Object



68
69
70
71
72
73
74
# File 'backend/app/lib/progress_ticker.rb', line 68

def flush_statuses(client)
  updates = @status_updates.swap([])

  unless updates.empty?
    client.call(ASUtils.to_json(:status => updates) + ",\n")
  end
end

#log(s) ⇒ Object



37
38
39
# File 'backend/app/lib/progress_ticker.rb', line 37

def log(s)
  Log.debug(s)
end

#results=(result_hash) ⇒ Object



46
47
48
49
# File 'backend/app/lib/progress_ticker.rb', line 46

def results=(result_hash)
  raise "bad argument: #{result_hash}" unless result_hash.is_a?(Hash)
  @results.update {|val| result_hash }
end

#results?Boolean

Returns:

  • (Boolean)


52
53
54
# File 'backend/app/lib/progress_ticker.rb', line 52

def results?
  return @results.value.empty? ? false : true
end

#status_update(type, status) ⇒ Object



41
42
43
# File 'backend/app/lib/progress_ticker.rb', line 41

def status_update(type, status)
  @status_updates.update {|val| val + [status.merge(:type => type)] }
end

#tick(ticks = 1) ⇒ Object



30
31
32
33
34
# File 'backend/app/lib/progress_ticker.rb', line 30

def tick(ticks = 1)
  @ticks += ticks
  @last_tick.update {|val| {:ticks => @ticks, :total => @estimated_total_ticks}}
  @ticks
end

#tick_estimate=(val) ⇒ Object



24
25
26
27
# File 'backend/app/lib/progress_ticker.rb', line 24

def tick_estimate=(val)
  @estimated_total_ticks = val
  @ticks = 0
end