patriot-workflow-scheduler 0.7.2 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/lib/patriot.rb +1 -0
- data/lib/patriot/command.rb +11 -11
- data/lib/patriot/command/base.rb +3 -3
- data/lib/patriot/command/composite.rb +20 -6
- data/lib/patriot/command/post_processor.rb +2 -2
- data/lib/patriot/command/post_processor/base.rb +3 -2
- data/lib/patriot/command/post_processor/mail_notification.rb +3 -3
- data/lib/patriot/command/post_processor/retrial.rb +3 -3
- data/lib/patriot/command/sh_command.rb +14 -0
- data/lib/patriot/controller/worker_admin_controller.rb +13 -8
- data/lib/patriot/job_store/base.rb +16 -7
- data/lib/patriot/job_store/in_memory_store.rb +121 -29
- data/lib/patriot/job_store/job.rb +7 -7
- data/lib/patriot/job_store/job_ticket.rb +1 -0
- data/lib/patriot/job_store/rdb_job_store.rb +161 -54
- data/lib/patriot/tool/patriot_commands/execute.rb +1 -1
- data/lib/patriot/tool/patriot_commands/job.rb +6 -4
- data/lib/patriot/tool/patriot_commands/register.rb +7 -5
- data/lib/patriot/util/config.rb +14 -3
- data/lib/patriot/util/config/inifile_config.rb +1 -1
- data/lib/patriot/version.rb +3 -0
- data/lib/patriot/worker/base.rb +6 -3
- data/lib/patriot/worker/info_server.rb +34 -24
- data/lib/patriot/worker/servlet.rb +4 -8
- data/lib/patriot/worker/servlet/api_servlet_base.rb +40 -0
- data/lib/patriot/worker/servlet/index_servlet.rb +32 -0
- data/lib/patriot/worker/servlet/job_api_servlet.rb +156 -0
- data/lib/patriot/worker/servlet/worker_api_servlet.rb +67 -0
- data/skel/batch/sample/daily/test.pbc +1 -1
- data/skel/public/css/bootstrap.min.css +7412 -0
- data/skel/public/css/original.css +179 -54
- data/skel/public/js/patriot-workflow-scheduler-0.8.0.js +82252 -0
- data/skel/public/js/patriot-workflow-scheduler-0.8.0.min.js +26 -0
- data/skel/public/js/patriot-workflow-scheduler-0.8.0.min.js.map +1 -0
- data/skel/public/templates/_jobs.erb +4 -5
- data/skel/public/templates/job.erb +2 -4
- data/skel/public/templates/layout.erb +10 -10
- data/skel/public/views/index.erb +13 -0
- metadata +40 -4
- data/lib/patriot/worker/servlet/job_servlet.rb +0 -128
- data/lib/patriot/worker/servlet/worker_status_servlet.rb +0 -52
data/lib/patriot/util/config.rb
CHANGED
@@ -14,20 +14,31 @@ module Patriot
|
|
14
14
|
# default plugins directory
|
15
15
|
DEFAULT_PLUGIN_DIR = "plugins"
|
16
16
|
# plugin directory
|
17
|
-
PLUGIN_LIB_DIR = 'lib'
|
17
|
+
PLUGIN_LIB_DIR = 'lib'
|
18
18
|
# plugin initiation script
|
19
19
|
PLUGIN_INIT_SCRIPT = 'init.rb'
|
20
20
|
# admin user mail address
|
21
21
|
ADMIN_USER_KEY = 'admin_user'
|
22
22
|
|
23
|
+
# a comma separated list of hosts where workers are running
|
24
|
+
WORKER_HOST_KEY = 'worker_hosts'
|
25
|
+
# port number used by info server
|
26
|
+
INFO_SERVER_PORT_KEY = 'info_server_port'
|
27
|
+
|
28
|
+
# configuratio key for admin user name
|
29
|
+
USERNAME_KEY = 'info_server.admin.username'
|
30
|
+
# configuratio key for admin password
|
31
|
+
PASSWORD_KEY = 'info_server.admin.password'
|
32
|
+
|
33
|
+
|
23
34
|
# load configuration file
|
24
35
|
# @param option [Hash]
|
25
36
|
# @option option :path [String] path to configuration file
|
26
37
|
# @option option :type [String] load type (differe by tool)
|
27
38
|
# @option option :ignore_plugin [Boolean] set true not to load plugins
|
28
39
|
def load_config(option = {})
|
29
|
-
option = {:path => DEFAULT_CONFIG,
|
30
|
-
:type => nil,
|
40
|
+
option = {:path => DEFAULT_CONFIG,
|
41
|
+
:type => nil,
|
31
42
|
:ignore_plugin => false }.merge(option)
|
32
43
|
conf = nil
|
33
44
|
case File.extname(option[:path])
|
@@ -5,7 +5,7 @@ module Patriot
|
|
5
5
|
# a configuration implementation definied by the ini-file format
|
6
6
|
class IniFileConfig < Patriot::Util::Config::Base
|
7
7
|
|
8
|
-
#
|
8
|
+
# common section name
|
9
9
|
COMMON_SECTION = 'common'
|
10
10
|
|
11
11
|
# @param path [String] path to a configuration file
|
data/lib/patriot/worker/base.rb
CHANGED
@@ -28,12 +28,13 @@ module Patriot
|
|
28
28
|
# @abstract
|
29
29
|
# base class for worker implementations
|
30
30
|
class Base
|
31
|
-
|
31
|
+
|
32
32
|
include Patriot::Util::Logger
|
33
33
|
include Patriot::Util::Retry
|
34
34
|
include Patriot::JobStore::Factory
|
35
|
-
|
35
|
+
|
36
36
|
attr_accessor :host, :status, :cycle, :job_store, :config
|
37
|
+
attr_reader :started_at
|
37
38
|
|
38
39
|
# @param config [Patriot::Util::Config::Base]
|
39
40
|
def initialize(config)
|
@@ -73,6 +74,7 @@ module Patriot
|
|
73
74
|
job_ticket.exit_code = Patriot::Command::ExitCode::SUCCEEDED
|
74
75
|
rescue Exception => e
|
75
76
|
@logger.warn " job : #{job_ticket.job_id} failed"
|
77
|
+
@logger.warn e
|
76
78
|
job_ticket.description = e.to_s
|
77
79
|
else
|
78
80
|
job_ticket.description = command.description
|
@@ -122,6 +124,7 @@ module Patriot
|
|
122
124
|
File.open(pid_file, 'w') {|f| f.write($$)} # save pid for shutdown
|
123
125
|
set_traps
|
124
126
|
@info_server.start_server
|
127
|
+
@started_at = Time.now
|
125
128
|
@logger.info "initiating worker #{@node}@#{@host}"
|
126
129
|
init_worker
|
127
130
|
@status = Patriot::Worker::Status::ACTIVE
|
@@ -136,7 +139,7 @@ module Patriot
|
|
136
139
|
|
137
140
|
# should be overrided in sub class
|
138
141
|
# This method is for implementation-specific configuration
|
139
|
-
def init_worker
|
142
|
+
def init_worker
|
140
143
|
raise NotImplementedError
|
141
144
|
end
|
142
145
|
|
@@ -1,3 +1,6 @@
|
|
1
|
+
require 'thin'
|
2
|
+
require 'rack/rewrite'
|
3
|
+
|
1
4
|
module Patriot
|
2
5
|
module Worker
|
3
6
|
# info server (web management console and for monitoring)
|
@@ -8,15 +11,11 @@ module Patriot
|
|
8
11
|
# default port number
|
9
12
|
DEFAULT_PORT = '36104'
|
10
13
|
|
11
|
-
# urls used by this server
|
12
|
-
URLS_KEY = 'info_server.urls'
|
13
|
-
# mapping from the url to a servlet for the url
|
14
|
-
URL_MAP_KEY_PREFIX = 'info_server.urlmap'
|
15
|
-
|
16
14
|
# configuration key for rack handler used to start this server
|
17
15
|
RACK_HANDLER_KEY = 'info_server.rack.handler'
|
18
16
|
# default rack handler
|
19
|
-
DEFAULT_RACK_HANDLER = 'Rack::Handler::WEBrick'
|
17
|
+
# DEFAULT_RACK_HANDLER = 'Rack::Handler::WEBrick'
|
18
|
+
DEFAULT_RACK_HANDLER = 'Rack::Handler::Thin'
|
20
19
|
|
21
20
|
include Patriot::Util::Config
|
22
21
|
include Patriot::Util::Logger
|
@@ -39,35 +38,41 @@ module Patriot
|
|
39
38
|
@logger.info("port is not set. starting info server is skipped")
|
40
39
|
return
|
41
40
|
end
|
42
|
-
@server_thread = Thread.new do
|
41
|
+
@server_thread = Thread.new do
|
43
42
|
begin
|
44
43
|
@handler = eval(@config.get(RACK_HANDLER_KEY, DEFAULT_RACK_HANDLER))
|
45
44
|
app = Rack::URLMap.new(get_url_map)
|
46
45
|
app = Rack::CommonLogger.new(app, build_access_logger)
|
47
|
-
|
46
|
+
app = Rack::Rewrite.new(app){
|
47
|
+
# below 4 rules are for backward compatibility
|
48
|
+
r301 %r{^/jobs/?$}, "/"
|
49
|
+
rewrite %r{^/jobs/([^/]+)$}, "/api/v1/jobs/$1"
|
50
|
+
rewrite "/worker", "/api/v1/workers/this/state"
|
51
|
+
rewrite "/worker/status", "/api/v1/workers/this/state"
|
52
|
+
# for web console
|
53
|
+
rewrite %r{^(?!/api)}, "/"
|
54
|
+
}
|
55
|
+
app = Rack::Static.new(app, :urls => ["/js", "/css"], :root => File.join($home, "public"))
|
56
|
+
# TODO set options based on Handler type
|
57
|
+
@handler.run(app, {:Port => @port, :Host => '0.0.0.0', :signals => false}) do |server|
|
58
|
+
server.threaded = true
|
59
|
+
server.threadpool_size = 5
|
60
|
+
server.timeout = 60
|
61
|
+
end
|
48
62
|
rescue => e
|
49
63
|
@logger.error e
|
64
|
+
raise e
|
50
65
|
end
|
51
66
|
end
|
52
|
-
@logger.info "info server has started"
|
67
|
+
@logger.info "info server has started with #{@handler.class}"
|
53
68
|
return true
|
54
69
|
end
|
55
70
|
|
56
71
|
# @return [Hash<String, Sinatra::Base>]
|
57
72
|
def get_url_map
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
"/worker" => Patriot::Worker::Servlet::WorkerStatusServlet}
|
62
|
-
else
|
63
|
-
urlmap = {}
|
64
|
-
urls = [url] unless urls.is_a? Array
|
65
|
-
urls.each do |u|
|
66
|
-
servlet = eval( @config.get("#{URL_MAP_KEY_PREFIX}.#{u}") )
|
67
|
-
u = "/#{u}" unless u.start_with?("/")
|
68
|
-
urlmap[u] = servlet
|
69
|
-
end
|
70
|
-
end
|
73
|
+
urlmap = {"/" => Patriot::Worker::Servlet::IndexServlet,
|
74
|
+
"/api/v1/jobs" => Patriot::Worker::Servlet::JobAPIServlet,
|
75
|
+
"/api/v1/workers" => Patriot::Worker::Servlet::WorkerAPIServlet}
|
71
76
|
urlmap.values.each{|servlet| servlet.configure(@worker, @config)}
|
72
77
|
return urlmap
|
73
78
|
end
|
@@ -82,8 +87,13 @@ module Patriot
|
|
82
87
|
def shutdown_server
|
83
88
|
return false if @server.nil?
|
84
89
|
unless @server_thread.nil?
|
85
|
-
|
86
|
-
|
90
|
+
begin
|
91
|
+
@handler.shutdown
|
92
|
+
@logger.info "info server shutdowned"
|
93
|
+
rescue => e
|
94
|
+
@logger.error "failed to shutdown infoserver", e
|
95
|
+
raise e
|
96
|
+
end
|
87
97
|
end
|
88
98
|
end
|
89
99
|
|
@@ -10,14 +10,10 @@ module Patriot
|
|
10
10
|
# default offset for searching jobs
|
11
11
|
DEFAULT_JOB_OFFSET = 0
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
require 'patriot/worker/servlet/job_servlet.rb'
|
19
|
-
require 'patriot/worker/servlet/worker_status_servlet.rb'
|
20
|
-
|
13
|
+
require 'patriot/worker/servlet/index_servlet.rb'
|
14
|
+
require 'patriot/worker/servlet/api_servlet_base.rb'
|
15
|
+
require 'patriot/worker/servlet/job_api_servlet.rb'
|
16
|
+
require 'patriot/worker/servlet/worker_api_servlet.rb'
|
21
17
|
end
|
22
18
|
end
|
23
19
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'sinatra/base'
|
2
|
+
|
3
|
+
module Patriot
|
4
|
+
module Worker
|
5
|
+
module Servlet
|
6
|
+
class APIServletBase < Sinatra::Base
|
7
|
+
set :show_exceptions, :after_handler
|
8
|
+
|
9
|
+
### Helper Methods
|
10
|
+
helpers do
|
11
|
+
# require authorization for updating
|
12
|
+
def protected!
|
13
|
+
return if authorized?
|
14
|
+
headers['WWW-Authenticate'] = 'Basic Realm="Admin Only"'
|
15
|
+
halt 401, "Not Authorized"
|
16
|
+
end
|
17
|
+
|
18
|
+
# authorize user (basic authentication)
|
19
|
+
def authorized?
|
20
|
+
@auth ||= Rack::Auth::Basic::Request.new(request.env)
|
21
|
+
return @auth.provided? && @auth.basic? && @auth.credentials && @auth.credentials == [@@username, @@password]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# @param worker [Patriot::Wokrer::Base]
|
26
|
+
# @param config [Patriot::Util::Config::Base]
|
27
|
+
def self.configure(worker, config)
|
28
|
+
@@worker = worker
|
29
|
+
@@config = config
|
30
|
+
@@username = config.get(Patriot::Util::Config::USERNAME_KEY, "")
|
31
|
+
@@password = config.get(Patriot::Util::Config::PASSWORD_KEY, "")
|
32
|
+
end
|
33
|
+
|
34
|
+
before do
|
35
|
+
content_type 'application/json;charset=utf8'
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'sinatra/base'
|
2
|
+
require 'sinatra/contrib'
|
3
|
+
|
4
|
+
module Patriot
|
5
|
+
module Worker
|
6
|
+
module Servlet
|
7
|
+
|
8
|
+
# allow to monitor worker status
|
9
|
+
class IndexServlet < Sinatra::Base
|
10
|
+
register Sinatra::Contrib
|
11
|
+
|
12
|
+
set :public_folder, File.join($home, "public")
|
13
|
+
set :views, File.join($home, "public", "views")
|
14
|
+
|
15
|
+
# @param worker [Patriot::Worker::Base]
|
16
|
+
# @param config [Patriot::Util::Config::Base]
|
17
|
+
def self.configure(worker, config)
|
18
|
+
@@worker = worker
|
19
|
+
end
|
20
|
+
|
21
|
+
before do
|
22
|
+
@worker = @@worker
|
23
|
+
end
|
24
|
+
|
25
|
+
get '/' do
|
26
|
+
erb :index
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,156 @@
|
|
1
|
+
require 'sinatra/base'
|
2
|
+
require 'sinatra/contrib'
|
3
|
+
|
4
|
+
module Patriot
|
5
|
+
module Worker
|
6
|
+
module Servlet
|
7
|
+
# excepton thrown in case job not found
|
8
|
+
class JobNotFoundException < Exception; end
|
9
|
+
# provide job management functionalities
|
10
|
+
class JobAPIServlet < Patriot::Worker::Servlet::APIServletBase
|
11
|
+
register Sinatra::Contrib
|
12
|
+
include Patriot::Util::DateUtil
|
13
|
+
include Patriot::Command::Parser
|
14
|
+
|
15
|
+
set :show_exceptions, :after_handler
|
16
|
+
|
17
|
+
get '/stats' do
|
18
|
+
return JSON.generate(@@worker.job_store.get_job_size(:ignore_states => [Patriot::JobStore::JobState::SUCCEEDED]))
|
19
|
+
end
|
20
|
+
|
21
|
+
get '/' do
|
22
|
+
state = (params['state'] || Patriot::JobStore::JobState::FAILED).to_i
|
23
|
+
limit = (params['limit'] || DEFAULT_JOB_LIMIT).to_i
|
24
|
+
offset = (params['offset'] || DEFAULT_JOB_OFFSET).to_i
|
25
|
+
|
26
|
+
query = {:limit => limit, :offset => offset}
|
27
|
+
query[:filter_exp] = params['filter_exp'] unless params['filter_exp'].blank?
|
28
|
+
job_ids = @@worker.job_store.find_jobs_by_state(state, query) || []
|
29
|
+
return JSON.generate(job_ids.map{|job_id| {:job_id => job_id, :state => state}})
|
30
|
+
end
|
31
|
+
|
32
|
+
get '/:job_id' do
|
33
|
+
job_id = params[:job_id]
|
34
|
+
job = @@worker.job_store.get(job_id, {:include_dependency => true})
|
35
|
+
halt(404, json({ERROR: "Job #{job_id} not found"})) if job.nil?
|
36
|
+
return JSON.generate(job.attributes.merge({'job_id' => job_id, "update_id" => job.update_id}))
|
37
|
+
end
|
38
|
+
|
39
|
+
get '/:job_id/histories' do
|
40
|
+
job_id = params[:job_id]
|
41
|
+
history_size = params['size'] || 3
|
42
|
+
histories = @@worker.job_store.get_execution_history(job_id, {:limit => history_size})
|
43
|
+
return JSON.generate(histories)
|
44
|
+
end
|
45
|
+
|
46
|
+
# get dependency graph of the specified job
|
47
|
+
#
|
48
|
+
# @param [String] job_id
|
49
|
+
# @param [String] p_level a max number of producer dependency level to get
|
50
|
+
# @param [String] c_level a max number of consumer dependency level to get
|
51
|
+
get '/:job_id/graph' do
|
52
|
+
job_id = params[:job_id]
|
53
|
+
producer_depth = (params['p_depth'] || 2).to_i
|
54
|
+
consumer_depth = (params['c_depth'] || 2).to_i
|
55
|
+
graph = @@worker.job_store.get_graph(job_id, {:producer_depth => producer_depth, :consumer_depth => consumer_depth})
|
56
|
+
return JSON.generate(graph)
|
57
|
+
end
|
58
|
+
|
59
|
+
post '/' do
|
60
|
+
protected!
|
61
|
+
body = JSON.parse(request.body.read)
|
62
|
+
halt(400, json({ERROR: "COMMAND_CLASS is not provided"})) if body["COMMAND_CLASS"].blank?
|
63
|
+
halt(400, json({ERROR: "Patriot::Command::CommandGroup is not acceptable"})) if body["COMMAND_CLASS"] == "Patriot::Command::CommandGroup"
|
64
|
+
command_class = body.delete("COMMAND_CLASS").gsub(/\./, '::').constantize
|
65
|
+
|
66
|
+
job = _build_command(command_class, body)[0]
|
67
|
+
job[Patriot::Command::STATE_ATTR] ||= body["state"]
|
68
|
+
@@worker.job_store.register(Time.now.to_i, [job])
|
69
|
+
return JSON.generate({:job_id => job.job_id})
|
70
|
+
end
|
71
|
+
|
72
|
+
put '/' do
|
73
|
+
protected!
|
74
|
+
body = JSON.parse(request.body.read)
|
75
|
+
job_ids = body["job_ids"]
|
76
|
+
state = body['state']
|
77
|
+
_set_state_of_jobs(job_ids, state)
|
78
|
+
return JSON.generate(job_ids.map{|job_id| {"job_id" => job_id, "state" => state} })
|
79
|
+
end
|
80
|
+
|
81
|
+
put '/:job_id' do
|
82
|
+
protected!
|
83
|
+
job_id = params['job_id']
|
84
|
+
job = @@worker.job_store.get(job_id)
|
85
|
+
halt(404, json({ERROR: "Job #{job_id} not found"})) if job.nil?
|
86
|
+
|
87
|
+
body = JSON.parse(request.body.read)
|
88
|
+
state = body['state']
|
89
|
+
options = body['option'] || {}
|
90
|
+
job_ids = _set_state_of_jobs(job_id, state, options)
|
91
|
+
return JSON.generate(job_ids.map{|jid| {"job_id" => jid, "state" => state}})
|
92
|
+
end
|
93
|
+
|
94
|
+
delete '/' do
|
95
|
+
protected!
|
96
|
+
body = request.body.read
|
97
|
+
job_ids = []
|
98
|
+
if body != ''
|
99
|
+
body = JSON.parse(body)
|
100
|
+
job_ids = body["job_ids"]
|
101
|
+
else
|
102
|
+
job_ids = JSON.parse(params["job_ids"])
|
103
|
+
end
|
104
|
+
job_ids.each{ |job_id| @@worker.job_store.delete_job(job_id) }
|
105
|
+
return JSON.generate(job_ids.map{|job_id| {"job_id" => job_id} })
|
106
|
+
end
|
107
|
+
|
108
|
+
delete '/:job_id' do
|
109
|
+
protected!
|
110
|
+
job_id = params['job_id']
|
111
|
+
job = @@worker.job_store.get(job_id)
|
112
|
+
halt(404, json({ERROR: "Job #{job_id} not found"})) if job.nil?
|
113
|
+
|
114
|
+
@@worker.job_store.delete_job(job_id)
|
115
|
+
return JSON.generate({"job_id" => job_id})
|
116
|
+
end
|
117
|
+
|
118
|
+
error JobNotFoundException do
|
119
|
+
"Job #{env['sinatra.error'].message} is not found"
|
120
|
+
end
|
121
|
+
|
122
|
+
# @private
|
123
|
+
def _set_state_of_jobs(job_ids, state, opts = {})
|
124
|
+
job_ids = [job_ids] unless job_ids.is_a? Array
|
125
|
+
opts = {'with_subsequent' => false}.merge(opts)
|
126
|
+
opts = {:include_subsequent => false}.merge(opts)
|
127
|
+
update_id = Time.now.to_i
|
128
|
+
@@worker.job_store.set_state(update_id, job_ids, state)
|
129
|
+
if opts['with_subsequent']
|
130
|
+
@@worker.job_store.process_subsequent(job_ids) do |job_store, jobs|
|
131
|
+
next if jobs.empty?
|
132
|
+
subsequent_ids = jobs.map(&:job_id)
|
133
|
+
@@worker.job_store.set_state(update_id, subsequent_ids, state)
|
134
|
+
job_ids |= subsequent_ids
|
135
|
+
end
|
136
|
+
end
|
137
|
+
return job_ids.uniq
|
138
|
+
end
|
139
|
+
private :_set_state_of_jobs
|
140
|
+
|
141
|
+
# @private
|
142
|
+
def _build_command(clazz, params)
|
143
|
+
_params = params.dup
|
144
|
+
_params["target_datetime"] = Date.today
|
145
|
+
cmd = clazz.new(@@config)
|
146
|
+
cmd.produce(_params.delete("products")) unless _params["products"].nil?
|
147
|
+
cmd.require(_params.delete("requisites")) unless _params["requisites"].nil?
|
148
|
+
cmds = cmd.build(_params)
|
149
|
+
return cmds.map{|c| c.to_job}
|
150
|
+
end
|
151
|
+
private :_build_command
|
152
|
+
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'sinatra/base'
|
2
|
+
require 'sinatra/contrib'
|
3
|
+
|
4
|
+
module Patriot
|
5
|
+
module Worker
|
6
|
+
module Servlet
|
7
|
+
# excepton thrown when a woker is not accessible
|
8
|
+
class WorkerInaccessibleException < Exception; end
|
9
|
+
# provide worker management functionalities
|
10
|
+
class WorkerAPIServlet < Patriot::Worker::Servlet::APIServletBase
|
11
|
+
register Sinatra::Contrib
|
12
|
+
|
13
|
+
HOST_KEY = "host"
|
14
|
+
VERSION_KEY = "version"
|
15
|
+
CLASS_KEY = "class"
|
16
|
+
STARTED_AT_KEY = "started_at"
|
17
|
+
CONFIG_KEY = "config"
|
18
|
+
|
19
|
+
STATE_KEY = "state"
|
20
|
+
|
21
|
+
LOCALHOST_EXPS = ["localhost", "127.0.0.1"]
|
22
|
+
|
23
|
+
set :show_exceptions, :after_handler
|
24
|
+
|
25
|
+
get '/' do
|
26
|
+
worker_hosts = @@config.get(Patriot::Util::Config::WORKER_HOST_KEY)
|
27
|
+
worker_hosts = [worker_hosts] unless worker_hosts.is_a?(Array)
|
28
|
+
worker_hosts = @@config.get(Patriot::Util::Config::WORKER_HOST_KEY).map do |h|
|
29
|
+
h = h.split(":")
|
30
|
+
port = h.size == 2 ? h[1] : Patriot::Worker::InfoServer::DEFAULT_PORT
|
31
|
+
{'host' => h[0], 'port' => port}
|
32
|
+
end
|
33
|
+
return JSON.generate(worker_hosts)
|
34
|
+
end
|
35
|
+
|
36
|
+
get '/this' do
|
37
|
+
return JSON.generate(
|
38
|
+
STATE_KEY => @@worker.status,
|
39
|
+
HOST_KEY => @@worker.host,
|
40
|
+
VERSION_KEY => Patriot::VERSION,
|
41
|
+
CLASS_KEY => @@worker.class.to_s,
|
42
|
+
STARTED_AT_KEY => @@worker.started_at,
|
43
|
+
CONFIG_KEY => {} # TODO
|
44
|
+
)
|
45
|
+
end
|
46
|
+
|
47
|
+
get '/this/state' do
|
48
|
+
return JSON.generate(
|
49
|
+
STATE_KEY => @@worker.status
|
50
|
+
)
|
51
|
+
end
|
52
|
+
|
53
|
+
put '/this/state' do
|
54
|
+
protected!
|
55
|
+
new_status = params['status']
|
56
|
+
if [Patriot::Worker::Status::ACTIVE, Patriot::Worker::Status::SLEEP ].include?(@@worker.status)
|
57
|
+
@@worker.status = new_status
|
58
|
+
else
|
59
|
+
# state cannot be changed in shutdown process
|
60
|
+
halt 403
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|