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
Returns the logger object that was set via
Newman::Server#logger=, or delegates todefault_loggerif no custom logger was provided. -
#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#simpleis the same asNewman::Server#simple!, but automatically starts an infinite polling loop. -
.simple!(app, settings_file) ⇒ Object
Newman::Server.simple!automatically generates aNewman::Mailerobject andNewman::Settingsobject from the providedsettings_file. -
.test_mode(settings_file) ⇒ Object
Newman::Server.test_modeautomatically generates aNewman::TestMailerobject andNewman::Settingsobject from the providedsettings_file.
Instance Method Summary collapse
-
#initialize(settings, mailer) ⇒ Server
constructor
To initialize a
Newman::Serverobject, a settings object and mailer object must be provided. -
#run ⇒ Object
Newman::Server.runkicks off a busy wait loop, alternating between callingNewman::Server.tickand sleeping for the amount of time specified bysettings.service.polling_interval. -
#tick ⇒ Object
Newman::Server.tickruns the following sequence for each incoming request.
Constructor Details
#initialize(settings, mailer) ⇒ Server
To initialize a Newman::Server object, a settings object and mailer object must
be provided.
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 for an example of how this approach works.
118 119 120 121 122 |
# File 'lib/newman/server.rb', line 118 def initialize(settings, mailer) self.settings = settings self.mailer = mailer 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.
132 133 134 |
# File 'lib/newman/server.rb', line 132 def apps @apps end |
#logger ⇒ Object
Returns the logger object that was set via Newman::Server#logger=,
or delegates to default_logger if no custom logger was provided.
140 141 142 |
# File 'lib/newman/server.rb', line 140 def logger @logger || default_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.
132 133 134 |
# File 'lib/newman/server.rb', line 132 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.
132 133 134 |
# File 'lib/newman/server.rb', line 132 def settings @settings end |
Class Method Details
.simple(app, settings_file) ⇒ Object
Newman::Server#simple is the same as Newman::Server#simple!, but
automatically starts an infinite polling loop.
66 67 68 69 |
# File 'lib/newman/server.rb', line 66 def self.simple(app, settings_file) server = simple!(app, settings_file) server.run end |
.simple!(app, settings_file) ⇒ Object
Newman::Server.simple! automatically generates a Newman::Mailer object
and Newman::Settings object from the provided settings_file. These
objects are then passed on to Newman::Server.new and a server instance
is created.
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
s = Newman::Server.simple!(ping_pong, "config/environment.rb")
# call s.tick or s.run at some later point.
Given a proper configuration file, this will make it possible to easily get your applications up and running with simple request and response logging enabled.
52 53 54 55 56 57 58 59 |
# File 'lib/newman/server.rb', line 52 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 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.
100 101 102 103 104 105 |
# File 'lib/newman/server.rb', line 100 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.
153 154 155 156 157 158 |
# File 'lib/newman/server.rb', line 153 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.
-
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. -
The list of
appsis iterated over sequentially, and each application'scallmethod is invoked with a parameters hash which include therequestemail, theresponseemail, thesettingsobject being used by the server, and theloggerobject 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.
2b) If there are any server errors (such as an error retrieving messages via IMAP), those errors are logged and re-raised, taking the server down. Currently, you should use a process watcher to restart Newman to protect against such failures, but be careful about restarting without knowing what went wrong!
- Assuming an exception is not encountered, the response is delivered.
190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 |
# File 'lib/newman/server.rb', line 190 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 rescue Exception => e logger.fatal("Caught exception: #{e}\n\n#{e.backtrace.join("\n")}") raise end |