Class: Krill::ThreadedManager

Inherits:
Object
  • Object
show all
Defined in:
lib/krill/threaded_manager.rb

Overview

Manages threaded execution of a job in technician interface. Provides methods called by Client via Server.

See DebugManager for manager used in test and debug modes.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(job) ⇒ ThreadedManager

Initializes a Krill::ThreadedManager object with the given job.

Parameters:

  • job (Job)

    the job

Raises:

  • (StandardError)

    if the job has no operations

  • (KrillSyntaxError)

    if the job's protocol has a syntax error



22
23
24
25
26
27
28
29
30
# File 'lib/krill/threaded_manager.rb', line 22

def initialize(job)
  raise "Error: job #{job.id} has no operations" if job.operations.empty?

  @mutex = Mutex.new
  @thread_status = ThreadStatus.new
  @thread_status.running = false

  @sandbox = ProtocolSandbox.new(job: job, mutex: @mutex, thread_status: @thread_status)
end

Instance Attribute Details

#sandboxObject (readonly)

accessible for testing



15
16
17
# File 'lib/krill/threaded_manager.rb', line 15

def sandbox
  @sandbox
end

#threadObject (readonly)

accessible for testing



15
16
17
# File 'lib/krill/threaded_manager.rb', line 15

def thread
  @thread
end

Instance Method Details

#check_againObject

Checks status of the job.

Method called by client via server.



89
90
91
92
93
94
95
# File 'lib/krill/threaded_manager.rb', line 89

def check_again
  if @thread.alive?
    wait 20
  else
    'done'
  end
end

#continueObject

Continues the job.

Method called by client via server.



100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/krill/threaded_manager.rb', line 100

def continue
  if @thread.alive?
    @mutex.synchronize do
      unless @thread_status.running
        @thread_status.running = true
        @thread.wakeup
      end
    end
    wait 20
  else
    'done'
  end
end

#notify(job) ⇒ Object

Associate a crash message to each operation of the given job.

Parameters:

  • job (Job)

    the job



132
133
134
135
136
137
138
139
140
# File 'lib/krill/threaded_manager.rb', line 132

def notify(job)
  job.operations.each do |operation|
    puts("notifying #{operation.id}")
    operation.associate(
      :job_crash,
      "Operation canceled when job #{job.id} crashed"
    )
  end
end

#startObject

Starts the thread and waits for 20 seconds if needed.

Method called by client via server.



57
58
59
60
61
# File 'lib/krill/threaded_manager.rb', line 57

def start
  start_thread
  wait(20) # This so that you wait until either the step is done or 20 seconds is up.
  # It doesn't have to wait the whole 20 seconds if the step finishes quickly.
end

#start_threadObject

Starts the thread for running this job.



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/krill/threaded_manager.rb', line 37

def start_thread
  @thread_status.running = true
  @thread = Thread.new do
    @sandbox.execute
  rescue KrillError, KrillSyntaxError, ProtocolError => e
    notify(@sandbox.job)
    raise e
  ensure
    @mutex.synchronize { @thread_status.running = false }

    if ActiveRecord::Base.connection && ActiveRecord::Base.connection.active?
      ActiveRecord::Base.connection.close
      puts "#{@sandbox.job.id}: Closing ActiveRecord connection"
    end
  end
end

#stopObject

Stops (aborts) this job.

Method called by client via server.



117
118
119
120
121
122
123
# File 'lib/krill/threaded_manager.rb', line 117

def stop
  # TODO: can this be elsewhere?
  puts "Stopping job #{@sandbox.job.id}"

  @thread.kill
  @mutex.synchronize { @thread_status.running = false }
end

#wait(secs) ⇒ String

Waits for the number of seconds while the thread is still running.

Parameters:

  • secs (Integer)

    the number of seconds to wait

Returns:

  • (String)

    'done' if execution is complete,



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/krill/threaded_manager.rb', line 67

def wait(secs)
  n = 0
  running = true
  @mutex.synchronize { running = @thread_status.running }

  while running
    return 'not_ready' unless n < 10 * secs # wait two seconds

    n += 1
    sleep(0.1)
    @mutex.synchronize { running = @thread_status.running }
  end

  @sandbox.reload
  return 'done' if @sandbox.done?

  'ready'
end