sanford 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. data/bench/report.txt +34 -4
  2. data/bench/runner.rb +122 -1
  3. data/bench/services.rb +5 -2
  4. data/lib/sanford/error_handler.rb +60 -0
  5. data/lib/sanford/exceptions.rb +11 -10
  6. data/lib/sanford/host.rb +79 -101
  7. data/lib/sanford/host_data.rb +55 -0
  8. data/lib/sanford/logger.rb +23 -0
  9. data/lib/sanford/manager.rb +13 -22
  10. data/lib/sanford/rake.rb +1 -0
  11. data/lib/sanford/runner.rb +50 -0
  12. data/lib/sanford/server.rb +31 -15
  13. data/lib/sanford/service_handler.rb +34 -43
  14. data/lib/sanford/test_runner.rb +47 -0
  15. data/lib/sanford/version.rb +1 -1
  16. data/lib/sanford/worker.rb +124 -0
  17. data/lib/sanford.rb +49 -6
  18. data/sanford.gemspec +1 -1
  19. data/test/helper.rb +1 -0
  20. data/test/support/fake_connection.rb +18 -0
  21. data/test/support/helpers.rb +6 -10
  22. data/test/support/service_handlers.rb +56 -68
  23. data/test/support/services.rb +55 -10
  24. data/test/system/managing_test.rb +18 -18
  25. data/test/system/request_handling_test.rb +10 -100
  26. data/test/unit/config_test.rb +1 -43
  27. data/test/unit/error_handler_test.rb +133 -0
  28. data/test/unit/host_configuration_test.rb +41 -0
  29. data/test/unit/host_data_test.rb +65 -0
  30. data/test/unit/host_test.rb +20 -112
  31. data/test/unit/{host/version_group_test.rb → host_version_group_test.rb} +0 -0
  32. data/test/unit/hosts_test.rb +56 -0
  33. data/test/unit/manager_test.rb +3 -3
  34. data/test/unit/runner_test.rb +26 -0
  35. data/test/unit/server_test.rb +10 -2
  36. data/test/unit/service_handler_test.rb +126 -115
  37. data/test/unit/worker_test.rb +195 -0
  38. metadata +28 -16
  39. data/lib/sanford/config.rb +0 -33
  40. data/lib/sanford/connection.rb +0 -70
  41. data/lib/sanford/exception_handler.rb +0 -43
  42. data/test/unit/connection_test.rb +0 -23
  43. data/test/unit/exception_handler_test.rb +0 -69
data/bench/report.txt CHANGED
@@ -2,9 +2,39 @@ Running benchmark report...
2
2
 
3
3
  Hitting "simple" service with {}, 10000 times
4
4
  ....................................................................................................
5
- Total Time: 15768.8473ms
6
- Average Time: 1.5768ms
7
- Min Time: 0.9949ms
8
- Max Time: 102.2670ms
5
+ Total Time: 10195.4432ms
6
+ Average Time: 1.0195ms
7
+ Min Time: 0.7040ms
8
+ Max Time: 117.8309ms
9
+
10
+ Distribution (number of requests):
11
+ 0ms: 8897
12
+ 0.7ms: 6897
13
+ 0.8ms: 1451
14
+ 0.9ms: 549
15
+ 1ms: 1049
16
+ 1.0ms: 308
17
+ 1.1ms: 236
18
+ 1.2ms: 198
19
+ 1.3ms: 134
20
+ 1.4ms: 66
21
+ 1.5ms: 44
22
+ 1.6ms: 26
23
+ 1.7ms: 18
24
+ 1.8ms: 15
25
+ 1.9ms: 4
26
+ 117ms: 1
27
+ 2ms: 24
28
+ 3ms: 7
29
+ 4ms: 2
30
+ 82ms: 1
31
+ 83ms: 1
32
+ 84ms: 3
33
+ 85ms: 2
34
+ 86ms: 2
35
+ 88ms: 3
36
+ 89ms: 4
37
+ 90ms: 2
38
+ 91ms: 2
9
39
 
10
40
  Done running benchmark report
data/bench/runner.rb CHANGED
@@ -43,10 +43,11 @@ module Bench
43
43
  output("\n", false)
44
44
 
45
45
  total_time = benchmarks.inject(0){|s, n| s + n }
