Class: Videoreg::Registrar
- Inherits:
-
Base
- Object
- Base
- Videoreg::Registrar
show all
- Defined in:
- lib/videoreg/registrar.rb
Constant Summary
collapse
- DELEGATE_TO_CONFIG =
[:command, :outfile, :resolution, :fps, :duration, :device, :storage, :base_cmd, :store_max]
Instance Attribute Summary collapse
Instance Method Summary
collapse
Methods inherited from Base
#logger, logger, #logger=, logger=, #proc_alive?, #tpl, #which
Constructor Details
#initialize(&block) ⇒ Registrar
Returns a new instance of Registrar.
14
15
16
17
18
19
20
|
# File 'lib/videoreg/registrar.rb', line 14
def initialize(&block)
@config = Videoreg::Config.new
@pid = nil
@halted_mutex = nil
@terminated = false
configure(&block) if block_given?
end
|
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(m) ⇒ Object
27
28
29
|
# File 'lib/videoreg/registrar.rb', line 27
def method_missing(m)
DELEGATE_TO_CONFIG.include?(m.to_sym) ? config.send(m) : super
end
|
Instance Attribute Details
#config ⇒ Object
Returns the value of attribute config.
9
10
11
|
# File 'lib/videoreg/registrar.rb', line 9
def config
@config
end
|
Instance Method Details
#clean_old_files! ⇒ Object
78
79
80
81
82
83
84
85
86
87
88
|
# File 'lib/videoreg/registrar.rb', line 78
def clean_old_files!
all_saved_files = Dir[Pathname.new(storage).join("*#{File.extname(config.filename)}").to_s].sort_by { |c|
File.stat(c).ctime
}.reverse
if all_saved_files.length > config.store_max.to_i
all_saved_files[config.store_max.to_i..-1].each do |saved_file|
logger.info "Removing saved file #{saved_file}..."
File.unlink(saved_file) if File.exists?(saved_file)
end
end
end
|
22
23
24
25
|
# File 'lib/videoreg/registrar.rb', line 22
def configure
@thread = nil
yield @config
end
|
#continuous ⇒ Object
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
|
# File 'lib/videoreg/registrar.rb', line 31
def continuous
logger.info "Starting the continuous capture..."
@terminated = false
@thread = Thread.new do
while true do
unless @halted_mutex.nil?
logger.info "Registrar (#{device}) HALTED. Waiting for the restore message..."
@halted_mutex.lock
end
unless device_exists?
logger.error "Capture failed! Device #{device} does not exist!"
terminate!
end
begin
logger.info "Cleaning old files from storage (#{storage})... (MAX: #{config.store_max})"
clean_old_files!
logger.info "Waiting for registrar (#{device}) to finish the part (#{outfile})..."
run logger.info "Registrar (#{device}) has finished to capture the part (#{outfile})..."
rescue RuntimeError => e
logger.error(e.message)
logger.info "Registrar (#{device}) has failed to capture the part (#{outfile})..."
terminate!
end
end
end
end
|
#device_exists? ⇒ Boolean
149
150
151
|
# File 'lib/videoreg/registrar.rb', line 149
def device_exists?
File.exists?(device)
end
|
#force_release_lock! ⇒ Object
144
145
146
147
|
# File 'lib/videoreg/registrar.rb', line 144
def force_release_lock!
logger.info("Forced to release lockfile #{config.lockfile}...")
File.unlink(config.lockfile) if File.exists?(config.lockfile)
end
|
#halt! ⇒ Object
90
91
92
93
94
95
|
# File 'lib/videoreg/registrar.rb', line 90
def halt!
logger.info "Registrar #{device} HALTED! Killing process..."
@halted_mutex = Mutex.new
@halted_mutex.lock
kill_process!
end
|
#kill! ⇒ Object
125
126
127
128
129
130
|
# File 'lib/videoreg/registrar.rb', line 125
def kill!
terminate!
kill_process! if process_alive?
ensure
safe_release!
end
|
#kill_process! ⇒ Object
Kill just the underlying process
114
115
116
117
118
119
120
121
122
|
# File 'lib/videoreg/registrar.rb', line 114
def kill_process!
begin
logger.info("Killing the process for #{device} : #{pid}")
Process.kill("KILL", pid) if process_alive?
Process.getpgid
rescue => e
logger.warn("An attempt to kill already killed process (#{pid}): #{e.message}")
end
end
|
#pause! ⇒ Object
97
98
99
100
|
# File 'lib/videoreg/registrar.rb', line 97
def pause!
logger.info "Registrar #{device} pausing process with pid #{pid}..."
Process.kill("STOP", pid) if process_alive?
end
|
#paused? ⇒ Boolean
165
166
167
|
# File 'lib/videoreg/registrar.rb', line 165
def paused?
process_alive? && (`ps -p #{pid} -o stat=`.chomp == "T")
end
|
#pid ⇒ Object
74
75
76
|
# File 'lib/videoreg/registrar.rb', line 74
def pid
@pid || ((rpid = lockfile.lockcode) ? rpid.to_i : nil)
end
|
#process_alive? ⇒ Boolean
157
158
159
|
# File 'lib/videoreg/registrar.rb', line 157
def process_alive?
!pid.to_s.empty? && pid.to_i != 0 && proc_alive?(pid)
end
|
#recover! ⇒ Object
102
103
104
105
106
|
# File 'lib/videoreg/registrar.rb', line 102
def recover!
logger.info "Registrar #{device} UNHALTED! Recovering process..."
@halted_mutex.unlock if @halted_mutex && @halted_mutex.locked?
@halted_mutex = nil
end
|
#resume! ⇒ Object
108
109
110
111
|
# File 'lib/videoreg/registrar.rb', line 108
def resume!
logger.info "Registrar #{device} resuming process with pid #{pid}..."
Process.kill("CONT", pid) if process_alive?
end
|
#run ⇒ Object
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
# File 'lib/videoreg/registrar.rb', line 59
def run
logger.info "Spawning a new process to capture video from device '#{device}'..."
raise "Lockfile already exists '#{config.lockfile}'..." if File.exist?(config.lockfile)
logger.info "Running the command: '#{command}'..."
raise "#{base_cmd} not found on your system. Please install it or add it to your PATH" if which(base_cmd).nil?&& !File.exists?(base_cmd)
Open4::popen4(command) do |pid, stdin, stdout, stderr|
@pid = pid
raise "Cannot lock the lock-file '#{config.lockfile}'..." unless lock(pid)
output = stdout.read + stderr.read
raise "FATAL ERROR: Cannot capture video: \n #{output}" if error?(output)
end
ensure
release
end
|
#safe_release! ⇒ Object
140
141
142
|
# File 'lib/videoreg/registrar.rb', line 140
def safe_release!
release if File.exists?(config.lockfile)
end
|
#self_alive? ⇒ Boolean
153
154
155
|
# File 'lib/videoreg/registrar.rb', line 153
def self_alive?
process_alive? && lockfile.readlock
end
|
#terminate! ⇒ Object
Terminate the main thread
133
134
135
136
137
138
|
# File 'lib/videoreg/registrar.rb', line 133
def terminate!
@terminated = true
@thread.kill if @thread
ensure
safe_release!
end
|
#terminated? ⇒ Boolean
161
162
163
|
# File 'lib/videoreg/registrar.rb', line 161
def terminated?
@terminated
end
|