Class: WebappWorker::Application

Inherits:
Object
  • Object
show all
Defined in:
lib/webapp_worker/application.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(user_supplied_hash = {}) ⇒ Application

Returns a new instance of Application.



9
10
11
12
13
14
15
16
17
18
19
20
# File 'lib/webapp_worker/application.rb', line 9

def initialize(user_supplied_hash={})
	standard_hash = { hostname:"#{self.hostname}", mailto:"", environment:"local", jobs:"", file:"" }

	user_supplied_hash = {} unless user_supplied_hash
	user_supplied_hash = standard_hash.merge(user_supplied_hash)

	user_supplied_hash.each do |key,value|
		self.instance_variable_set("@#{key}", value)
		self.class.send(:define_method, key, proc{self.instance_variable_get("@#{key}")})
		self.class.send(:define_method, "#{key}=", proc{|x| self.instance_variable_set("@#{key}", x)})
	end
end

Instance Attribute Details

#environmentObject

Returns the value of attribute environment.



7
8
9
# File 'lib/webapp_worker/application.rb', line 7

def environment
  @environment
end

#fileObject

Returns the value of attribute file.



7
8
9
# File 'lib/webapp_worker/application.rb', line 7

def file
  @file
end

#file_mtimeObject

Returns the value of attribute file_mtime.



7
8
9
# File 'lib/webapp_worker/application.rb', line 7

def file_mtime
  @file_mtime
end

#hostnameObject

Returns the value of attribute hostname.



7
8
9
# File 'lib/webapp_worker/application.rb', line 7

def hostname
  @hostname
end

#jobsObject

Returns the value of attribute jobs.



7
8
9
# File 'lib/webapp_worker/application.rb', line 7

def jobs
  @jobs
end

#mailtoObject

Returns the value of attribute mailto.



7
8
9
# File 'lib/webapp_worker/application.rb', line 7

def mailto
  @mailto
end

Instance Method Details

#check_file_modification_timeObject



33
34
35
36
37
38
39
40
# File 'lib/webapp_worker/application.rb', line 33

def check_file_modification_time
	mtime = File.mtime(@file)

	if mtime != @file_mtime
		@file_mtime = mtime
		self.parse_yaml(@file)
	end
end

#commands_to_runObject



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/webapp_worker/application.rb', line 86

def commands_to_run
	self.check_file_modification_time

	commands = {}
	c = {}
	next_commands = {}

	@jobs.each do |job|
		j = WebappWorker::Job.new(job)
		commands.store(j.command,j.next_run?)
	end
	(commands.sort_by { |key,value| value }).collect { |key,value| c.store(key,value) }

	c.each do |key,value|
		next_commands.store(key,value)
	end

	return next_commands
end

#next_command_run?(til) ⇒ Boolean

Returns:

  • (Boolean)


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
# File 'lib/webapp_worker/application.rb', line 42

def next_command_run?(til)
	commands = {}
	c = {}
	next_commands = {}
	new_jobs = []

	(0..til).each do |i|
		@jobs.each do |j|
			new_jobs << j
		end
	end

	new_jobs.flatten.each do |job|
		j = WebappWorker::Job.new(job)
		commands.store(j.command,j.next_runs?(til))
	end

	(commands.sort_by { |key,value| value }).collect { |key,value| c.store(key,value) }

	counter = 0
	c.each do |key,value|
		next_commands.store(key,value)
		counter = counter + 1
		break if counter >= @jobs.length
	end

	return next_commands
end

#next_command_run_time?Boolean

Returns:

  • (Boolean)


71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/webapp_worker/application.rb', line 71

def next_command_run_time?
	commands = {}
	c = {}

	@jobs.each do |job|
		j = WebappWorker::Job.new(job)
		commands.store(j.command,j.next_run?)
	end
	(commands.sort_by { |key,value| value }).collect { |key,value| c.store(key,value) }

	c.each do |key,value|
		return value[0]
	end
end

#parse_yaml(yaml) ⇒ Object



22
23
24
25
26
27
# File 'lib/webapp_worker/application.rb', line 22

def parse_yaml(yaml)
	@file = yaml
	@file_mtime = File.mtime(@file)
	@mailto = (YAML.load_file(@file))[@environment]["mailto"] unless @mailto
	@jobs = (YAML.load_file(@file))[@environment][@hostname] unless @hostname.nil?
end

#run(debug = nil, verbose = nil) ⇒ Object



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
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
181
182
183
184
185
186
187
188
189
190
191
# File 'lib/webapp_worker/application.rb', line 106

def run(debug=nil,verbose=nil)
	p = Process.fork do
		#Some Setup Work
		$0="WebApp Worker - Job File: #{@file}"
		waw_system = WebappWorker::System.new
		waw_system.setup(debug,verbose)
		logger = waw_system.logger

		%w(INT QUIT TERM TSTP).each do |sig|
			Signal.trap(sig) do
				stop_loop = true
				logger.warn "Received a #{sig} signal, stopping current commands."
				waw_system.graceful_termination(@threads,@command_processes)
			end
		end

		#WebApp Worker is setup now do the real work
		@command_processes = {}
		@threads = {}
		stop_loop = false

		logger.debug "Going into Loop"
		until stop_loop
			@threads.each do |thread,command|
				if thread.status == false
					logger.debug "Deleting Old Thread from Array of Jobs"
					@threads.delete(thread)
				end
			end

			data = self.commands_to_run

			data.each do |command,time|
				time = time[0]
				now = Time.now.utc
				range = (time - now).to_i

				if @threads.detect { |thr,com| com == command }
					data.delete(command)
				else
					t = Thread.new do
						logger.debug "Creating New Thread for command: #{command} - may need to sleep for: #{range} seconds"
						sleep(range) unless range <= 0
						logger.debug "Running Command: #{command}"

						pid, stdin, stdout, stderr = Open4::popen4 command
						@command_processes.store(pid,command)

						#make logger log to a specific job file log file

						ignored, status = Process::waitpid2 pid

						if status.to_i == 0
							logger.debug "Completed Command: #{command}"
						else
							logger.fatal "Command: #{command} Failure! Exited with Status: #{status.to_i}, Standard Out and Error Below"
							logger.fatal "STDOUT BELOW:"
							stdout.each_line do |line|
								logger.fatal line
							end
							logger.fatal "STDERR BELOW:"
							stderr.each_line do |line|
								logger.fatal line
							end
							logger.fatal "Command: #{command} Unable to Complete! Standard Out and Error Above"
						end
					end
					@threads.store(t,command)
				end
			end

			logger.debug Thread.list
			logger.debug @threads.inspect
			logger.debug @command_processes.inspect

			time = self.next_command_run_time?
			now = Time.now.utc
			range = (time - now).to_i
			range = range - 1
			logger.debug "Sleeping for #{range} seconds after looping through all jobs found"
			sleep(range) unless range <= 0
		end
	end

	Process.detach(p)
end