46
+ average = total_time / benchmarks.size
46
47
  data = {
47
48
  :number_of_requests => times,
48
49
  :total_time_taken => self.round_and_display(total_time),
49
- :average_time_taken => self.round_and_display(total_time / benchmarks.size),
50
+ :average_time_taken => self.round_and_display(average),
50
51
  :min_time_taken => self.round_and_display(benchmarks.min),
51
52
  :max_time_taken => self.round_and_display(benchmarks.max)
52
53
  }
@@ -55,6 +56,19 @@ module Bench
55
56
  output "Average Time: #{data[:average_time_taken].rjust(size)}ms"
56
57
  output "Min Time: #{data[:min_time_taken].rjust(size)}ms"
57
58
  output "Max Time: #{data[:max_time_taken].rjust(size)}ms"
59
+
60
+ output "\n"
61
+
62
+ distribution = Distribution.new(benchmarks)
63
+
64
+ output "Distribution (number of requests):"
65
+ distribution.each do |grouping|
66
+ output " #{grouping.time}ms: #{grouping.number_of_requests}"
67
+ grouping.precise_groupings.each do |precise_grouping|
68
+ output " #{precise_grouping.time}ms: #{precise_grouping.number_of_requests}"
69
+ end
70
+ end
71
+
58
72
  output "\n"
59
73
  end
60
74
 
@@ -97,6 +111,113 @@ module Bench
97
111
  [ integer, fractional.ljust(4, '0') ].join('.')
98
112
  end
99
113
 
114
+ class Distribution
115
+
116
+ def initialize(benchmarks)
117
+ hash = benchmarks.inject({}) do |hash, benchmark|
118
+ index = Index.new(benchmark).number
119
+ hash[index] ||= Grouping.new(index)
120
+ hash[index].add(benchmark)
121
+ hash
122
+ end
123
+ @groupings = hash.values.sort
124
+ end
125
+
126
+ def each(&block)
127
+ @groupings.each(&block)
128
+ end
129
+
130
+ class BaseGrouping
131
+
132
+ def self.max_time(time = nil)
133
+ size = time.to_s.size
134
+ @max_time = size if size > @max_time.to_i
135
+ @max_time
136
+ end
137
+
138
+ def self.max_number(number = nil)
139
+ size = number.to_s.size
140
+ @max_size = size if size > @max_size.to_i
141
+ @max_size
142
+ end
143
+
144
+ attr_reader :name
145
+
146
+ def initialize(index)
147
+ @name = index.to_s
148
+ @set = []
149
+ self.class.max_time(index.to_s.size)
150
+ end
151
+
152
+ def add(benchmark)
153
+ result = @set.push(benchmark)
154
+ self.class.max_number(@set.size.to_s.size)
155
+ result
156
+ end
157
+
158
+ def time
159
+ @name.rjust(self.class.max_time)
160
+ end
161
+
162
+ def number_of_requests
163
+ @set.size.to_s.rjust(self.class.max_number)
164
+ end
165
+
166
+ def <=>(other)
167
+ self.name.to_f <=> other.name.to_f
168
+ end
169
+
170
+ end
171
+
172
+ class Grouping < BaseGrouping
173
+
174
+ def initialize(index)
175
+ super
176
+ @precise_groupings = {}
177
+ end
178
+
179
+ def add(benchmark)
180
+ add_precise_grouping(benchmark) if self.collect_precise?
181
+ super(benchmark)
182
+ end
183
+
184
+ def collect_precise?
185
+ @name.to_i <= 1
186
+ end
187
+
188
+ def precise_groupings
189
+ @precise_groupings.values.sort
190
+ end
191
+
192
+ protected
193
+
194
+ def add_precise_grouping(benchmark)
195
+ index = PreciseIndex.new(benchmark).number
196
+ @precise_groupings[index] ||= BaseGrouping.new(index)
197
+ @precise_groupings[index].add(benchmark)
198
+ end
199
+
200
+ end
201
+
202
+ class Index < Struct.new(:number)
203
+
204
+ def initialize(benchmark)
205
+ super benchmark.to_i
206
+ end
207
+ end
208
+
209
+ class PreciseIndex < Struct.new(:number)
210
+
211
+ MODIFIER = 10.to_f
212
+
213
+ def initialize(benchmark)
214
+ super((benchmark * MODIFIER).to_i / MODIFIER)
215
+ end
216
+
217
+ end
218
+
219
+ end
220
+
100
221
  end
101
222
 
102
223
  end
data/bench/services.rb CHANGED
@@ -1,8 +1,11 @@
1
1
  class BenchHost
2
2
  include Sanford::Host
3
3
 
