sanford 0.10.1 → 0.11.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +1 -1
- data/README.md +41 -56
- data/Rakefile +0 -1
- data/bench/client.rb +8 -3
- data/bench/{services.rb → config.sanford} +11 -6
- data/bench/{runner.rb → report.rb} +2 -2
- data/bench/report.txt +32 -32
- data/lib/sanford/cli.rb +42 -28
- data/lib/sanford/config_file.rb +79 -0
- data/lib/sanford/{worker.rb → connection_handler.rb} +28 -20
- data/lib/sanford/error_handler.rb +7 -7
- data/lib/sanford/pid_file.rb +42 -0
- data/lib/sanford/process.rb +136 -0
- data/lib/sanford/process_signal.rb +20 -0
- data/lib/sanford/route.rb +48 -0
- data/lib/sanford/router.rb +36 -0
- data/lib/sanford/runner.rb +30 -58
- data/lib/sanford/sanford_runner.rb +19 -9
- data/lib/sanford/server.rb +211 -42
- data/lib/sanford/server_data.rb +47 -0
- data/lib/sanford/service_handler.rb +8 -46
- data/lib/sanford/template_source.rb +19 -2
- data/lib/sanford/test_runner.rb +27 -28
- data/lib/sanford/version.rb +1 -1
- data/lib/sanford.rb +1 -23
- data/sanford.gemspec +4 -5
- data/test/helper.rb +3 -20
- data/test/support/app_server.rb +142 -0
- data/test/support/config.sanford +7 -0
- data/test/support/config_invalid_run.sanford +3 -0
- data/test/support/config_no_run.sanford +0 -0
- data/test/support/fake_server_connection.rb +58 -0
- data/test/support/pid_file_spy.rb +19 -0
- data/test/support/template.erb +1 -0
- data/test/system/server_tests.rb +378 -0
- data/test/system/service_handler_tests.rb +224 -0
- data/test/unit/cli_tests.rb +187 -0
- data/test/unit/config_file_tests.rb +59 -0
- data/test/unit/connection_handler_tests.rb +254 -0
- data/test/unit/error_handler_tests.rb +30 -35
- data/test/unit/pid_file_tests.rb +70 -0
- data/test/unit/process_signal_tests.rb +61 -0
- data/test/unit/process_tests.rb +428 -0
- data/test/unit/route_tests.rb +92 -0
- data/test/unit/router_tests.rb +65 -0
- data/test/unit/runner_tests.rb +61 -15
- data/test/unit/sanford_runner_tests.rb +162 -28
- data/test/unit/sanford_tests.rb +0 -8
- data/test/unit/server_data_tests.rb +87 -0
- data/test/unit/server_tests.rb +502 -21
- data/test/unit/service_handler_tests.rb +114 -219
- data/test/unit/template_engine_tests.rb +1 -1
- data/test/unit/template_source_tests.rb +56 -16
- data/test/unit/test_runner_tests.rb +206 -0
- metadata +67 -67
- data/bench/tasks.rb +0 -41
- data/lib/sanford/config.rb +0 -28
- data/lib/sanford/host.rb +0 -129
- data/lib/sanford/host_data.rb +0 -65
- data/lib/sanford/hosts.rb +0 -38
- data/lib/sanford/manager.rb +0 -275
- data/test/support/fake_connection.rb +0 -36
- data/test/support/helpers.rb +0 -17
- data/test/support/service_handlers.rb +0 -154
- data/test/support/services.rb +0 -123
- data/test/support/simple_client.rb +0 -62
- data/test/system/request_handling_tests.rb +0 -306
- data/test/unit/config_tests.rb +0 -56
- data/test/unit/host_data_tests.rb +0 -71
- data/test/unit/host_tests.rb +0 -141
- data/test/unit/hosts_tests.rb +0 -50
- data/test/unit/manager_tests.rb +0 -195
- data/test/unit/worker_tests.rb +0 -24
data/lib/sanford/host_data.rb
DELETED
@@ -1,65 +0,0 @@
|
|
1
|
-
require 'sanford/service_handler'
|
2
|
-
require 'sanford/sanford_runner'
|
3
|
-
|
4
|
-
module Sanford
|
5
|
-
|
6
|
-
class HostData
|
7
|
-
|
8
|
-
# When trying to run a server for a host, we need to build up the host's
|
9
|
-
# data to increase the performance of the server. This is done by
|
10
|
-
# constantizing a host's handlers and merging a host's configuration with
|
11
|
-
# optional overrides.
|
12
|
-
|
13
|
-
# NOTE: The `name` attribute shouldn't be removed, it is used to identify
|
14
|
-
# a `HostData`, particularly in error handlers
|
15
|
-
|
16
|
-
attr_reader :name, :logger, :verbose, :keep_alive, :error_procs
|
17
|
-
|
18
|
-
def initialize(service_host, options = nil)
|
19
|
-
service_host.configuration.init_procs.each(&:call)
|
20
|
-
|
21
|
-
overrides = self.remove_nil_values(options || {})
|
22
|
-
configuration = service_host.configuration.to_hash.merge(overrides)
|
23
|
-
|
24
|
-
@name = configuration[:name]
|
25
|
-
@logger = configuration[:logger]
|
26
|
-
@verbose = configuration[:verbose_logging]
|
27
|
-
@keep_alive = configuration[:receives_keep_alive]
|
28
|
-
@error_procs = configuration[:error_procs]
|
29
|
-
|
30
|
-
@handlers = service_host.services.inject({}) do |h, (name, handler_class_name)|
|
31
|
-
h.merge({ name => self.constantize(handler_class_name) })
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
def handler_class_for(service)
|
36
|
-
@handlers[service] || raise(Sanford::NotFoundError)
|
37
|
-
end
|
38
|
-
|
39
|
-
def run(handler_class, request)
|
40
|
-
SanfordRunner.new(handler_class, request, self.logger).run
|
41
|
-
end
|
42
|
-
|
43
|
-
protected
|
44
|
-
|
45
|
-
def constantize(handler_class_name)
|
46
|
-
Sanford::ServiceHandler.constantize(handler_class_name) ||
|
47
|
-
raise(Sanford::NoHandlerClassError.new(handler_class_name))
|
48
|
-
end
|
49
|
-
|
50
|
-
def remove_nil_values(hash)
|
51
|
-
hash.inject({}){|h, (k, v)| !v.nil? ? h.merge({ k => v }) : h }
|
52
|
-
end
|
53
|
-
|
54
|
-
end
|
55
|
-
|
56
|
-
NotFoundError = Class.new(RuntimeError)
|
57
|
-
|
58
|
-
class NoHandlerClassError < RuntimeError
|
59
|
-
def initialize(handler_class_name)
|
60
|
-
super "Sanford couldn't find the service handler '#{handler_class_name}'."\
|
61
|
-
" It doesn't exist or hasn't been required in yet."
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
end
|
data/lib/sanford/hosts.rb
DELETED
@@ -1,38 +0,0 @@
|
|
1
|
-
require 'set'
|
2
|
-
require 'sanford/host'
|
3
|
-
|
4
|
-
module Sanford
|
5
|
-
|
6
|
-
class Hosts
|
7
|
-
|
8
|
-
def initialize(values = [])
|
9
|
-
@set = Set.new(values)
|
10
|
-
end
|
11
|
-
|
12
|
-
def method_missing(method, *args, &block)
|
13
|
-
@set.send(method, *args, &block)
|
14
|
-
end
|
15
|
-
|
16
|
-
def respond_to?(method)
|
17
|
-
super || @set.respond_to?(method)
|
18
|
-
end
|
19
|
-
|
20
|
-
# We want class names to take precedence over a configured name, so that if
|
21
|
-
# a user specifies a specific class, they always get it
|
22
|
-
def find(name)
|
23
|
-
find_by_class_name(name) || find_by_name(name)
|
24
|
-
end
|
25
|
-
|
26
|
-
private
|
27
|
-
|
28
|
-
def find_by_class_name(class_name)
|
29
|
-
@set.detect{|host_class| host_class.to_s == class_name.to_s }
|
30
|
-
end
|
31
|
-
|
32
|
-
def find_by_name(name)
|
33
|
-
@set.detect{|host_class| host_class.name == name.to_s }
|
34
|
-
end
|
35
|
-
|
36
|
-
end
|
37
|
-
|
38
|
-
end
|
data/lib/sanford/manager.rb
DELETED
@@ -1,275 +0,0 @@
|
|
1
|
-
require 'sanford/cli'
|
2
|
-
require 'sanford/server'
|
3
|
-
|
4
|
-
module Sanford
|
5
|
-
|
6
|
-
module Manager
|
7
|
-
|
8
|
-
def self.call(action, options = nil)
|
9
|
-
get_handler_class(action).new(options).tap{ |manager| manager.send(action) }
|
10
|
-
end
|
11
|
-
|
12
|
-
def self.get_handler_class(action)
|
13
|
-
case action.to_sym
|
14
|
-
when :start, :run
|
15
|
-
ServerHandler
|
16
|
-
when :stop, :restart
|
17
|
-
SignalHandler
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
class Config
|
22
|
-
attr_reader :host_name, :host, :ip, :port, :pid, :pid_file, :restart_dir
|
23
|
-
attr_reader :file_descriptor, :client_file_descriptors
|
24
|
-
|
25
|
-
def initialize(opts = nil)
|
26
|
-
options = OpenStruct.new(opts || {})
|
27
|
-
@host_name = ENV['SANFORD_HOST'] || options.host
|
28
|
-
|
29
|
-
@host = @host_name ? Sanford.hosts.find(@host_name) : Sanford.hosts.first
|
30
|
-
@host ||= NullHost.new
|
31
|
-
|
32
|
-
@file_descriptor = ENV['SANFORD_SERVER_FD'] || options.file_descriptor
|
33
|
-
@file_descriptor = @file_descriptor.to_i if @file_descriptor
|
34
|
-
@ip = ENV['SANFORD_IP'] || options.ip || @host.ip
|
35
|
-
@port = ENV['SANFORD_PORT'] || options.port || @host.port
|
36
|
-
@port = @port.to_i if @port
|
37
|
-
|
38
|
-
client_fds_str = ENV['SANFORD_CLIENT_FDS'] || options.client_fds || ""
|
39
|
-
@client_file_descriptors = client_fds_str.split(',').map(&:to_i)
|
40
|
-
|
41
|
-
@pid_file = PIDFile.new(ENV['SANFORD_PID_FILE'] || options.pid_file || @host.pid_file)
|
42
|
-
@pid = options.pid || @pid_file.pid
|
43
|
-
|
44
|
-
@restart_dir = ENV['SANFORD_RESTART_DIR'] || options.restart_dir
|
45
|
-
end
|
46
|
-
|
47
|
-
def listen_args
|
48
|
-
@file_descriptor ? [ @file_descriptor ] : [ @ip, @port ]
|
49
|
-
end
|
50
|
-
|
51
|
-
def has_listen_args?
|
52
|
-
!!@file_descriptor || !!(@ip && @port)
|
53
|
-
end
|
54
|
-
|
55
|
-
def found_host?
|
56
|
-
!@host.kind_of?(NullHost)
|
57
|
-
end
|
58
|
-
|
59
|
-
class NullHost
|
60
|
-
[ :ip, :port, :pid_file ].each do |method_name|
|
61
|
-
define_method(method_name){ }
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
class PIDFile
|
66
|
-
DEF_FILE = '/dev/null'
|
67
|
-
|
68
|
-
def initialize(path)
|
69
|
-
@path = (path || DEF_FILE).to_s
|
70
|
-
end
|
71
|
-
|
72
|
-
def pid
|
73
|
-
pid = File.read(@path).strip if File.exists?(@path)
|
74
|
-
pid.to_i if pid && !pid.empty?
|
75
|
-
end
|
76
|
-
|
77
|
-
def write
|
78
|
-
begin
|
79
|
-
File.open(@path, 'w'){|f| f.puts Process.pid }
|
80
|
-
rescue Errno::ENOENT => err
|
81
|
-
e = RuntimeError.new("Can't write pid to file `#{@path}`")
|
82
|
-
e.set_backtrace(err.backtrace)
|
83
|
-
raise e
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
def remove
|
88
|
-
FileUtils.rm_f(@path)
|
89
|
-
end
|
90
|
-
|
91
|
-
def to_s
|
92
|
-
@path
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
end
|
97
|
-
|
98
|
-
class ServerHandler
|
99
|
-
|
100
|
-
def initialize(options = nil)
|
101
|
-
@config = Config.new(options)
|
102
|
-
raise Sanford::NoHostError.new(@config.host_name) if !@config.found_host?
|
103
|
-
raise Sanford::InvalidHostError.new(@config.host) if !@config.has_listen_args?
|
104
|
-
@host = @config.host
|
105
|
-
@logger = @host.logger
|
106
|
-
|
107
|
-
@server_options = {}
|
108
|
-
# FUTURE allow passing through dat-tcp options (min/max workers)
|
109
|
-
# FUTURE merge in host options for verbose / keep_alive
|
110
|
-
|
111
|
-
@restart_cmd = RestartCmd.new(@config)
|
112
|
-
end
|
113
|
-
|
114
|
-
def run
|
115
|
-
self.run! false
|
116
|
-
end
|
117
|
-
|
118
|
-
def start
|
119
|
-
self.run! true
|
120
|
-
end
|
121
|
-
|
122
|
-
protected
|
123
|
-
|
124
|
-
def run!(daemonize = false)
|
125
|
-
daemonize!(true) if daemonize && !ENV['SANFORD_SKIP_DAEMONIZE']
|
126
|
-
Sanford::Server.new(@host, @server_options).tap do |server|
|
127
|
-
log "Starting #{@host.name} server..."
|
128
|
-
|
129
|
-
server.listen(*@config.listen_args)
|
130
|
-
$0 = ProcessName.new(@host.name, server.ip, server.port)
|
131
|
-
log "Listening on #{server.ip}:#{server.port}"
|
132
|
-
|
133
|
-
@config.pid_file.write
|
134
|
-
log "PID: #{Process.pid}"
|
135
|
-
|
136
|
-
Signal.trap("TERM"){ self.stop!(server) }
|
137
|
-
Signal.trap("INT"){ self.halt!(server) }
|
138
|
-
Signal.trap("USR2"){ self.restart!(server) }
|
139
|
-
|
140
|
-
server_thread = server.run(@config.client_file_descriptors)
|
141
|
-
log "#{@host.name} server started and ready."
|
142
|
-
server_thread.join
|
143
|
-
end
|
144
|
-
rescue RuntimeError => err
|
145
|
-
log "Error: #{err.message}"
|
146
|
-
log "#{@host.name} server never started."
|
147
|
-
ensure
|
148
|
-
@config.pid_file.remove
|
149
|
-
end
|
150
|
-
|
151
|
-
def restart!(server)
|
152
|
-
log "Restarting #{@host.name} server..."
|
153
|
-
server.pause
|
154
|
-
log "server paused"
|
155
|
-
|
156
|
-
ENV['SANFORD_HOST'] = @host.name
|
157
|
-
ENV['SANFORD_SERVER_FD'] = server.file_descriptor.to_s
|
158
|
-
ENV['SANFORD_CLIENT_FDS'] = server.client_file_descriptors.join(',')
|
159
|
-
ENV['SANFORD_SKIP_DAEMONIZE'] = 'yes'
|
160
|
-
|
161
|
-
log "calling exec ..."
|
162
|
-
Dir.chdir @restart_cmd.dir
|
163
|
-
Kernel.exec(*@restart_cmd.argv)
|
164
|
-
end
|
165
|
-
|
166
|
-
def stop!(server)
|
167
|
-
log "Stopping #{@host.name} server..."
|
168
|
-
server.stop
|
169
|
-
log "#{@host.name} server stopped."
|
170
|
-
end
|
171
|
-
|
172
|
-
def halt!(server)
|
173
|
-
log "Halting #{@host.name} server..."
|
174
|
-
server.halt false
|
175
|
-
log "#{@host.name} server halted."
|
176
|
-
end
|
177
|
-
|
178
|
-
# Full explanation: http://www.steve.org.uk/Reference/Unix/faq_2.html#SEC16
|
179
|
-
def daemonize!(no_chdir = false, no_close = false)
|
180
|
-
exit if fork
|
181
|
-
Process.setsid
|
182
|
-
exit if fork
|
183
|
-
Dir.chdir "/" unless no_chdir
|
184
|
-
if !no_close
|
185
|
-
null = File.open "/dev/null", 'w'
|
186
|
-
STDIN.reopen null
|
187
|
-
STDOUT.reopen null
|
188
|
-
STDERR.reopen null
|
189
|
-
end
|
190
|
-
return 0
|
191
|
-
end
|
192
|
-
|
193
|
-
def log(message)
|
194
|
-
@logger.info "[Sanford] #{message}"
|
195
|
-
end
|
196
|
-
|
197
|
-
class ProcessName < String
|
198
|
-
def initialize(name, ip, port)
|
199
|
-
super "#{[ name, ip, port ].join('_')}"
|
200
|
-
end
|
201
|
-
end
|
202
|
-
|
203
|
-
class RestartCmd
|
204
|
-
attr_reader :argv, :dir
|
205
|
-
|
206
|
-
def initialize(config = nil)
|
207
|
-
require 'rubygems'
|
208
|
-
config ||= OpenStruct.new
|
209
|
-
@dir = config.restart_dir || get_pwd
|
210
|
-
@argv = [ Gem.ruby, $0, ARGV.dup ].flatten
|
211
|
-
end
|
212
|
-
|
213
|
-
protected
|
214
|
-
|
215
|
-
# Trick from puma/unicorn. Favor PWD because it contains an unresolved
|
216
|
-
# symlink. This is useful when restarting after deploying; the original
|
217
|
-
# directory may be removed, but the symlink is pointing to a new
|
218
|
-
# directory.
|
219
|
-
def get_pwd
|
220
|
-
env_stat = File.stat(ENV['PWD'])
|
221
|
-
pwd_stat = File.stat(Dir.pwd)
|
222
|
-
if env_stat.ino == pwd_stat.ino && env_stat.dev == pwd_stat.dev
|
223
|
-
ENV['PWD']
|
224
|
-
else
|
225
|
-
Dir.pwd
|
226
|
-
end
|
227
|
-
end
|
228
|
-
|
229
|
-
end
|
230
|
-
|
231
|
-
end
|
232
|
-
|
233
|
-
class SignalHandler
|
234
|
-
|
235
|
-
def initialize(options = nil)
|
236
|
-
@config = Config.new(options)
|
237
|
-
raise Sanford::NoPIDError.new if !@config.pid
|
238
|
-
end
|
239
|
-
|
240
|
-
def stop
|
241
|
-
Process.kill("TERM", @config.pid)
|
242
|
-
end
|
243
|
-
|
244
|
-
def restart
|
245
|
-
Process.kill("USR2", @config.pid)
|
246
|
-
end
|
247
|
-
|
248
|
-
end
|
249
|
-
|
250
|
-
end
|
251
|
-
|
252
|
-
class NoHostError < CLIRB::Error
|
253
|
-
def initialize(host_name)
|
254
|
-
message = if Sanford.hosts.empty?
|
255
|
-
"No hosts have been defined. Please define a host before trying to run Sanford."
|
256
|
-
else
|
257
|
-
"A host couldn't be found with the name #{host_name.inspect}. "
|
258
|
-
end
|
259
|
-
super message
|
260
|
-
end
|
261
|
-
end
|
262
|
-
|
263
|
-
class InvalidHostError < CLIRB::Error
|
264
|
-
def initialize(host)
|
265
|
-
super "A port must be configured or provided to run a server for '#{host}'"
|
266
|
-
end
|
267
|
-
end
|
268
|
-
|
269
|
-
class NoPIDError < CLIRB::Error
|
270
|
-
def initialize
|
271
|
-
super "A PID or PID file is required"
|
272
|
-
end
|
273
|
-
end
|
274
|
-
|
275
|
-
end
|
@@ -1,36 +0,0 @@
|
|
1
|
-
class FakeConnection
|
2
|
-
|
3
|
-
attr_reader :read_data, :response, :write_stream_closed
|
4
|
-
|
5
|
-
def self.with_request(name, params = {}, raise_on_write = false)
|
6
|
-
request = Sanford::Protocol::Request.new(name, params)
|
7
|
-
self.new(request.to_hash, raise_on_write)
|
8
|
-
end
|
9
|
-
|
10
|
-
def initialize(*args)
|
11
|
-
if args.first.kind_of?(Sanford::Protocol::Connection)
|
12
|
-
protocol_connection = args.first
|
13
|
-
@read_data = proc{ protocol_connection.read }
|
14
|
-
@write_data = proc{|data| protocol_connection.write(data) }
|
15
|
-
else
|
16
|
-
@read_data, @raise_on_write = args
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
def read_data
|
21
|
-
@read_data.kind_of?(Proc) ? @read_data.call : @read_data
|
22
|
-
end
|
23
|
-
|
24
|
-
def write_data(data)
|
25
|
-
if @raise_on_write
|
26
|
-
@raise_on_write = false
|
27
|
-
raise 'test fail'
|
28
|
-
end
|
29
|
-
@response = Sanford::Protocol::Response.parse(data)
|
30
|
-
end
|
31
|
-
|
32
|
-
def close_write
|
33
|
-
@write_stream_closed = true
|
34
|
-
end
|
35
|
-
|
36
|
-
end
|
data/test/support/helpers.rb
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
module Test
|
2
|
-
module SpawnServerHelper
|
3
|
-
|
4
|
-
def start_server(host, &block)
|
5
|
-
begin
|
6
|
-
server = Sanford::Server.new(host, { :ready_timeout => 0.1 })
|
7
|
-
server.listen(host.ip, host.port)
|
8
|
-
thread = server.run
|
9
|
-
yield
|
10
|
-
ensure
|
11
|
-
server.halt if server
|
12
|
-
thread.join if thread
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
end
|
17
|
-
end
|
@@ -1,154 +0,0 @@
|
|
1
|
-
class BasicServiceHandler
|
2
|
-
include Sanford::ServiceHandler
|
3
|
-
|
4
|
-
def run!
|
5
|
-
{ 'name' => 'Joe Test', 'email' => "joe.test@example.com" }
|
6
|
-
end
|
7
|
-
|
8
|
-
end
|
9
|
-
|
10
|
-
class SerializeErrorServiceHandler
|
11
|
-
include Sanford::ServiceHandler
|
12
|
-
|
13
|
-
# return data that fails BSON serialization
|
14
|
-
# BSON errors if it is sent date/datetime values
|
15
|
-
def run!
|
16
|
-
{ 'date' => Date.today,
|
17
|
-
'datetime' => DateTime.now
|
18
|
-
}
|
19
|
-
end
|
20
|
-
|
21
|
-
end
|
22
|
-
|
23
|
-
module CallbackServiceHandler
|
24
|
-
|
25
|
-
def self.included(receiver)
|
26
|
-
receiver.class_eval do
|
27
|
-
attr_reader :before_called, :after_called
|
28
|
-
attr_reader :before_init_called, :init_bang_called, :after_init_called
|
29
|
-
attr_reader :before_run_called, :run_bang_called, :after_run_called
|
30
|
-
attr_reader :second_before_init_called, :second_after_run_called
|
31
|
-
|
32
|
-
before do
|
33
|
-
@before_called = true
|
34
|
-
end
|
35
|
-
after do
|
36
|
-
@after_called = true
|
37
|
-
end
|
38
|
-
|
39
|
-
before_init do
|
40
|
-
@before_init_called = true
|
41
|
-
end
|
42
|
-
before_init do
|
43
|
-
@second_before_init_called = true
|
44
|
-
end
|
45
|
-
|
46
|
-
after_init do
|
47
|
-
@after_init_called = true
|
48
|
-
end
|
49
|
-
|
50
|
-
before_run do
|
51
|
-
@before_run_called = true
|
52
|
-
end
|
53
|
-
|
54
|
-
after_run do
|
55
|
-
@after_run_called = true
|
56
|
-
end
|
57
|
-
after_run do
|
58
|
-
@second_after_run_called = true
|
59
|
-
end
|
60
|
-
|
61
|
-
end
|
62
|
-
|
63
|
-
end
|
64
|
-
|
65
|
-
def init!
|
66
|
-
@init_bang_called = true
|
67
|
-
end
|
68
|
-
|
69
|
-
def run!
|
70
|
-
@run_bang_called = true
|
71
|
-
end
|
72
|
-
|
73
|
-
end
|
74
|
-
|
75
|
-
class FlagServiceHandler
|
76
|
-
include Sanford::ServiceHandler
|
77
|
-
include CallbackServiceHandler
|
78
|
-
|
79
|
-
end
|
80
|
-
|
81
|
-
class HaltingBehaviorServiceHandler
|
82
|
-
include Sanford::ServiceHandler
|
83
|
-
include CallbackServiceHandler
|
84
|
-
|
85
|
-
before_init do
|
86
|
-
halt_when('before_init')
|
87
|
-
end
|
88
|
-
|
89
|
-
def init!
|
90
|
-
super
|
91
|
-
halt_when('init!')
|
92
|
-
end
|
93
|
-
|
94
|
-
after_init do
|
95
|
-
halt_when('after_init')
|
96
|
-
end
|
97
|
-
|
98
|
-
before_run do
|
99
|
-
halt_when('before_run')
|
100
|
-
end
|
101
|
-
|
102
|
-
def run!
|
103
|
-
super
|
104
|
-
halt_when('run!')
|
105
|
-
end
|
106
|
-
|
107
|
-
after_run do
|
108
|
-
halt_when('after_run')
|
109
|
-
end
|
110
|
-
|
111
|
-
def halt_when(method_name)
|
112
|
-
return if ![*params['when']].include?(method_name)
|
113
|
-
halt(200, {
|
114
|
-
:message => "#{method_name} halting",
|
115
|
-
:data => {
|
116
|
-
:before_init_called => @before_init_called,
|
117
|
-
:init_bang_called => @init_bang_called,
|
118
|
-
:after_init_called => @after_init_called,
|
119
|
-
:before_run_called => @before_run_called,
|
120
|
-
:run_bang_called => @run_bang_called,
|
121
|
-
:after_run_called => @after_run_called
|
122
|
-
}
|
123
|
-
})
|
124
|
-
end
|
125
|
-
|
126
|
-
end
|
127
|
-
|
128
|
-
class RenderHandler
|
129
|
-
include Sanford::ServiceHandler
|
130
|
-
|
131
|
-
def run!
|
132
|
-
render params['template_name']
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
|
-
class RunOtherHandler
|
137
|
-
include Sanford::ServiceHandler
|
138
|
-
|
139
|
-
def run!
|
140
|
-
response = run_handler(HaltServiceHandler, 'code' => 200, 'data' => 'RunOtherHandler')
|
141
|
-
response.data
|
142
|
-
end
|
143
|
-
end
|
144
|
-
|
145
|
-
class HaltServiceHandler
|
146
|
-
include Sanford::ServiceHandler
|
147
|
-
|
148
|
-
def run!
|
149
|
-
halt params['code'], :message => params['message'], :data => params['data']
|
150
|
-
end
|
151
|
-
|
152
|
-
end
|
153
|
-
|
154
|
-
class InvalidServiceHandler; end
|
data/test/support/services.rb
DELETED
@@ -1,123 +0,0 @@
|
|
1
|
-
require 'logger'
|
2
|
-
|
3
|
-
class TestHost
|
4
|
-
include Sanford::Host
|
5
|
-
|
6
|
-
attr_accessor :init_has_been_called
|
7
|
-
|
8
|
-
init do
|
9
|
-
self.init_has_been_called = true
|
10
|
-
end
|
11
|
-
|
12
|
-
ip 'localhost'
|
13
|
-
port 12000
|
14
|
-
pid_file File.expand_path('../../../tmp/test_host.pid', __FILE__)
|
15
|
-
|
16
|
-
logger(Logger.new(File.expand_path("../../../log/test.log", __FILE__)).tap do |logger|
|
17
|
-
logger.level = Logger::DEBUG
|
18
|
-
end)
|
19
|
-
verbose_logging false
|
20
|
-
|
21
|
-
error do |exception, host_data, request|
|
22
|
-
if exception.kind_of?(::MyCustomError)
|
23
|
-
Sanford::Protocol::Response.new([ 987, 'custom error!' ])
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
service_handler_ns 'TestHost'
|
28
|
-
|
29
|
-
service :echo, 'Echo'
|
30
|
-
service 'bad', 'Bad'
|
31
|
-
service 'multiply', 'Multiply'
|
32
|
-
service 'halt_it', '::TestHost::HaltIt'
|
33
|
-
service 'authorized', 'Authorized'
|
34
|
-
service 'custom_error', 'CustomError'
|
35
|
-
|
36
|
-
class Echo
|
37
|
-
include Sanford::ServiceHandler
|
38
|
-
|
39
|
-
def run!
|
40
|
-
params['message']
|
41
|
-
end
|
42
|
-
|
43
|
-
end
|
44
|
-
|
45
|
-
class Bad
|
46
|
-
include Sanford::ServiceHandler
|
47
|
-
|
48
|
-
def run!
|
49
|
-
raise "hahaha"
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
class Multiply
|
54
|
-
include Sanford::ServiceHandler
|
55
|
-
|
56
|
-
def init!
|
57
|
-
@number = params['number'] || 1
|
58
|
-
end
|
59
|
-
|
60
|
-
def run!
|
61
|
-
@number * 2
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
class HaltIt
|
66
|
-
include Sanford::ServiceHandler
|
67
|
-
|
68
|
-
def run!
|
69
|
-
halt 728, {
|
70
|
-
:message => "I do what I want",
|
71
|
-
:data => [ 1, true, 'yes' ]
|
72
|
-
}
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
class Authorized
|
77
|
-
include Sanford::ServiceHandler
|
78
|
-
|
79
|
-
before_run do
|
80
|
-
halt 401, :message => "Not authorized"
|
81
|
-
end
|
82
|
-
|
83
|
-
end
|
84
|
-
|
85
|
-
::MyCustomError = Class.new(RuntimeError)
|
86
|
-
|
87
|
-
class CustomError
|
88
|
-
include Sanford::ServiceHandler
|
89
|
-
|
90
|
-
def run!
|
91
|
-
raise ::MyCustomError
|
92
|
-
end
|
93
|
-
|
94
|
-
end
|
95
|
-
|
96
|
-
end
|
97
|
-
|
98
|
-
class MyHost
|
99
|
-
include Sanford::Host
|
100
|
-
|
101
|
-
name 'my_host'
|
102
|
-
ip 'my.local'
|
103
|
-
pid_file File.expand_path('../../../tmp/my_host.pid', __FILE__)
|
104
|
-
end
|
105
|
-
|
106
|
-
class InvalidHost
|
107
|
-
include Sanford::Host
|
108
|
-
|
109
|
-
name 'invalid_host'
|
110
|
-
end
|
111
|
-
|
112
|
-
class UndefinedHandlersHost
|
113
|
-
include Sanford::Host
|
114
|
-
|
115
|
-
port 12345
|
116
|
-
|
117
|
-
service 'undefined', 'ThisIsNotDefined'
|
118
|
-
|
119
|
-
end
|
120
|
-
|
121
|
-
class EmptyHost
|
122
|
-
include Sanford::Host
|
123
|
-
end
|