Class: Hydra::Master
- Inherits:
-
Object
- Object
- Hydra::Master
- Includes:
- Hydra::Messages::Master, Open3
- Defined in:
- lib/hydra/master.rb
Instance Attribute Summary collapse
-
#report_text ⇒ Object
readonly
A text report of the time it took to run each file.
Instance Method Summary collapse
-
#initialize(opts = { }) ⇒ Master
constructor
Create a new Master.
-
#process_results(worker, message) ⇒ Object
Process the results coming back from the worker.
-
#send_file(worker) ⇒ Object
Send a file down to a worker.
-
#worker_begin(worker) ⇒ Object
Message handling.
Constructor Details
#initialize(opts = { }) ⇒ Master
Create a new Master
Options:
-
:files
-
An array of test files to be run. These should be relative paths from the root of the project, since they may be run on different machines which may have different paths.
-
-
:workers
-
An array of hashes. Each hash should be the configuration options for a worker.
-
-
:listeners
-
An array of Hydra::Listener objects. See Hydra::Listener::MinimalOutput for an example listener
-
-
:verbose
-
Set to true to see lots of Hydra output (for debugging)
-
-
:autosort
-
Set to false to disable automatic sorting by historical run-time per file
-
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/hydra/master.rb', line 35 def initialize(opts = { }) opts.stringify_keys! config_file = opts.delete('config') { nil } if config_file begin config_erb = ERB.new(IO.read(config_file)).result(binding) rescue Exception => e raise(YmlLoadError,"config file was found, but could not be parsed with ERB.\n#{$!.inspect}") end begin config_yml = YAML::load(config_erb) rescue StandardError => e raise(YmlLoadError,"config file was found, but could not be parsed.\n#{$!.inspect}") end opts.merge!(config_yml.stringify_keys!) end @files = Array(opts.fetch('files') { nil }) raise "No files, nothing to do" if @files.empty? @incomplete_files = @files.dup @workers = [] @listeners = [] @event_listeners = Array(opts.fetch('listeners') { nil } ) @event_listeners.select{|l| l.is_a? String}.each do |l| @event_listeners.delete_at(@event_listeners.index(l)) listener = eval(l) @event_listeners << listener if listener.is_a?(Hydra::Listener::Abstract) end @verbose = opts.fetch('verbose') { false } @autosort = opts.fetch('autosort') { true } @sync = opts.fetch('sync') { nil } @environment = opts.fetch('environment') { 'test' } if @autosort sort_files_from_report @event_listeners << Hydra::Listener::ReportGenerator.new(File.new(heuristic_file, 'w')) end # default is one worker that is configured to use a pipe with one runner worker_cfg = opts.fetch('workers') { [ { 'type' => 'local', 'runners' => 1} ] } trace "Initialized" trace " Files: (#{@files.inspect})" trace " Workers: (#{worker_cfg.inspect})" trace " Verbose: (#{@verbose.inspect})" @event_listeners.each{|l| l.testing_begin(@files) } boot_workers worker_cfg end |
Instance Attribute Details
#report_text ⇒ Object (readonly)
A text report of the time it took to run each file
132 133 134 |
# File 'lib/hydra/master.rb', line 132 def report_text @report_text end |
Instance Method Details
#process_results(worker, message) ⇒ Object
Process the results coming back from the worker.
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/hydra/master.rb', line 107 def process_results(worker, ) if .output =~ /ActiveRecord::StatementInvalid(.*)[Dd]eadlock/ or .output =~ /PGError: ERROR(.*)[Dd]eadlock/ or .output =~ /Mysql::Error: SAVEPOINT(.*)does not exist: ROLLBACK/ or .output =~ /Mysql::Error: Deadlock found/ trace "Deadlock detected running [#{.file}]. Will retry at the end" @files.push(.file) send_file(worker) else @incomplete_files.delete_at(@incomplete_files.index(.file)) trace "#{@incomplete_files.size} Files Remaining" @event_listeners.each{|l| l.file_end(.file, .output) } if @incomplete_files.empty? @workers.each do |worker| @event_listeners.each{|l| l.worker_end(worker) } end shutdown_all_workers else send_file(worker) end end end |
#send_file(worker) ⇒ Object
Send a file down to a worker.
95 96 97 98 99 100 101 102 103 104 |
# File 'lib/hydra/master.rb', line 95 def send_file(worker) f = @files.shift if f trace "Sending #{f.inspect}" @event_listeners.each{|l| l.file_begin(f) } worker[:io].write(RunFile.new(:file => f)) else trace "No more files to send" end end |
#worker_begin(worker) ⇒ Object
Message handling
90 91 92 |
# File 'lib/hydra/master.rb', line 90 def worker_begin(worker) @event_listeners.each {|l| l.worker_begin(worker) } end |