4
- self.port = 12000
5
- self.pid_dir = File.expand_path("../../tmp", __FILE__)
4
+ port 12000
5
+ pid_dir File.expand_path("../../tmp", __FILE__)
6
+
7
+ logger Logger.new(STDOUT)
8
+ verbose_logging false
6
9
 
7
10
  version 'v1' do
8
11
  service 'simple', 'BenchHost::Simple'
@@ -0,0 +1,60 @@
1
+ require 'ostruct'
2
+ require 'sanford-protocol'
3
+
4
+ module Sanford
5
+
6
+ class ErrorHandler
7
+
8
+ attr_reader :exception, :host_data, :request
9
+
10
+ def initialize(exception, host_data, request = nil)
11
+ @exception, @host_data, @request = exception, host_data, request
12
+ end
13
+
14
+ # The exception that we are generating a response for can change in the case
15
+ # that the configured error proc raises an exception. If this occurs, a
16
+ # response will be generated for that exception, instead of the original
17
+ # one. This is designed to avoid "hidden" errors happening, this way the
18
+ # server will respond and log based on the last exception that occurred.
19
+
20
+ def run
21
+ begin
22
+ result = @host_data.error_proc.call(@exception, @host_data, @request)
23
+ rescue Exception => proc_exception
24
+ @exception = proc_exception
25
+ end
26
+ self.response_from_proc(result) || self.response_from_exception(@exception)
27
+ end
28
+
29
+ protected
30
+
31
+ def response_from_proc(result)
32
+ case result
33
+ when Sanford::Protocol::Response
34
+ result
35
+ when Integer, Symbol
36
+ build_response result
37
+ end
38
+ end
39
+
40
+ def response_from_exception(exception)
41
+ case(exception)
42
+ when Sanford::Protocol::BadMessageError, Sanford::Protocol::BadRequestError
43
+ build_response :bad_request, :message => exception.message
44
+ when Sanford::NotFoundError
45
+ build_response :not_found
46
+ when Sanford::Protocol::TimeoutError
47
+ build_response :timeout
48
+ when Exception
49
+ build_response :error, :message => "An unexpected error occurred."
50
+ end
51
+ end
52
+
53
+ def build_response(status, options = nil)
54
+ options = OpenStruct.new(options || {})
55
+ Sanford::Protocol::Response.new([ status, options.message ], options.data)
56
+ end
57
+
58
+ end
59
+
60
+ end
@@ -1,37 +1,38 @@
1
1
  module Sanford
2
2
 
3
- class BaseError < RuntimeError; end
3
+ BaseError = Class.new(RuntimeError)
4
4
 
5
- class NotFoundError < BaseError; end
5
+ NotFoundError = Class.new(RuntimeError)
6
6
 
7
7
  class NoHostError < BaseError
8
8
  attr_reader :message
9
9
 
10
10
  def initialize(host_name)
11
- @message = if Sanford.config.hosts.empty?
12
- "No hosts have been defined. " \
13
- "Please define a host before trying to run Sanford."
11
+ message = if Sanford.hosts.empty?
12
+ "No hosts have been defined. Please define a host before trying to run Sanford."
14
13
  else
15
14
  "A host couldn't be found with the name #{host_name.inspect}. "
16
15
  end
16
+ super message
17
17
  end
18
+
18
19
  end
19
20
 
20
21
  class InvalidHostError < BaseError
21
- attr_reader :message
22
22
 
23
23
  def initialize(host)
24
- @message = "A port must be configured or provided to build an instance of '#{host}'"
24
+ super "A port must be configured or provided to run a server for '#{host}'"
25
25
  end
26
+
26
27
  end
27
28
 
28
29
  class NoHandlerClassError < BaseError
29
- attr_reader :message
30
30
 
31
- def initialize(host, handler_class_name)
32
- @message = "Sanford couldn't find the service handler '#{handler_class_name}'." \
31
+ def initialize(handler_class_name)
32
+ super "Sanford couldn't find the service handler '#{handler_class_name}'. " \
33
33
  "It doesn't exist or hasn't been required in yet."
34
34
  end
35
+
35
36
  end
36
37
 
37
38
  end
