naf 1.1.0
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/.gitignore +16 -0
- data/.rspec +1 -0
- data/.travis.yml +17 -0
- data/Gemfile +17 -0
- data/LICENSE +2 -0
- data/README.rdoc +22 -0
- data/RELEASE_NOTES.rdoc +18 -0
- data/Rakefile +43 -0
- data/app/assets/images/bg-grad.png +0 -0
- data/app/assets/images/clock.png +0 -0
- data/app/assets/images/control_play_blue.png +0 -0
- data/app/assets/images/down_arrow.gif +0 -0
- data/app/assets/images/papertrail_job.png +0 -0
- data/app/assets/images/papertrail_machine.png +0 -0
- data/app/assets/images/papertrail_machine_runner.png +0 -0
- data/app/assets/images/terminate.png +0 -0
- data/app/assets/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/app/assets/images/ui-bg_flat_0_ffffff_40x100.png +0 -0
- data/app/assets/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/app/assets/images/ui-bg_glass_0_f4f4f4_1x400.png +0 -0
- data/app/assets/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- data/app/assets/images/ui-bg_glass_65_f4f4f4_1x400.png +0 -0
- data/app/assets/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/app/assets/images/ui-bg_glass_75_dadada_1x400.png +0 -0
- data/app/assets/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/app/assets/images/ui-bg_glass_75_f4f4f4_1x400.png +0 -0
- data/app/assets/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/app/assets/images/ui-bg_highlight-soft_0_f4f4f4_1x100.png +0 -0
- data/app/assets/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/app/assets/images/ui-icons_222222_256x240.png +0 -0
- data/app/assets/images/ui-icons_2e83ff_256x240.png +0 -0
- data/app/assets/images/ui-icons_454545_256x240.png +0 -0
- data/app/assets/images/ui-icons_888888_256x240.png +0 -0
- data/app/assets/images/ui-icons_cd0a0a_256x240.png +0 -0
- data/app/assets/images/up_arrow.gif +0 -0
- data/app/assets/javascripts/dataTablesTemplates/applications.js +94 -0
- data/app/assets/javascripts/dataTablesTemplates/jobs.js +163 -0
- data/app/assets/javascripts/dataTablesTemplates/machine_runner_invocations.js +60 -0
- data/app/assets/javascripts/dataTablesTemplates/machine_runners.js +82 -0
- data/app/assets/javascripts/dataTablesTemplates/machines.js +93 -0
- data/app/assets/javascripts/date.js +104 -0
- data/app/assets/javascripts/iso8601.js +41 -0
- data/app/assets/javascripts/jquery.dataTables.custom.js +62 -0
- data/app/assets/javascripts/jquery.dataTables.js +6862 -0
- data/app/assets/javascripts/naf.js +30 -0
- data/app/assets/javascripts/underscore.js +713 -0
- data/app/assets/stylesheets/jquery_ui/jquery-ui-1.8.5.custom.css.erb +572 -0
- data/app/assets/stylesheets/min_naf.css +14 -0
- data/app/assets/stylesheets/min_naf/layout.css.scss +355 -0
- data/app/assets/stylesheets/naf.css +14 -0
- data/app/assets/stylesheets/naf/layout.css.scss +497 -0
- data/app/controllers/naf/affinities_controller.rb +61 -0
- data/app/controllers/naf/application_controller.rb +43 -0
- data/app/controllers/naf/application_schedule_affinity_tabs_controller.rb +75 -0
- data/app/controllers/naf/applications_controller.rb +153 -0
- data/app/controllers/naf/historical_job_affinity_tabs_controller.rb +65 -0
- data/app/controllers/naf/historical_jobs_controller.rb +159 -0
- data/app/controllers/naf/janitorial_assignments_controller.rb +77 -0
- data/app/controllers/naf/logger_names_controller.rb +58 -0
- data/app/controllers/naf/logger_styles_controller.rb +59 -0
- data/app/controllers/naf/machine_affinity_slots_controller.rb +69 -0
- data/app/controllers/naf/machine_runner_invocations_controller.rb +59 -0
- data/app/controllers/naf/machine_runners_controller.rb +26 -0
- data/app/controllers/naf/machines_controller.rb +95 -0
- data/app/helpers/naf/application_helper.rb +275 -0
- data/app/models/log4r/papertrail_outputter.rb +19 -0
- data/app/models/logical/naf/application.rb +183 -0
- data/app/models/logical/naf/construction_zone/ad_hoc_work_order.rb +22 -0
- data/app/models/logical/naf/construction_zone/application_schedule_work_order.rb +15 -0
- data/app/models/logical/naf/construction_zone/application_work_order.rb +25 -0
- data/app/models/logical/naf/construction_zone/boss.rb +123 -0
- data/app/models/logical/naf/construction_zone/foreman.rb +53 -0
- data/app/models/logical/naf/construction_zone/proletariat.rb +40 -0
- data/app/models/logical/naf/construction_zone/work_order.rb +100 -0
- data/app/models/logical/naf/create_infrastructure.rb +48 -0
- data/app/models/logical/naf/job.rb +357 -0
- data/app/models/logical/naf/job_creator.rb +155 -0
- data/app/models/logical/naf/job_fetcher.rb +167 -0
- data/app/models/logical/naf/job_statuses/errored.rb +27 -0
- data/app/models/logical/naf/job_statuses/finished.rb +26 -0
- data/app/models/logical/naf/job_statuses/finished_less_minute.rb +25 -0
- data/app/models/logical/naf/job_statuses/queued.rb +32 -0
- data/app/models/logical/naf/job_statuses/running.rb +34 -0
- data/app/models/logical/naf/job_statuses/terminated.rb +25 -0
- data/app/models/logical/naf/job_statuses/waiting.rb +43 -0
- data/app/models/logical/naf/machine.rb +85 -0
- data/app/models/logical/naf/machine_runner.rb +46 -0
- data/app/models/logical/naf/machine_runner_invocation.rb +50 -0
- data/app/models/logical/naf/pickler.rb +74 -0
- data/app/models/logical/naf/unpickler.rb +98 -0
- data/app/models/naf/affinity.rb +145 -0
- data/app/models/naf/affinity_classification.rb +44 -0
- data/app/models/naf/application.rb +100 -0
- data/app/models/naf/application_run_group_restriction.rb +39 -0
- data/app/models/naf/application_schedule.rb +181 -0
- data/app/models/naf/application_schedule_affinity_tab.rb +86 -0
- data/app/models/naf/application_schedule_prerequisite.rb +50 -0
- data/app/models/naf/application_type.rb +72 -0
- data/app/models/naf/by_historical_job_id.rb +86 -0
- data/app/models/naf/historical_job.rb +334 -0
- data/app/models/naf/historical_job_affinity_tab.rb +61 -0
- data/app/models/naf/historical_job_prerequisite.rb +19 -0
- data/app/models/naf/janitorial_archive_assignment.rb +36 -0
- data/app/models/naf/janitorial_assignment.rb +37 -0
- data/app/models/naf/janitorial_create_assignment.rb +36 -0
- data/app/models/naf/janitorial_drop_assignment.rb +36 -0
- data/app/models/naf/logger_level.rb +21 -0
- data/app/models/naf/logger_name.rb +23 -0
- data/app/models/naf/logger_style.rb +58 -0
- data/app/models/naf/logger_style_name.rb +28 -0
- data/app/models/naf/machine.rb +257 -0
- data/app/models/naf/machine_affinity_slot.rb +78 -0
- data/app/models/naf/machine_runner.rb +51 -0
- data/app/models/naf/machine_runner_invocation.rb +71 -0
- data/app/models/naf/naf_base.rb +9 -0
- data/app/models/naf/queued_job.rb +164 -0
- data/app/models/naf/running_job.rb +80 -0
- data/app/models/process/naf/application.rb +164 -0
- data/app/models/process/naf/janitor.rb +117 -0
- data/app/models/process/naf/machine_manager.rb +150 -0
- data/app/models/process/naf/machine_upgrader.rb +112 -0
- data/app/models/process/naf/runner.rb +539 -0
- data/app/views/naf/affinities/_form.html.erb +50 -0
- data/app/views/naf/affinities/edit.html.erb +11 -0
- data/app/views/naf/affinities/index.html.erb +57 -0
- data/app/views/naf/affinities/new.html.erb +15 -0
- data/app/views/naf/affinities/show.html.erb +48 -0
- data/app/views/naf/application_schedule_affinity_tabs/_form.html.erb +31 -0
- data/app/views/naf/application_schedule_affinity_tabs/edit.html.erb +12 -0
- data/app/views/naf/application_schedule_affinity_tabs/new.html.erb +11 -0
- data/app/views/naf/applications/_application_schedule.html.erb +80 -0
- data/app/views/naf/applications/_application_schedule_prerequisites.html.erb +14 -0
- data/app/views/naf/applications/_form.html.erb +109 -0
- data/app/views/naf/applications/_search_container.html.erb +94 -0
- data/app/views/naf/applications/_show.html.erb +34 -0
- data/app/views/naf/applications/edit.html.erb +11 -0
- data/app/views/naf/applications/index.html.erb +51 -0
- data/app/views/naf/applications/index.json.erb +11 -0
- data/app/views/naf/applications/new.html.erb +11 -0
- data/app/views/naf/applications/show.html.erb +203 -0
- data/app/views/naf/datatable.html.erb +49 -0
- data/app/views/naf/historical_job_affinity_tabs/_form.html.erb +36 -0
- data/app/views/naf/historical_job_affinity_tabs/edit.html.erb +11 -0
- data/app/views/naf/historical_job_affinity_tabs/new.html.erb +11 -0
- data/app/views/naf/historical_jobs/_form.html.erb +94 -0
- data/app/views/naf/historical_jobs/_runners.html.erb +22 -0
- data/app/views/naf/historical_jobs/_search_container.html.erb +140 -0
- data/app/views/naf/historical_jobs/edit.html.erb +11 -0
- data/app/views/naf/historical_jobs/index.html.erb +48 -0
- data/app/views/naf/historical_jobs/index.json.erb +26 -0
- data/app/views/naf/historical_jobs/new.html.erb +61 -0
- data/app/views/naf/historical_jobs/show.html.erb +201 -0
- data/app/views/naf/janitorial_assignments/_form.html.erb +38 -0
- data/app/views/naf/janitorial_assignments/_rows.html.erb +17 -0
- data/app/views/naf/janitorial_assignments/edit.html.erb +11 -0
- data/app/views/naf/janitorial_assignments/index.html.erb +56 -0
- data/app/views/naf/janitorial_assignments/index.js.erb +1 -0
- data/app/views/naf/janitorial_assignments/new.html.erb +11 -0
- data/app/views/naf/layouts/jquery_datatables.json.erb +6 -0
- data/app/views/naf/logger_names/_form.html.erb +18 -0
- data/app/views/naf/logger_names/edit.html.erb +11 -0
- data/app/views/naf/logger_names/new.html.erb +11 -0
- data/app/views/naf/logger_names/show.html.erb +44 -0
- data/app/views/naf/logger_styles/_form.html.erb +30 -0
- data/app/views/naf/logger_styles/_logger_style_names.html.erb +19 -0
- data/app/views/naf/logger_styles/edit.html.erb +11 -0
- data/app/views/naf/logger_styles/new.html.erb +11 -0
- data/app/views/naf/logger_styles/show.html.erb +48 -0
- data/app/views/naf/machine_affinity_slots/_form.html.erb +36 -0
- data/app/views/naf/machine_affinity_slots/edit.html.erb +11 -0
- data/app/views/naf/machine_affinity_slots/new.html.erb +11 -0
- data/app/views/naf/machine_runner_invocations/_filter.html.erb +21 -0
- data/app/views/naf/machine_runner_invocations/index.html.erb +36 -0
- data/app/views/naf/machine_runner_invocations/index.json.erb +16 -0
- data/app/views/naf/machine_runner_invocations/show.html.erb +91 -0
- data/app/views/naf/machine_runners/index.html.erb +82 -0
- data/app/views/naf/machine_runners/index.json.erb +16 -0
- data/app/views/naf/machine_runners/show.html.erb +113 -0
- data/app/views/naf/machines/_filter.html.erb +26 -0
- data/app/views/naf/machines/_form.html.erb +62 -0
- data/app/views/naf/machines/_show.html.erb +169 -0
- data/app/views/naf/machines/edit.html.erb +11 -0
- data/app/views/naf/machines/index.html.erb +51 -0
- data/app/views/naf/machines/index.json.erb +23 -0
- data/app/views/naf/machines/new.html.erb +11 -0
- data/app/views/naf/machines/show.html.erb +92 -0
- data/app/views/naf/record.html.erb +46 -0
- data/app/views/naf/shared/_application.html.erb +50 -0
- data/app/views/naf/shared/_information_container.html.erb +19 -0
- data/app/views/naf/shared/_select_per_page.html.erb +72 -0
- data/ci/test-build.sh +17 -0
- data/ci/travis.sh +26 -0
- data/config/initializers/naf.rb +3 -0
- data/config/routes.rb +38 -0
- data/db/migrate/20120820023848_naf_schema.rb +413 -0
- data/doc/README_FOR_APP +2 -0
- data/lib/generators/naf_generator.rb +45 -0
- data/lib/generators/templates/config/logging/af.yml +26 -0
- data/lib/generators/templates/config/logging/naf.yml +22 -0
- data/lib/generators/templates/config/logging/nafjob.yml +16 -0
- data/lib/generators/templates/config/logging/nafrunner.yml +17 -0
- data/lib/generators/templates/naf.rb +11 -0
- data/lib/generators/templates/naf_layout.html.erb +15 -0
- data/lib/naf.rb +48 -0
- data/lib/naf/configuration.rb +23 -0
- data/lib/naf/engine.rb +18 -0
- data/lib/naf/version.rb +3 -0
- data/lib/tasks/naf_tasks.rake +370 -0
- data/naf.gemspec +30 -0
- data/script/rails +10 -0
- data/spec/controllers/naf/affinities_controller_spec.rb +79 -0
- data/spec/controllers/naf/application_controller_spec.rb +10 -0
- data/spec/controllers/naf/application_schedule_affinity_tabs_controller_spec.rb +106 -0
- data/spec/controllers/naf/applications_controller_spec.rb +109 -0
- data/spec/controllers/naf/historical_job_affinity_tabs_controller_spec.rb +96 -0
- data/spec/controllers/naf/historical_jobs_controller_spec.rb +19 -0
- data/spec/controllers/naf/machine_affinity_slots_controller_spec.rb +109 -0
- data/spec/controllers/naf/machines_controller_spec.rb +74 -0
- data/spec/dummy/.gitignore +12 -0
- data/spec/dummy/README +19 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/assets/javascripts/application.js +16 -0
- data/spec/dummy/app/assets/stylesheets/application.css +14 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/models/my_script.rb +8 -0
- data/spec/dummy/app/models/other/base.rb.sample +10 -0
- data/spec/dummy/app/views/layouts/application.html.erb +15 -0
- data/spec/dummy/app/views/layouts/naf_layout.html.erb +15 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +62 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database-non_primary.yml +20 -0
- data/spec/dummy/config/database-primary.yml +16 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +37 -0
- data/spec/dummy/config/environments/production.rb +67 -0
- data/spec/dummy/config/environments/test.rb +37 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/inflections.rb +15 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/naf.rb.non_primary +4 -0
- data/spec/dummy/config/initializers/naf.rb.primary +3 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/logging/af.yml +26 -0
- data/spec/dummy/config/logging/naf.yml +22 -0
- data/spec/dummy/config/logging/nafjob.yml +16 -0
- data/spec/dummy/config/logging/nafrunner.yml +17 -0
- data/spec/dummy/config/routes.rb +5 -0
- data/spec/dummy/db/.gitignore +2 -0
- data/spec/dummy/lib/tasks/dummy.rake +60 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +25 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/factories/naf.rb +433 -0
- data/spec/helpers/naf/application_helper_spec.rb +0 -0
- data/spec/models/logical/naf/application_spec.rb +69 -0
- data/spec/models/logical/naf/job_creator_spec.rb +32 -0
- data/spec/models/logical/naf/job_fetcher_spec.rb +140 -0
- data/spec/models/logical/naf/job_spec.rb +282 -0
- data/spec/models/logical/naf/machine_spec.rb +61 -0
- data/spec/models/naf/affinity_classification_spec.rb +56 -0
- data/spec/models/naf/affinity_spec.rb +100 -0
- data/spec/models/naf/application_run_group_restriction_spec.rb +57 -0
- data/spec/models/naf/application_schedule_affinity_tab_spec.rb +85 -0
- data/spec/models/naf/application_schedule_prerequisite_spec.rb +35 -0
- data/spec/models/naf/application_schedule_spec.rb +166 -0
- data/spec/models/naf/application_spec.rb +128 -0
- data/spec/models/naf/application_type_spec.rb +104 -0
- data/spec/models/naf/historical_job_affinity_tab_spec.rb +59 -0
- data/spec/models/naf/historical_job_prerequisite_spec.rb +25 -0
- data/spec/models/naf/historical_job_spec.rb +334 -0
- data/spec/models/naf/logger_level_spec.rb +34 -0
- data/spec/models/naf/logger_name_spec.rb +35 -0
- data/spec/models/naf/logger_style_name_spec.rb +39 -0
- data/spec/models/naf/logger_style_spec.rb +89 -0
- data/spec/models/naf/machine_affinity_slot_spec.rb +77 -0
- data/spec/models/naf/machine_runner_invocation_spec.rb +38 -0
- data/spec/models/naf/machine_runner_spec.rb +37 -0
- data/spec/models/naf/machine_spec.rb +425 -0
- data/spec/models/naf/naf_base_spec.rb +14 -0
- data/spec/models/naf/queued_job_spec.rb +171 -0
- data/spec/models/naf/running_job_spec.rb +107 -0
- data/spec/models/process/naf/application_spec.rb +8 -0
- data/spec/models/process/naf/janitor_spec.rb +10 -0
- data/spec/models/process/naf/runner_spec.rb +10 -0
- data/spec/spec_helper.rb +32 -0
- data/spec/support/engine_routing.rb +27 -0
- data/spec/support/script_spec_helper.rb +58 -0
- metadata +590 -0
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
module Logical
|
|
2
|
+
module Naf
|
|
3
|
+
class JobCreator
|
|
4
|
+
def queue_application(application,
|
|
5
|
+
application_run_group_restriction,
|
|
6
|
+
application_run_group_name,
|
|
7
|
+
application_run_group_limit = 1,
|
|
8
|
+
priority = 0,
|
|
9
|
+
affinities = [],
|
|
10
|
+
prerequisites = [],
|
|
11
|
+
enqueue = false)
|
|
12
|
+
|
|
13
|
+
# Before adding a job to the queue, check whether the number of
|
|
14
|
+
# jobs (running/queued) is equal to or greater than the application
|
|
15
|
+
# run group limit, or if enqueue_backlogs is set to false. If so,
|
|
16
|
+
# do not add the job to the queue
|
|
17
|
+
running_jobs = ::Naf::RunningJob.
|
|
18
|
+
select('application_run_group_limit, MAX(created_at) AS created_at, count(*)').
|
|
19
|
+
where('command = ? AND application_run_group_name = ?',
|
|
20
|
+
application.command, application_run_group_name).
|
|
21
|
+
group('application_run_group_name, application_run_group_limit').first
|
|
22
|
+
|
|
23
|
+
queued_jobs = ::Naf::QueuedJob.
|
|
24
|
+
select('application_run_group_limit, MAX(created_at) AS created_at, count(*)').
|
|
25
|
+
where('command = ? AND application_run_group_name = ?',
|
|
26
|
+
application.command, application_run_group_name).
|
|
27
|
+
group('application_run_group_name, application_run_group_limit').first
|
|
28
|
+
|
|
29
|
+
if enqueue == false && (running_jobs.present? || queued_jobs.present?)
|
|
30
|
+
group_limit = running_jobs.try(:application_run_group_limit).to_i + queued_jobs.try(:application_run_group_limit).to_i
|
|
31
|
+
total_jobs = running_jobs.try(:count).to_i + queued_jobs.try(:count).to_i
|
|
32
|
+
|
|
33
|
+
return if group_limit <= total_jobs
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
::Naf::HistoricalJob.transaction do
|
|
37
|
+
historical_job = ::Naf::HistoricalJob.create!(application_id: application.id,
|
|
38
|
+
application_type_id: application.application_type_id,
|
|
39
|
+
command: application.command,
|
|
40
|
+
application_run_group_restriction_id: application_run_group_restriction.id,
|
|
41
|
+
application_run_group_name: application_run_group_name,
|
|
42
|
+
application_run_group_limit: application_run_group_limit,
|
|
43
|
+
priority: priority,
|
|
44
|
+
log_level: application.log_level)
|
|
45
|
+
historical_job.add_tags([::Naf::HistoricalJob::SYSTEM_TAGS[:pre_work]])
|
|
46
|
+
|
|
47
|
+
# Create historical job affinity tabs for each affinity associated with the historical job
|
|
48
|
+
affinities.each do |affinity|
|
|
49
|
+
affinity_parameter = ::Naf::ApplicationScheduleAffinityTab.
|
|
50
|
+
where(affinity_id: affinity.id,
|
|
51
|
+
application_schedule_id: application.application_schedule.try(:id)).
|
|
52
|
+
first.try(:affinity_parameter)
|
|
53
|
+
::Naf::HistoricalJobAffinityTab.create(historical_job_id: historical_job.id,
|
|
54
|
+
affinity_id: affinity.id,
|
|
55
|
+
affinity_parameter: affinity_parameter)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
historical_job.verify_prerequisites(prerequisites)
|
|
59
|
+
# Create historical job prerequisites for each prerequisite associated with the historical job
|
|
60
|
+
prerequisites.each do |prerequisite|
|
|
61
|
+
::Naf::HistoricalJobPrerequisite.create(historical_job_id: historical_job.id,
|
|
62
|
+
prerequisite_historical_job_id: prerequisite.id)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
create_queue_job(historical_job)
|
|
66
|
+
|
|
67
|
+
return historical_job
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def queue_application_schedule(application_schedule, schedules_queued_already = [])
|
|
72
|
+
prerequisite_jobs = []
|
|
73
|
+
|
|
74
|
+
# Check if schedule has been queued
|
|
75
|
+
if schedules_queued_already.include? application_schedule.id
|
|
76
|
+
raise ::Naf::HistoricalJob::JobPrerequisiteLoop.new(application_schedule)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Keep track of queued schedules
|
|
80
|
+
schedules_queued_already << application_schedule.id
|
|
81
|
+
# Queue application schedule prerequisites
|
|
82
|
+
application_schedule.prerequisites.each do |application_schedule_prerequisite|
|
|
83
|
+
prerequisite_jobs << queue_application_schedule(application_schedule_prerequisite, schedules_queued_already)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# Queue the application
|
|
87
|
+
return queue_application(application_schedule.application,
|
|
88
|
+
application_schedule.application_run_group_restriction,
|
|
89
|
+
application_schedule.application_run_group_name,
|
|
90
|
+
application_schedule.application_run_group_limit,
|
|
91
|
+
application_schedule.priority,
|
|
92
|
+
application_schedule.affinities,
|
|
93
|
+
prerequisite_jobs,
|
|
94
|
+
application_schedule.enqueue_backlogs)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# This method act similar to queue_application but is used for testing purpose
|
|
98
|
+
def queue_rails_job(command,
|
|
99
|
+
application_run_group_restriction = ::Naf::ApplicationRunGroupRestriction.limited_per_all_machines,
|
|
100
|
+
application_run_group_name = :command,
|
|
101
|
+
application_run_group_limit = 1,
|
|
102
|
+
priority = 0,
|
|
103
|
+
affinities = [],
|
|
104
|
+
prerequisites = [])
|
|
105
|
+
application_run_group_name = command if application_run_group_name == :command
|
|
106
|
+
::Naf::HistoricalJob.transaction do
|
|
107
|
+
historical_job = ::Naf::HistoricalJob.create!(application_type_id: 1,
|
|
108
|
+
command: command,
|
|
109
|
+
application_run_group_restriction_id: application_run_group_restriction.id,
|
|
110
|
+
application_run_group_name: application_run_group_name,
|
|
111
|
+
application_run_group_limit: application_run_group_limit,
|
|
112
|
+
priority: priority)
|
|
113
|
+
affinities.each do |affinity|
|
|
114
|
+
::Naf::HistoricalJobAffinityTab.create(historical_job_id: historical_job.id, affinity_id: affinity.id)
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
historical_job.verify_prerequisites(prerequisites)
|
|
118
|
+
prerequisites.each do |prerequisite|
|
|
119
|
+
::Naf::HistoricalJobPrerequisite.create(historical_job_id: historical_job.id,
|
|
120
|
+
prerequisite_historical_job_id: prerequisite.id)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
create_queue_job(historical_job)
|
|
124
|
+
|
|
125
|
+
return historical_job
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def create_queue_job(historical_job)
|
|
130
|
+
queued_job = ::Naf::QueuedJob.new(application_id: historical_job.application_id,
|
|
131
|
+
application_type_id: historical_job.application_type_id,
|
|
132
|
+
command: historical_job.command,
|
|
133
|
+
application_run_group_restriction_id: historical_job.application_run_group_restriction_id,
|
|
134
|
+
application_run_group_name: historical_job.application_run_group_name,
|
|
135
|
+
application_run_group_limit: historical_job.application_run_group_limit,
|
|
136
|
+
priority: historical_job.priority)
|
|
137
|
+
queued_job.id = historical_job.id
|
|
138
|
+
queued_job.save!
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def queue_test
|
|
142
|
+
queue_rails_job("#{self.class.name}.test")
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def self.test(*foo)
|
|
146
|
+
seconds = rand 120 + 15
|
|
147
|
+
puts "TEST CALLED: #{Time.zone.now}: #{foo.inspect}: sleeping for #{seconds} seconds"
|
|
148
|
+
sleep(seconds)
|
|
149
|
+
puts "TEST DONE: #{Time.zone.now}: #{foo.inspect}"
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
MiddleClass = JobCreator
|
|
154
|
+
end
|
|
155
|
+
end
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
module Logical
|
|
2
|
+
module Naf
|
|
3
|
+
class JobFetcher
|
|
4
|
+
include ::Af::Application::SafeProxy
|
|
5
|
+
|
|
6
|
+
attr_reader :machine
|
|
7
|
+
|
|
8
|
+
def initialize(machine)
|
|
9
|
+
@machine = machine
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def fetch_next_job
|
|
13
|
+
fetch_possible_jobs.each do |possible_job|
|
|
14
|
+
running_job = nil
|
|
15
|
+
::Naf::HistoricalJob.lock_for_job_queue do
|
|
16
|
+
running_job = start_job(possible_job)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
if running_job.present?
|
|
20
|
+
# Update tags
|
|
21
|
+
running_job.historical_job.remove_tags([::Naf::HistoricalJob::SYSTEM_TAGS[:pre_work]])
|
|
22
|
+
running_job.historical_job.add_tags([::Naf::HistoricalJob::SYSTEM_TAGS[:work]])
|
|
23
|
+
|
|
24
|
+
# found a job
|
|
25
|
+
parse_log_level(running_job)
|
|
26
|
+
|
|
27
|
+
return running_job
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# no jobs found
|
|
32
|
+
return nil
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
private
|
|
36
|
+
|
|
37
|
+
# This method fetches queued jobs that can be started. In order for a job to
|
|
38
|
+
# run on a machine, we need to check affinities for historical_job_affinity_tabs
|
|
39
|
+
# and machine_affinity_slots.
|
|
40
|
+
#
|
|
41
|
+
# A job without affinity tabs can be run on any machine
|
|
42
|
+
# A job with affinity tabs can only run on machines:
|
|
43
|
+
# - that have matching affinity slot(s)
|
|
44
|
+
#
|
|
45
|
+
# A machine with non-required affinity slots can run jobs:
|
|
46
|
+
# - that don't have any affinity tabs
|
|
47
|
+
# - that have affinity tab(s) that match affinity slot(s)
|
|
48
|
+
# A machine with required affinity slots can run jobs:
|
|
49
|
+
# - that have affinity tab(s) that match the required affinity slot(s)
|
|
50
|
+
# and if other affinity tabs are present, they also need to match
|
|
51
|
+
# afffinity slots
|
|
52
|
+
#
|
|
53
|
+
def fetch_possible_jobs
|
|
54
|
+
possible_jobs = nil
|
|
55
|
+
if machine.machine_affinity_slots.select(&:required).present?
|
|
56
|
+
# Retrieve the machine's required affinities in order to not
|
|
57
|
+
# compute it several times.
|
|
58
|
+
required_machine_affinities = ::Naf::Machine.
|
|
59
|
+
select("ARRAY(
|
|
60
|
+
SELECT affinity_id
|
|
61
|
+
FROM #{::Naf.schema_name}.machine_affinity_slots
|
|
62
|
+
WHERE machine_id = #{machine.id} AND required = true
|
|
63
|
+
ORDER BY affinity_id) AS required_affinities").
|
|
64
|
+
group("required_affinities").
|
|
65
|
+
first.required_affinities
|
|
66
|
+
|
|
67
|
+
# Choose queued jobs that can be run by the machine
|
|
68
|
+
possible_jobs = ::Naf::QueuedJob.
|
|
69
|
+
select("#{::Naf.schema_name}.queued_jobs.id, #{::Naf.schema_name}.queued_jobs.priority, #{::Naf.schema_name}.queued_jobs.created_at").
|
|
70
|
+
weight_available_on_machine(machine).
|
|
71
|
+
runnable_by_machine(machine).
|
|
72
|
+
is_not_restricted_by_run_group(machine).
|
|
73
|
+
prerequisites_finished.
|
|
74
|
+
group("#{::Naf.schema_name}.queued_jobs.id, #{::Naf.schema_name}.queued_jobs.priority, #{::Naf.schema_name}.queued_jobs.created_at").
|
|
75
|
+
having("array(
|
|
76
|
+
select affinity_id::integer
|
|
77
|
+
from #{::Naf.schema_name}.historical_job_affinity_tabs
|
|
78
|
+
where historical_job_id = queued_jobs.id and affinity_id in (
|
|
79
|
+
select affinity_id
|
|
80
|
+
from #{::Naf.schema_name}.machine_affinity_slots
|
|
81
|
+
where machine_id = #{machine.id} and required = true)
|
|
82
|
+
order by affinity_id) = '#{required_machine_affinities}'").
|
|
83
|
+
order_by_priority.
|
|
84
|
+
limit(100)
|
|
85
|
+
elsif machine.machine_affinity_slots.present?
|
|
86
|
+
# Choose queued jobs that can be run by the machine
|
|
87
|
+
possible_jobs = ::Naf::QueuedJob.
|
|
88
|
+
weight_available_on_machine(machine).
|
|
89
|
+
runnable_by_machine(machine).
|
|
90
|
+
is_not_restricted_by_run_group(machine).
|
|
91
|
+
prerequisites_finished.
|
|
92
|
+
order_by_priority.limit(100)
|
|
93
|
+
else
|
|
94
|
+
# Machine can run any queued job
|
|
95
|
+
possible_jobs = ::Naf::QueuedJob.
|
|
96
|
+
weight_available_on_machine(machine).
|
|
97
|
+
is_not_restricted_by_run_group(machine).
|
|
98
|
+
prerequisites_finished.
|
|
99
|
+
order_by_priority.limit(100)
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def start_job(possible_job)
|
|
104
|
+
sql = <<-SQL
|
|
105
|
+
UPDATE
|
|
106
|
+
#{::Naf::HistoricalJob.partition_table_name(possible_job.id)}
|
|
107
|
+
SET
|
|
108
|
+
started_at = NOW(),
|
|
109
|
+
started_on_machine_id = ?
|
|
110
|
+
WHERE
|
|
111
|
+
id = ? AND started_at IS NULL
|
|
112
|
+
RETURNING
|
|
113
|
+
*
|
|
114
|
+
SQL
|
|
115
|
+
|
|
116
|
+
historical_job = ::Naf::HistoricalJob.find_by_sql([sql, machine.id, possible_job.id]).first
|
|
117
|
+
if historical_job.present?
|
|
118
|
+
::Naf::QueuedJob.delete(historical_job.id)
|
|
119
|
+
running_job = ::Naf::RunningJob.new(application_id: historical_job.application_id,
|
|
120
|
+
application_type_id: historical_job.application_type_id,
|
|
121
|
+
command: historical_job.command,
|
|
122
|
+
application_run_group_restriction_id: historical_job.application_run_group_restriction_id,
|
|
123
|
+
application_run_group_name: historical_job.application_run_group_name,
|
|
124
|
+
application_run_group_limit: historical_job.application_run_group_limit,
|
|
125
|
+
started_on_machine_id: historical_job.started_on_machine_id,
|
|
126
|
+
started_at: historical_job.started_at,
|
|
127
|
+
log_level: historical_job.log_level)
|
|
128
|
+
running_job.id = historical_job.id
|
|
129
|
+
running_job.save!
|
|
130
|
+
|
|
131
|
+
running_job
|
|
132
|
+
else
|
|
133
|
+
nil
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def logger
|
|
138
|
+
return af_logger(self.class.name)
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def parse_log_level(running_job)
|
|
142
|
+
log_levels = {}
|
|
143
|
+
unless machine.log_level.blank?
|
|
144
|
+
begin
|
|
145
|
+
log_level_hash = JSON.parse(machine.log_level)
|
|
146
|
+
log_levels.merge!(log_level_hash)
|
|
147
|
+
rescue StandardError => e
|
|
148
|
+
logger.error "couldn't parse machine.log_level: #{machine.log_level}: (#{e.message})"
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
unless running_job.application.nil? || running_job.application.log_level.blank?
|
|
153
|
+
begin
|
|
154
|
+
log_level_hash = JSON.parse(running_job.application.log_level)
|
|
155
|
+
log_levels.merge!(log_level_hash)
|
|
156
|
+
rescue StandardError => e
|
|
157
|
+
logger.error "couldn't parse running_job.application.log_level: #{running_job.application.log_level}: (#{e.message})"
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
running_job.log_level = log_levels.to_json
|
|
162
|
+
running_job.save!
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module Logical
|
|
2
|
+
module Naf
|
|
3
|
+
module JobStatuses
|
|
4
|
+
class Errored
|
|
5
|
+
|
|
6
|
+
def self.all(conditions)
|
|
7
|
+
<<-SQL
|
|
8
|
+
(
|
|
9
|
+
SELECT
|
|
10
|
+
j.*, null AS "historical_job_id"
|
|
11
|
+
FROM
|
|
12
|
+
"#{::Naf.schema_name}"."historical_jobs" AS j
|
|
13
|
+
WHERE
|
|
14
|
+
j.finished_at IS NOT NULL AND
|
|
15
|
+
(j.exit_status > 0 OR
|
|
16
|
+
j.request_to_terminate = true)
|
|
17
|
+
#{conditions}
|
|
18
|
+
ORDER BY
|
|
19
|
+
finished_at desc
|
|
20
|
+
)
|
|
21
|
+
SQL
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module Logical
|
|
2
|
+
module Naf
|
|
3
|
+
module JobStatuses
|
|
4
|
+
class Finished
|
|
5
|
+
|
|
6
|
+
def self.all(conditions)
|
|
7
|
+
<<-SQL
|
|
8
|
+
(
|
|
9
|
+
SELECT
|
|
10
|
+
j.*, null AS "historical_job_id"
|
|
11
|
+
FROM
|
|
12
|
+
"#{::Naf.schema_name}"."historical_jobs" AS j
|
|
13
|
+
WHERE
|
|
14
|
+
(j.finished_at IS NOT NULL OR
|
|
15
|
+
j.request_to_terminate = true)
|
|
16
|
+
#{conditions}
|
|
17
|
+
ORDER BY
|
|
18
|
+
finished_at DESC NULLS LAST
|
|
19
|
+
)
|
|
20
|
+
SQL
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module Logical
|
|
2
|
+
module Naf
|
|
3
|
+
module JobStatuses
|
|
4
|
+
class FinishedLessMinute
|
|
5
|
+
|
|
6
|
+
def self.all(conditions)
|
|
7
|
+
<<-SQL
|
|
8
|
+
(
|
|
9
|
+
SELECT
|
|
10
|
+
j.*, NULL AS "historical_job_id"
|
|
11
|
+
FROM
|
|
12
|
+
"#{::Naf.schema_name}"."historical_jobs" AS j
|
|
13
|
+
WHERE
|
|
14
|
+
j.finished_at > '#{Time.zone.now - 1.minute}'
|
|
15
|
+
#{conditions}
|
|
16
|
+
ORDER BY
|
|
17
|
+
finished_at DESC
|
|
18
|
+
)
|
|
19
|
+
SQL
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
module Logical
|
|
2
|
+
module Naf
|
|
3
|
+
module JobStatuses
|
|
4
|
+
class Queued
|
|
5
|
+
|
|
6
|
+
def self.all(conditions)
|
|
7
|
+
<<-SQL
|
|
8
|
+
(
|
|
9
|
+
SELECT DISTINCT
|
|
10
|
+
j.*, jp."historical_job_id"
|
|
11
|
+
FROM
|
|
12
|
+
"#{::Naf.schema_name}"."historical_jobs" AS j
|
|
13
|
+
LEFT JOIN
|
|
14
|
+
"#{::Naf.schema_name}"."historical_job_prerequisites" AS jp
|
|
15
|
+
ON j."id" = jp."historical_job_id"
|
|
16
|
+
WHERE
|
|
17
|
+
j.finished_at IS NULL AND
|
|
18
|
+
j.request_to_terminate = false AND
|
|
19
|
+
jp.historical_job_id IS NULL AND
|
|
20
|
+
j.started_at IS NULL
|
|
21
|
+
#{conditions}
|
|
22
|
+
ORDER BY
|
|
23
|
+
created_at desc
|
|
24
|
+
)
|
|
25
|
+
SQL
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
module Logical
|
|
2
|
+
module Naf
|
|
3
|
+
module JobStatuses
|
|
4
|
+
class Running
|
|
5
|
+
|
|
6
|
+
def self.all(status = :running, conditions)
|
|
7
|
+
if status == :queued
|
|
8
|
+
order = "created_at"
|
|
9
|
+
direction = "desc"
|
|
10
|
+
else
|
|
11
|
+
order = "started_at"
|
|
12
|
+
direction = "desc"
|
|
13
|
+
end
|
|
14
|
+
<<-SQL
|
|
15
|
+
(
|
|
16
|
+
SELECT
|
|
17
|
+
j.*, null AS "historical_job_id"
|
|
18
|
+
FROM
|
|
19
|
+
"#{::Naf.schema_name}"."historical_jobs" AS j
|
|
20
|
+
WHERE
|
|
21
|
+
j.started_at IS NOT NULL AND
|
|
22
|
+
j.finished_at IS NULL AND
|
|
23
|
+
j.request_to_terminate = false
|
|
24
|
+
#{conditions}
|
|
25
|
+
ORDER BY
|
|
26
|
+
#{order} #{direction}
|
|
27
|
+
)
|
|
28
|
+
SQL
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|