Class: Newman::Server
- Inherits:
-
Object
- Object
- Newman::Server
- Defined in:
- lib/newman/server.rb
Instance Attribute Summary collapse
-
#apps ⇒ Object
These accessors are mostly meant for use with server objects under test mode, or server objects that have been explicitly instantiated.
-
#logger ⇒ Object
These accessors are mostly meant for use with server objects under test mode, or server objects that have been explicitly instantiated.
-
#mailer ⇒ Object
These accessors are mostly meant for use with server objects under test mode, or server objects that have been explicitly instantiated.
-
#settings ⇒ Object
These accessors are mostly meant for use with server objects under test mode, or server objects that have been explicitly instantiated.
Class Method Summary collapse
-
.simple(app, settings_file) ⇒ Object
‘Newman::Server.simple` automatically generates a `Newman::Mailer` object and `Newman::Settings` object from the privded `settings_file`.
-
.test_mode(settings_file) ⇒ Object
‘Newman::Server.test_mode` automatically generates a `Newman::TestMailer` object and `Newman::Settings` object from the provided `settings_file`.
Instance Method Summary collapse
-
#initialize(settings, mailer, logger = nil) ⇒ Server
constructor
To initialize a ‘Newman::Server` object, a settings object and mailer object must be provided, and a logger object may also be provided.
-
#run ⇒ Object
‘Newman::Server.run` kicks off a busy wait loop, alternating between calling `Newman::Server.tick` and sleeping for the amount of time specified by `settings.service.polling_interval`.
-
#tick ⇒ Object
‘Newman::Server.tick` runs the following sequence for each incoming request.
Constructor Details
#initialize(settings, mailer, logger = nil) ⇒ Server
To initialize a ‘Newman::Server` object, a settings object and mailer object must be provided, and a logger object may also be provided. If a logger object is not provided, `Newman::Server#default_logger` is called to create one.
Instantiating a server object directly can be useful for building live integration tests, or for building cron jobs which process email periodically rather than in a busy-wait loop. See one of Newman’s [live tests](github.com/mendicant-university/newman/blob/master/examples/live_test.rb) for an example of how this approach works.
108 109 110 111 112 113 |
# File 'lib/newman/server.rb', line 108 def initialize(settings, mailer, logger=nil) self.settings = settings self.mailer = mailer self.logger = logger || default_logger self.apps = [] end |
Instance Attribute Details
#apps ⇒ Object
These accessors are mostly meant for use with server objects under test mode, or server objects that have been explicitly instantiated. If you are using ‘Newman::Server.simple` to run your apps, it’s safe to treat these as an implementation detail; all important data will get passed down into your apps on each ‘tick`.
123 124 125 |
# File 'lib/newman/server.rb', line 123 def apps @apps end |
#logger ⇒ Object
These accessors are mostly meant for use with server objects under test mode, or server objects that have been explicitly instantiated. If you are using ‘Newman::Server.simple` to run your apps, it’s safe to treat these as an implementation detail; all important data will get passed down into your apps on each ‘tick`.
123 124 125 |
# File 'lib/newman/server.rb', line 123 def logger @logger end |
#mailer ⇒ Object
These accessors are mostly meant for use with server objects under test mode, or server objects that have been explicitly instantiated. If you are using ‘Newman::Server.simple` to run your apps, it’s safe to treat these as an implementation detail; all important data will get passed down into your apps on each ‘tick`.
123 124 125 |
# File 'lib/newman/server.rb', line 123 def mailer @mailer end |
#settings ⇒ Object
These accessors are mostly meant for use with server objects under test mode, or server objects that have been explicitly instantiated. If you are using ‘Newman::Server.simple` to run your apps, it’s safe to treat these as an implementation detail; all important data will get passed down into your apps on each ‘tick`.
123 124 125 |
# File 'lib/newman/server.rb', line 123 def settings @settings end |
Class Method Details
.simple(app, settings_file) ⇒ Object
‘Newman::Server.simple` automatically generates a `Newman::Mailer` object and `Newman::Settings` object from the privded `settings_file`. These objects are then passed on to `Newman::Server.new` and a server instance is created. The server object is set up to run the specified `app`, with request and response logging support enabled. Calling this method puts the server in an infinite polling loop, because its final action is to call `Newman::Server.run`.
The following example demonstrates how to use this method:
ping_pong = Newman::Application.new do
subject(:match, "ping") do
respond(:subject => "pong")
end
default do
respond(:subject => "You missed the ball!")
end
end
Newman::Server.simple(ping_pong, "config/environment.rb")
Given a properly configured settings file, this code will launch a polling server and run the simple ‘ping_pong` application.
51 52 53 54 55 56 57 58 |
# File 'lib/newman/server.rb', line 51 def self.simple(app, settings_file) settings = Settings.from_file(settings_file) mailer = Mailer.new(settings) server = new(settings, mailer) server.apps = [RequestLogger, app, ResponseLogger] server.run end |
.test_mode(settings_file) ⇒ Object
‘Newman::Server.test_mode` automatically generates a `Newman::TestMailer` object and `Newman::Settings` object from the provided `settings_file`. These objects are then passed on to `Newman::Server.new` and a server instance which is preconfigured for use in integration testing is returned.
Using the application from the ‘Newman::Server.simple` documentation above, it’d be possible to write a simple integration test using this method in the following way:
server = Newman::Server.test_mode("config/environment.rb")
server.apps << ping_pong
mailer = server.mailer
mailer.deliver_message(:to => "[email protected]",
:subject => "ping)
server.tick
mailer.messages.first.subject.must_equal("pong")
It’s worth mentioning that although ‘Newman::Server.test_mode` is part of Newman’s external interface, the ‘Newman::TestMailer` object is considered part of its internals. This is due to some ugly issues with global state and the overall brittleness of the current implementation. Expect a bit of weirdness if you plan to use this feature, at least until we improve upon it.
89 90 91 92 93 94 |
# File 'lib/newman/server.rb', line 89 def self.test_mode(settings_file) settings = Settings.from_file(settings_file) mailer = TestMailer.new(settings) new(settings, mailer) end |
Instance Method Details
#run ⇒ Object
‘Newman::Server.run` kicks off a busy wait loop, alternating between calling `Newman::Server.tick` and sleeping for the amount of time specified by `settings.service.polling_interval`. We originally planned to use an EventMachine periodic timer here to potentially make running several servers within a single process easier, but had trouble coming up with a use case that made the extra dependency worth it.
134 135 136 137 138 139 |
# File 'lib/newman/server.rb', line 134 def run loop do tick sleep settings.service.polling_interval end end |
#tick ⇒ Object
‘Newman::Server.tick` runs the following sequence for each incoming request.
1) A response is generated with the TO field set to the FROM field of the request, and the FROM field set to ‘settings.service.default_sender`. Applications can change these values later, but these are sensible defaults that work for most common needs.
2) The list of ‘apps` is iterated over sequentially, and each application’s ‘call` method is invoked with a parameters hash which include the `request` email, the `response` email, the `settings` object being used by the server, and the `logger` object being used by the server.
2a) If any application raises an exception, that exception is caught and the processing of the current request is halted. Details about the failure are logged and if ‘settings.service.raise_exceptions` is enabled, the exception is re-raised, typically taking the server down with it. This setting is off by default.
3) Assuming an exception is not encountered, the response is delivered.
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 |
# File 'lib/newman/server.rb', line 165 def tick mailer..each do |request| response = mailer.(:to => request.from, :from => settings.service.default_sender) begin apps.each do |app| app.call(:request => request, :response => response, :settings => settings, :logger => logger) end rescue StandardError => e logger.info("FAIL") { e.to_s } logger.debug("FAIL") { "#{e.inspect}\n"+e.backtrace.join("\n ") } if settings.service.raise_exceptions raise else next end end response.deliver end end |