data/lib/sanford/host.rb CHANGED
@@ -1,136 +1,93 @@
1
- # Sanford's Host mixin is used to define service hosts. When mixed into a class
2
- # it provides the interface for configuring the service host and for adding
3
- # versioned services. It also contains the logic for routing a request to a
4
- # a service handler.
5
- #
6
- # Options:
7
- # * `name` - A string for naming this host. This can be used when specifying
8
- # a host with the rake tasks and will be used to name the PID
9
- # file. Defaults to the class's name.
10
- # * `ip` - The string for the ip that the TCP Server should bind to. This
11
- # defaults to '0.0.0.0'.
12
- # * `port` - The integer for the port that the TCP Server should bind to.
13
- # This isn't defaulted and must be provided.
14
- # * `pid_dir` - The directory to write the PID file to. This is defaulted to
15
- # Dir.pwd.
16
- # * `logger` - The logger to use if the Sanford server logs messages. This is
17
- # defaulted to an instance of Ruby's Logger.
18
- #
19
- require 'logger'
20
1
  require 'ns-options'
21
2
  require 'pathname'
22
3
 
23
- require 'sanford/config'
24
- require 'sanford/exception_handler'
25
4
  require 'sanford/exceptions'
26
- require 'sanford/service_handler'
5
+ require 'sanford/logger'
27
6
 
28
7
  module Sanford
8
+
29
9
  module Host
30
10
 
31
- # Notes:
32
- # * When Host is included on a class, it needs to mixin NsOptions and define
33
- # the options directly on the class (instead of on the Host module).
34
- # Otherwise, NsOptions will not work correctly for the class.
35
- def self.included(host_class)
36
- host_class.class_eval do
37
- include NsOptions
38
- extend Sanford::Host::Interface
39
-
40
- options :config do
41
- option :name, String, :default => host_class.to_s
42
- option :ip, String, :default => '0.0.0.0'
43
- option :port, Integer
44
- option :pid_dir, Pathname, :default => Dir.pwd
45
- option :logger, :default => proc{ Sanford::NullLogger.new }
46
-
47
- option :exception_handler, :default => Sanford::ExceptionHandler
48
- option :versioned_services, Hash, :default => {}
49
- end
11
+ class Configuration
12
+ include NsOptions::Proxy
13
+
14
+ # A Host's configuration is a seperate ns-options proxy class because
15
+ # `Host` is a module, so it itself cannot be a ns-options proxy (and
16
+ # still function as a mixin). Also, since it is making the `Host`
17
+ # a `Singleton`, mixing that with `NsOptions::Proxy` could have strange
18
+ # effects (messing up someone's `initialize`). Thus, the `Configuration`
19
+ # is a separate class and not on the `Host` directly.
20
+
21
+ option :name, String
22
+ option :ip, String, :default => '0.0.0.0'
23
+ option :port, Integer
24
+ option :pid_dir, Pathname, :default => Dir.pwd
25
+ option :logger, :default => proc{ Sanford::NullLogger.new }
26
+ option :verbose_logging, :default => true
27
+ option :error_proc, Proc, :default => proc{ }
28
+
29
+ def initialize(host)
30
+ self.name = host.class.to_s
50
31
  end
51
- Sanford.config.hosts.add(host_class)
52
- end
53
32
 
54
- INTERFACE_OPTIONS = [ :name, :ip, :port, :pid_dir, :logger, :exception_handler ]
55
-
56
- # Notes:
57
- # * The `initialize` takes the values configured on the class and merges
58
- # the passed in options. This is used to set the individual instance's
59
- # configuration (which allows overwriting options like the port).
60
- def initialize(options = nil)
61
- options = self.remove_nil_values(options)
62
- config_options = self.class.config.to_hash.merge(options)
63
- self.config.apply(config_options)
64
- raise(Sanford::InvalidHostError.new(self.class)) if !self.port
65
33
  end
66
34
 
67
- INTERFACE_OPTIONS.each do |name|
68
-
69
- define_method(name) do
70
- self.config.send(name)
35
+ def self.included(host_class)
36
+ host_class.class_eval do
37
+ include Singleton
38
+ extend Sanford::Host::ClassMethods
71
39
  end
72
-
40
+ Sanford.register(host_class)
73
41
  end
74
42
 
75
- def run(request)
76
- request_handler(request).run
77
- end
43
+ attr_reader :configuration, :versioned_services
78
44
 
79
- def inspect
80
- reference = '0x0%x' % (self.object_id << 1)
81
- "#<#{self.class}:#{reference} ip=#{self.config.ip.inspect} " \
82
- "port=#{self.config.port.inspect}>"
45
+ def initialize
46
+ @configuration = Configuration.new(self)
47
+ @versioned_services = {}
83
48
  end
