Class: Teek::BackgroundThread::BackgroundWork

Inherits:
Object
  • Object
show all
Defined in:
lib/teek/background_thread.rb

Defined Under Namespace

Classes: TaskContext

Instance Method Summary collapse

Constructor Details

#initialize(app, data, worker: nil, &block) ⇒ BackgroundWork

Returns a new instance of BackgroundWork.



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/teek/background_thread.rb', line 33

def initialize(app, data, worker: nil, &block)
  # Thread mode supports both block and worker class for API consistency
  @app = app
  @data = data
  @work_block = block || (worker && proc { |t, d| worker.new.call(t, d) })
  @callbacks = { progress: nil, done: nil, message: nil }
  @started = false
  @done = false
  @paused = false

  # Communication channels
  @output_queue = Thread::Queue.new    # Worker -> Main
  @message_queue = Thread::Queue.new   # Main -> Worker
  @worker_thread = nil
end

Instance Method Details

#closeObject



93
94
95
96
97
# File 'lib/teek/background_thread.rb', line 93

def close
  @done = true
  @worker_thread&.kill
  self
end

#done?Boolean

Returns:

  • (Boolean)


99
100
101
# File 'lib/teek/background_thread.rb', line 99

def done?
  @done
end

#on_done(&block) ⇒ Object



55
56
57
58
59
# File 'lib/teek/background_thread.rb', line 55

def on_done(&block)
  @callbacks[:done] = block
  maybe_start
  self
end

#on_message(&block) ⇒ Object

Called when worker sends a non-result message back



62
63
64
65
# File 'lib/teek/background_thread.rb', line 62

def on_message(&block)
  @callbacks[:message] = block
  self
end

#on_progress(&block) ⇒ Object



49
50
51
52
53
# File 'lib/teek/background_thread.rb', line 49

def on_progress(&block)
  @callbacks[:progress] = block
  maybe_start
  self
end

#pauseObject

Convenience methods



74
75
76
77
78
# File 'lib/teek/background_thread.rb', line 74

def pause
  @paused = true
  send_message(:pause)
  self
end

#paused?Boolean

Returns:

  • (Boolean)


103
104
105
# File 'lib/teek/background_thread.rb', line 103

def paused?
  @paused
end

#resumeObject



80
81
82
83
84
85
86
# File 'lib/teek/background_thread.rb', line 80

def resume
  @paused = false
  send_message(:resume)
  # Restart polling (was stopped when paused)
  @app.after(0, &@poll_proc) if @poll_proc && !@done
  self
end

#send_message(msg) ⇒ Object

Send a message to the worker (pause, resume, stop, or custom)



68
69
70
71
# File 'lib/teek/background_thread.rb', line 68

def send_message(msg)
  @message_queue << msg
  self
end

#startObject



107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/teek/background_thread.rb', line 107

def start
  return self if @started
  @started = true

  @worker_thread = Thread.new do
    Thread.current[:tk_in_background_work] = true
    task = TaskContext.new(@output_queue, @message_queue)
    begin
      @work_block.call(task, @data)
      @output_queue << [:done]
    rescue StopIteration
      @output_queue << [:done]
    rescue => e
      @output_queue << [:error, "#{e.class}: #{e.message}\n#{e.backtrace.first(3).join("\n")}"]
      @output_queue << [:done]
    end
  end

  start_polling
  self
end

#stopObject



88
89
90
91
# File 'lib/teek/background_thread.rb', line 88

def stop
  send_message(:stop)
  self
end