Module: Oats::OatsLock
- Defined in:
- lib/oats/oats_lock.rb
Constant Summary collapse
- @@file_handle =
nil
- @@is_locked =
false
Class Method Summary collapse
- .find_matching_processes(proc_names) ⇒ Object
- .kill_pid(pid, info_line = nil) ⇒ Object
- .kill_webdriver_browsers ⇒ Object
-
.locked?(verify = nil) ⇒ Boolean
Returns the locked state after the last check verify: true will verify the true state of the lock.
-
.reset ⇒ Object
Removes lock.
-
.set(verbose = nil) ⇒ Object
Returns true if able to set the lock.
Class Method Details
.find_matching_processes(proc_names) ⇒ Object
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 |
# File 'lib/oats/oats_lock.rb', line 141 def OatsLock.find_matching_processes(proc_names) matched = [] if RUBY_PLATFORM =~ /(mswin|mingw)/ processes = WIN32OLE.connect("winmgmts://").ExecQuery("select * from win32_process") # for process in processes do # for property in process.Properties_ do # puts property.Name # end # break # end processes.each do |process| # puts [process.Commandline, process.ProcessId, process.name].inspect if process.Commandline =~ proc_names matched.push [process.ProcessId,process.Name,nil, process.CommandLine] end end else pscom = RUBY_PLATFORM =~ /linux/ ? 'ps lxww' : 'ps -ef' `#{pscom}`.split("\n").each do |lvar| line = lvar.chomp case RUBY_PLATFORM when /darwin/ # ps -ef output pid = line[5..11] next if pid.to_i == 0 ppid = line[12..16] proc_name = line[50..-1] when /linux/ # ps ww output pid = line[7..12] next if pid.to_i == 0 ppid = line[13..18] proc_name = line[69..-1] else raise OatError, "Do not know how to parse ps output from #{RUBY_PLATFORM}" end next unless pid matched.push [pid.strip, proc_name.strip, ppid.strip, line.strip] if proc_name =~ proc_names end end return matched end |
.kill_pid(pid, info_line = nil) ⇒ Object
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/oats/oats_lock.rb', line 117 def OatsLock.kill_pid(pid,info_line=nil) signal = 'KILL' no_such_process = false begin killed = Process.kill(signal,pid.to_i) rescue Errno::ESRCH # OK if the process is gone no_such_process = true end if RUBY_VERSION =~ /^1.9/ if killed.empty? killed = 0 else killed = 1 end end if no_such_process # $log.debug "No such process #{info_line||pid}" elsif killed == 0 $log.warn "Failed to kill [#{info_line||pid}]" else $log.warn "Successfully killed [#{info_line||pid}]" end end |
.kill_webdriver_browsers ⇒ Object
182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 |
# File 'lib/oats/oats_lock.rb', line 182 def OatsLock.kill_webdriver_browsers # match = "ruby.*oats/lib/oats_main.rb" match = 'ruby.*oats(\\\\|\/)bin(\\\\|\/)oats' # Not tested on agents on Windows_NT if $oats_execution['agent'] nickname = $oats_execution['agent']['execution:occ:agent_nickname'] port = $oats_execution['agent']['execution:occ:agent_port'] match += " -p #{port} -n #{nickname}" end # Kill all selenium automation chrome jobs on MacOS. Assumes MacOS is for development only, not OCC. # Will cause problems if multiple agents are run on MacOS if RUBY_PLATFORM =~ /darwin/ chrome_automation_procs = OatsLock.find_matching_processes(/ Chrome .* --dom-automation/) chrome_automation_procs.each do |pid,proc_name,ppid| OatsLock.kill_pid pid end end oats_procs = OatsLock.find_matching_processes(/#{match}\z/) chromedriver_procs = OatsLock.find_matching_processes(/IEXPLORE.EXE\" -noframemerging|(chromedriver|firefox(-bin|\.exe\") -no-remote)/) webdriver_procs = OatsLock.find_matching_processes(/webdriver/) oats_procs.each do |opid,oproc_name,oppid| chromedriver_procs.each do |cpid,cproc_name,cppid| if cppid == opid webdriver_procs.each do |wpid,wproc_name,wppid| OatsLock.kill_pid wpid if wppid == cpid end OatsLock.kill_pid cpid end end end # If parent ruby dies, ppid reverts to "1" (chromedriver_procs + webdriver_procs).each do |pid,proc_name,ppid| if RUBY_PLATFORM =~ /(mswin|mingw)/ OatsLock.kill_pid pid else OatsLock.kill_pid pid if ppid == "1" and proc_name !~ /defunct/ end end end |
.locked?(verify = nil) ⇒ Boolean
Returns the locked state after the last check verify: true will verify the true state of the lock
30 31 32 33 34 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 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 114 115 |
# File 'lib/oats/oats_lock.rb', line 30 def OatsLock.locked?(verify = nil) return @@is_locked unless verify @@is_locked = false if RUBY_PLATFORM !~ /(mswin|mingw)/ or ENV['TEMP'] =~ /^\/cygdrive/ if File.exist?(in_progress_file) pids = IO.readlines(in_progress_file) ruby_pid = pids.shift return @@is_locked unless ruby_pid ps_line = `ps -p #{ruby_pid} ` if ps_line =~ /bin\/ruby/ @@is_locked = true $log.error "Another oats session is possibly in progress:" $log.error ">> #{ps_line}" $log.error "Please kill locking processes or remove #{in_progress_file}." else pids.each { |pid| OatsLock.kill_pid(pid.chomp) } FileUtils.rm(in_progress_file) end end else begin FileUtils.rm(in_progress_file) rescue Errno::ENOENT # No such File or Directory rescue Errno::EACCES # unlink Permission denied @@is_locked = true return @@is_locked if verify == :handles_are_cleared # Attempt to kill all dangling processes that prevent removal of the lock proc_array = nil hstring = lock_file ok_to_kill = /(java)|(mysql)||(chromedriver)|(firefox)||(chrome)|(iexplore)\.exe/ pid, proc_name, handle_string, line = nil matches = IO.popen("handle #{hstring}").readlines oats_is_alive = false matches.each do |lvar| line = lvar.chomp proc_array = parse_windows_handle_process_line(line) pid, proc_name, handle_string = proc_array next unless pid if proc_name =~ /ruby/ # if pid = $$.to_s # @@is_locked = false # return false # end oats_is_alive = line $log.error "Another oats session is possibly in progress:" $log.error ">> #{line}" $log.error "Please kill locking processes and remove this file if the oats session is defunct." break end end @@is_locked = oats_is_alive unless oats_is_alive matches.each do |lvar| line = lvar.chomp pid, proc_name, handle_string = parse_windows_handle_process_line(line) next unless pid raise "Handle error for [#{hstring}] Please notify OATS administrator." unless handle_string =~ /#{hstring}/ $log.warn "Likely locking process: [#{line}]" if proc_name =~ ok_to_kill $log.warn "Will attempt to kill [#{proc_name}] with PID #{pid}" signal = 'KILL' killed = Process.kill(signal,pid.to_i) if RUBY_VERSION =~ /^1.9/ if killed.empty? killed = 0 else killed = 1 end end if killed == 0 $log.warn "Failed to kill the process" else $log.warn "Successfully killed [#{proc_name}]" end else $log.warn "Oats is configured not to auto-kill process [#{proc_name}]" end end sleep 2 # Need time to clear the process handles @@is_locked = OatsLock.locked?(:handles_are_cleared) # Still locked? end @@is_locked = proc_array if @@is_locked and proc_array end end return @@is_locked end |
.reset ⇒ Object
Removes lock
226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 |
# File 'lib/oats/oats_lock.rb', line 226 def OatsLock.reset if @@file_handle # Only for Windows @@file_handle.close @@file_handle = nil @@is_locked = true else # Doesn't return status properly for non-windows, just resets the lock if $oats_execution['agent'].nil? and RUBY_PLATFORM !~ /(mswin|mingw)/ and File.exist?(in_progress_file) pids = IO.readlines(in_progress_file) current_pid = pids.shift pids.each { |pid| OatsLock.kill_pid(pid.chomp) } # Legacy firefox end @@is_locked = false end FileUtils.rm_f in_progress_file return @@is_locked end |
.set(verbose = nil) ⇒ Object
Returns true if able to set the lock.
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
# File 'lib/oats/oats_lock.rb', line 10 def OatsLock.set(verbose = nil) if OatsLock.locked?(true) return false else @@file_handle = File.open(in_progress_file, 'w') my_pid = Process.pid.to_s @@file_handle.puts my_pid if RUBY_PLATFORM !~ /(mswin|mingw)/ or ENV['TEMP'] =~ /^\/cygdrive/ # Leave file handle open for windows to detect and kill associated java, etc. # processes using file handles. @@file_handle.close @@file_handle = nil end @@is_locked = true return true end end |