84
49
 
85
- protected
86
-
87
- def request_handler(request)
88
- handler_class(get_handler_class_name(request)).new(self.logger, request)
50
+ def name(*args)
51
+ self.configuration.name *args
89
52
  end
90
53
 
91
- def handler_class(class_name_str)
92
- self.logger.info(" Handler: #{class_name_str.inspect}")
93
- Sanford::ServiceHandler.constantize(class_name_str).tap do |handler_class|
94
- raise Sanford::NoHandlerClassError.new(self, class_name_str) if !handler_class
95
- end
54
+ def ip(*args)
55
+ self.configuration.ip *args
96
56
  end
97
57
 
98
- def get_handler_class_name(request)
99
- services = self.config.versioned_services[request.version] || {}
100
- services[request.name].tap do |name|
101
- raise Sanford::NotFoundError if !name
102
- end
58
+ def port(*args)
59
+ self.configuration.port *args
103
60
  end
104
61
 
105
- def remove_nil_values(options)
106
- (options || {}).inject({}) do |hash, (k, v)|
107
- hash.merge!({ k => v }) if !v.nil?
108
- hash
109
- end
62
+ def pid_dir(*args)
63
+ self.configuration.pid_dir *args
110
64
  end
111
65
 
112
- module Interface
113
-
114
- INTERFACE_OPTIONS.each do |name|
115
-
116
- define_method(name) do |*args|
117
- self.config.send("#{name}=", *args) if !args.empty?
118
- self.config.send(name)
119
- end
66
+ def logger(*args)
67
+ self.configuration.logger *args
68
+ end
120
69
 
121
- define_method("#{name}=") do |new_value|
122
- self.config.send("#{name}=", new_value)
123
- end
70
+ def verbose_logging(*args)
71
+ self.configuration.verbose_logging *args
72
+ end
124
73
 
125
- end
74
+ def error(&block)
75
+ self.configuration.error_proc = block
76
+ end
126
77
 
127
- def version(name, &block)
128
- version_group = Sanford::Host::VersionGroup.new(name, &block)
129
- self.config.versioned_services.merge!(version_group.to_hash)
130
- end
78
+ def version(name, &block)
79
+ version_group = Sanford::Host::VersionGroup.new(name, &block)
80
+ @versioned_services.merge!(version_group.to_hash)
81
+ end
131
82
 
83
+ def inspect
84
+ reference = '0x0%x' % (self.object_id << 1)
85
+ "#<#{self.class}:#{reference} ip=#{self.configuration.ip.inspect} " \
86
+ "port=#{self.configuration.port.inspect}>"
132
87
  end
133
88
 
89
+ protected
90
+
134
91
  class VersionGroup
135
92
  attr_reader :name, :services
136
93
 
@@ -158,5 +115,26 @@ module Sanford
158
115
 
159
116
  end
160
117
 
118
+ module ClassMethods
119
+
120
+ # the class level of a `Host` should just proxy it's methods down to it's
121
+ # instance (it's a `Singleton`)
122
+
123
+ # `name` is defined by all objects, so we can't rely on `method_missing`
124
+ def name(*args)
125
+ self.instance.name(*args)
126
+ end
127
+
128
+ def method_missing(method, *args, &block)
129
+ self.instance.send(method, *args, &block)
130
+ end
131
+
132
+ def respond_to?(method)
133
+ super || self.instance.respond_to?(method)
134
+ end
135
+
136
+ end
137
+
161
138
  end
139
+
162
140
  end
