naf 2.1.3 → 2.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/app/models/logical/naf/log_parser/runner.rb +1 -1
- data/app/models/naf/application_type.rb +4 -3
- data/app/models/process/naf/logger/base.rb +22 -0
- data/app/models/process/naf/logger/job_log.rb +9 -0
- data/app/models/process/naf/logger/runner_log.rb +13 -0
- data/app/models/process/naf/runner.rb +2 -73
- data/bin/naf +1 -1
- data/lib/naf/version.rb +1 -1
- data/naf.gemspec +1 -1
- metadata +5 -3
- data/app/models/process/naf/runner_log.rb +0 -26
@@ -52,7 +52,7 @@ module Logical::Naf
|
|
52
52
|
|
53
53
|
def get_invocation_id(uuid)
|
54
54
|
if invocations_ids[uuid].blank?
|
55
|
-
@invocations_ids[uuid] = ::Naf::MachineRunnerInvocation.find_by_uuid(uuid).id
|
55
|
+
@invocations_ids[uuid] = ::Naf::MachineRunnerInvocation.find_by_uuid(uuid).try(:id)
|
56
56
|
end
|
57
57
|
|
58
58
|
invocations_ids[uuid]
|
@@ -7,6 +7,7 @@ module Naf
|
|
7
7
|
:invocation_method
|
8
8
|
|
9
9
|
SCRIPT_RUNNER = "#{Gem.ruby} #{Rails.root}/script/rails runner"
|
10
|
+
JOB_LOGGER = "#{Rails.root}/script/rails runner ::Process::Naf::Logger::JobLog.run"
|
10
11
|
|
11
12
|
#---------------------
|
12
13
|
# *** Associations ***
|
@@ -32,9 +33,9 @@ module Naf
|
|
32
33
|
self.send(invocation_method.to_sym, job)
|
33
34
|
end
|
34
35
|
|
35
|
-
def invoke(job,
|
36
|
-
|
37
|
-
|
36
|
+
def invoke(job, job_command)
|
37
|
+
command = job_command + " 2>&1 | #{JOB_LOGGER} >> #{LOGGING_ROOT_DIRECTORY}/naf/crash.log 2>&1"
|
38
|
+
Process.spawn({ 'NAF_JOB_ID' => job.id.to_s }, command)
|
38
39
|
end
|
39
40
|
|
40
41
|
def rails_invocator(job)
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'open4'
|
2
|
+
|
3
|
+
module Process::Naf::Logger
|
4
|
+
class Base < ::Af::Application
|
5
|
+
|
6
|
+
def work
|
7
|
+
log_file = ::Logical::Naf::LogFile.new(file_path)
|
8
|
+
log_file.open
|
9
|
+
|
10
|
+
while $stdin.gets
|
11
|
+
begin
|
12
|
+
log_file << $_.rstrip
|
13
|
+
ensure
|
14
|
+
log_file.write
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
log_file.close
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Process::Naf::Logger
|
2
|
+
class RunnerLog < Base
|
3
|
+
|
4
|
+
opt :invocation_uuid,
|
5
|
+
"unique identifer used for runner logs",
|
6
|
+
default: `uuidgen`
|
7
|
+
|
8
|
+
def file_path
|
9
|
+
"#{::Naf::PREFIX_PATH}/#{::Naf.schema_name}/runners/#{@invocation_uuid}/"
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
13
|
+
end
|
@@ -184,7 +184,6 @@ module Process::Naf
|
|
184
184
|
logger.info escape_html("working: #{machine}")
|
185
185
|
|
186
186
|
@children = {}
|
187
|
-
@threads = {}
|
188
187
|
|
189
188
|
at_exit {
|
190
189
|
::Af::Application.singleton.emergency_teardown
|
@@ -349,11 +348,6 @@ module Process::Naf
|
|
349
348
|
logger.info { escape_html("cleaning up dead child: #{child_job.reload}") }
|
350
349
|
finish_job(child_job,
|
351
350
|
{ exit_status: (status && status.exitstatus), termination_signal: (status && status.termsig) })
|
352
|
-
|
353
|
-
thread = @threads.delete(pid)
|
354
|
-
logger.detail escape_html("cleaning up threads: #{thread.inspect}")
|
355
|
-
logger.detail escape_html("thread list: #{Thread.list}")
|
356
|
-
thread.join
|
357
351
|
else
|
358
352
|
# this can happen if the child is sigstopped
|
359
353
|
logger.warn escape_html("child waited for did not exit: #{child_job}, status: #{status.inspect}")
|
@@ -382,13 +376,8 @@ module Process::Naf
|
|
382
376
|
|
383
377
|
logger.info escape_html("starting new job : #{running_job.inspect}")
|
384
378
|
|
385
|
-
|
386
|
-
pid
|
387
|
-
stdin.close
|
388
|
-
|
389
|
-
# Reset NAF_JOB_ID
|
390
|
-
ENV.delete('NAF_JOB_ID')
|
391
|
-
if pid
|
379
|
+
pid = running_job.historical_job.spawn
|
380
|
+
if pid.present?
|
392
381
|
@children[pid] = running_job
|
393
382
|
running_job.pid = pid
|
394
383
|
running_job.historical_job.pid = pid
|
@@ -397,17 +386,6 @@ module Process::Naf
|
|
397
386
|
logger.info escape_html("job started : #{running_job}")
|
398
387
|
running_job.save!
|
399
388
|
running_job.historical_job.save!
|
400
|
-
|
401
|
-
# Spawn a thread to output the log of each job to files.
|
402
|
-
#
|
403
|
-
# Make sure not to execute any database calls inside this
|
404
|
-
# block, as it will start an ActiveRecord connection for each
|
405
|
-
# thread and eventually raise a ConnetionTimeoutError, resulting
|
406
|
-
# the runner to exit.
|
407
|
-
thread = Thread.new do
|
408
|
-
log_output_until_job_finishes(running_job.id, stdout, stderr)
|
409
|
-
end
|
410
|
-
@threads[pid] = thread
|
411
389
|
else
|
412
390
|
# should never get here (well, hopefully)
|
413
391
|
logger.error escape_html("#{machine}: failed to execute #{running_job}")
|
@@ -425,55 +403,6 @@ module Process::Naf
|
|
425
403
|
logger.debug_gross "done starting jobs"
|
426
404
|
end
|
427
405
|
|
428
|
-
def log_output_until_job_finishes(job_id, stdout, stderr)
|
429
|
-
log_file = ::Logical::Naf::LogFile.new("#{::Naf::PREFIX_PATH}/#{::Naf.schema_name}/jobs/#{job_id}")
|
430
|
-
log_file.open
|
431
|
-
|
432
|
-
# Continue reading logs from stdout/stderror until it reaches end of file
|
433
|
-
while true
|
434
|
-
read_pipes = []
|
435
|
-
read_pipes << stdout if stdout
|
436
|
-
read_pipes << stderr if stderr
|
437
|
-
return if (read_pipes.length == 0)
|
438
|
-
|
439
|
-
error_pipes = read_pipes.clone
|
440
|
-
read_array, write_array, error_array = Kernel.select(read_pipes, nil, error_pipes, 1)
|
441
|
-
|
442
|
-
unless error_array.blank?
|
443
|
-
logger.error escape_html("job(#{job_id}): select returned error for #{error_pipes.inspect} (read_pipes: #{read_pipes.inspect})")
|
444
|
-
# XXX we should probably close the errored FDs
|
445
|
-
end
|
446
|
-
|
447
|
-
unless read_array.blank?
|
448
|
-
begin
|
449
|
-
for r in read_array do
|
450
|
-
begin
|
451
|
-
# Parse each log line into JSON
|
452
|
-
r.read_nonblock(10240).split("\n").each do |log|
|
453
|
-
log_file << log.rstrip
|
454
|
-
end
|
455
|
-
rescue Errno::EAGAIN => e
|
456
|
-
logger.error 'EAGAIN'
|
457
|
-
logger.error "#{e.inspect}"
|
458
|
-
logger.error "#{e.message}"
|
459
|
-
rescue Errno::EWOULDBLOCK => ew
|
460
|
-
logger.error 'EWOULDBLOCK'
|
461
|
-
logger.error "#{ew.inspect}"
|
462
|
-
logger.error "#{ew.message}"
|
463
|
-
rescue EOFError => eof
|
464
|
-
stdout = nil if r == stdout
|
465
|
-
stderr = nil if r == stderr
|
466
|
-
end
|
467
|
-
end
|
468
|
-
ensure
|
469
|
-
log_file.write
|
470
|
-
end
|
471
|
-
end
|
472
|
-
end
|
473
|
-
|
474
|
-
log_file.close
|
475
|
-
end
|
476
|
-
|
477
406
|
# XXX update_all doesn't support "from_partition" so we have this helper
|
478
407
|
def update_historical_job(updates, historical_job_id)
|
479
408
|
updates[:updated_at] = Time.zone.now
|
data/bin/naf
CHANGED
@@ -6,7 +6,7 @@ if action == 'runner'
|
|
6
6
|
if option == 'up'
|
7
7
|
puts "Bringing up the runner(s)..."
|
8
8
|
`screen -d -m bash -c 'source /root/.bash_profile && cd /root/current && a=\`uuidgen\` && script/rails runner ::Process::Naf::Runner.run --invocation-uuid $a 2>&1 |
|
9
|
-
script/rails runner ::Process::Naf::RunnerLog.run --invocation-uuid $a'`
|
9
|
+
script/rails runner ::Process::Naf::Logger::RunnerLog.run --invocation-uuid $a'`
|
10
10
|
|
11
11
|
elsif option == 'status'
|
12
12
|
num_runners = Integer(`ps -ef | grep Process::Naf::Runner.run | grep -v grep | grep -v uuidgen | wc -l`.strip)
|
data/lib/naf/version.rb
CHANGED
data/naf.gemspec
CHANGED
@@ -8,7 +8,7 @@ Gem::Specification.new do |s|
|
|
8
8
|
s.name = "naf"
|
9
9
|
s.version = Naf::VERSION
|
10
10
|
s.license = 'New BSD License'
|
11
|
-
s.date = '2014-02-
|
11
|
+
s.date = '2014-02-25'
|
12
12
|
s.summary = "Creates infrastructure for a customizable and robust Postgres-backed script scheduling/running"
|
13
13
|
s.description = "A cloud based distributed cron, application framework and operations console. Naf works as a distributed script running " +
|
14
14
|
"system that provides scheduling, logging, alarming, machine redundancy, and the ability to set constraint during script execution"
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: naf
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.1.
|
4
|
+
version: 2.1.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -12,7 +12,7 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date: 2014-02-
|
15
|
+
date: 2014-02-25 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: rails
|
@@ -320,10 +320,12 @@ files:
|
|
320
320
|
- app/models/process/naf/janitor.rb
|
321
321
|
- app/models/process/naf/log_archiver.rb
|
322
322
|
- app/models/process/naf/log_reader.rb
|
323
|
+
- app/models/process/naf/logger/base.rb
|
324
|
+
- app/models/process/naf/logger/job_log.rb
|
325
|
+
- app/models/process/naf/logger/runner_log.rb
|
323
326
|
- app/models/process/naf/machine_manager.rb
|
324
327
|
- app/models/process/naf/machine_upgrader.rb
|
325
328
|
- app/models/process/naf/runner.rb
|
326
|
-
- app/models/process/naf/runner_log.rb
|
327
329
|
- app/views/naf/affinities/_form.html.erb
|
328
330
|
- app/views/naf/affinities/edit.html.erb
|
329
331
|
- app/views/naf/affinities/index.html.erb
|
@@ -1,26 +0,0 @@
|
|
1
|
-
require 'open4'
|
2
|
-
|
3
|
-
module Process::Naf
|
4
|
-
class RunnerLog < ::Af::Application
|
5
|
-
|
6
|
-
opt :invocation_uuid,
|
7
|
-
"unique identifer used for runner logs",
|
8
|
-
default: `uuidgen`
|
9
|
-
|
10
|
-
def work
|
11
|
-
log_file = ::Logical::Naf::LogFile.new("#{::Naf::PREFIX_PATH}/#{::Naf.schema_name}/runners/#{@invocation_uuid}/")
|
12
|
-
log_file.open
|
13
|
-
|
14
|
-
while $stdin.gets
|
15
|
-
begin
|
16
|
-
log_file << $_.rstrip
|
17
|
-
ensure
|
18
|
-
log_file.write
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
log_file.close
|
23
|
-
end
|
24
|
-
|
25
|
-
end
|
26
|
-
end
|