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