@@ -0,0 +1,55 @@
1
+ require 'sanford/exceptions'
2
+ require 'sanford/service_handler'
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
+ attr_reader :name, :ip, :port, :pid_dir, :logger, :verbose, :error_proc
14
+
15
+ def initialize(service_host, options = nil)
16
+ configuration = service_host.configuration.to_hash.merge(remove_nil_values(options || {}))
17
+
18
+ @name = configuration[:name]
19
+ @ip, @port = configuration[:ip], configuration[:port]
20
+ @pid_dir = configuration[:pid_dir]
21
+ @logger, @verbose = configuration[:logger], configuration[:verbose_logging]
22
+ @error_proc = configuration[:error_proc]
23
+
24
+ @handlers = service_host.versioned_services.inject({}) do |hash, (version, services)|
25
+ hash.merge({ version => self.constantize_services(services) })
26
+ end
27
+
28
+ raise Sanford::InvalidHostError.new(service_host) if !self.port
29
+ end
30
+
31
+ def handler_class_for(version, service)
32
+ version_group = @handlers[version] || {}
33
+ version_group[service] || raise(Sanford::NotFoundError)
34
+ end
35
+
36
+ protected
37
+
38
+ def constantize_services(services)
39
+ services.inject({}) do |hash, (name, handler_class_name)|
40
+ hash.merge({ name => self.constantize(handler_class_name) })
41
+ end
42
+ end
43
+
44
+ def constantize(handler_class_name)
45
+ Sanford::ServiceHandler.constantize(handler_class_name) ||
46
+ raise(Sanford::NoHandlerClassError.new(handler_class_name))
47
+ end
48
+
49
+ def remove_nil_values(hash)
50
+ hash.inject({}){|h, (k, v)| !v.nil? ? h.merge({ k => v }) : h }
51
+ end
52
+
53
+ end
54
+
55
+ end
@@ -0,0 +1,23 @@
1
+ module Sanford
2
+
3
+ class Logger
4
+ attr_reader :summary, :verbose
5
+
6
+ def initialize(logger, verbose = true)
7
+ loggers = [ logger, Sanford::NullLogger.new ]
8
+ loggers.reverse! if !verbose
9
+ @verbose, @summary = loggers
10
+ end
11
+
12
+ end
13
+
14
+ class NullLogger
15
+ require 'logger'
16
+
17
+ ::Logger::Severity.constants.each do |name|
18
+ define_method(name.downcase){|*args| } # no-op
19
+ end
20
+
21
+ end
22
+
23
+ end
@@ -1,44 +1,35 @@
1
- # The Manager class is responsible for managing sanford's server process. Given
2
- # a host, it can start and stop the host's server process. This is done using
3
- # the Daemons gem and `run_proc`. The class provides a convenience method on the
4
- # class called `call`, which will find a host, build a new manager and call the
5
- # relevant action (this is what the rake tasks use).
6
- #
7
1
  require 'daemons'
8
2
 
9
- require 'sanford/config'
10
- require 'sanford/exceptions'
3
+ require 'sanford/host_data'
11
4
  require 'sanford/server'
12
5
 
13
6
  module Sanford
14
7
 
15
8
  class Manager
16
- attr_reader :host, :process_name
17
9
 
18
10
  def self.call(action, options = nil)
19
11
  options ||= {}
20
- options[:host] ||= ENV['SANFORD_HOST']
21
12
  options[:ip] ||= ENV['SANFORD_IP']
22
13
  options[:port] ||= ENV['SANFORD_PORT']
23
14
 
24
- host_class = if (host_class_or_name = options.delete(:host))
25
- Sanford.config.find_host(host_class_or_name)
26
- else
27
- Sanford.config.hosts.first
28
- end
29
- raise(Sanford::NoHostError.new(host_class_or_name)) if !host_class
30
- self.new(host_class, options).call(action)
15
+ name = options.delete(:host) || ENV['SANFORD_HOST']
16
+ service_host = name ? Sanford.hosts.find(name) : Sanford.hosts.first
17
+ raise(Sanford::NoHostError.new(name)) if !service_host
18
+
19
+ self.new(service_host, options).call(action)
31
20
  end
32
21
 
33
- def initialize(host_class, options = {})
34
- @host = host_class.new(options)
22
+ attr_reader :host, :process_name
23
+
24
+ def initialize(service_host, options = {})
25
+ @host = Sanford::HostData.new(service_host, options)
35
26
  @process_name = [ self.host.ip, self.host.port, self.host.name ].join('_')
36
27
  end
37
28
 
38
29
  def call(action)
39
- options = self.default_options.merge({ :ARGV => [ action.to_s ] })
40
- FileUtils.mkdir_p(options[:dir])
41
- ::Daemons.run_proc(self.process_name, options) do
30
+ daemons_options = self.default_options.merge({ :ARGV => [ action.to_s ] })
31
+ FileUtils.mkdir_p(daemons_options[:dir])
32
+ ::Daemons.run_proc(self.process_name, daemons_options) do
42
33
  server = Sanford::Server.new(self.host)
43
34
  server.start
44
35
  server.join_thread
data/lib/sanford/rake.rb CHANGED
@@ -12,6 +12,7 @@ module Sanford::Rake
12
12
 
13
13
  task :load_manager => :setup do
14
14
  require 'sanford'
15
+ require 'sanford/manager'
15
16
  Sanford.init
16
17
  end
17
18