Sanford
Sanford: simple hosts for Sanford services. Define hosts for versioned services. Setup handlers for the services. Run the host as a daemon.
Sanford uses Sanford::Protocol to communicate with clients.
Usage
# define a host
class MyHost
include Sanford::Host
port 8000
pid_dir '/path/to/pids'
# define some services
version 'v1' do
service 'get_user', 'MyHost::V1Services::GetUser'
end
end
# define handlers for the services
class MyHost::V1Services::GetUser
include Sanford::ServiceHandler
def run!
# process the service call and build a response
# the return value of this method will be used as the response data
end
end
Hosts
To define a Sanford host, include the mixin Sanford::Host
on a class and use the DSL to configure it. A few options can be set:
ip
- (string) A hostname or IP address for the server to bind to; default:'0.0.0.0'
.port
- (integer) The port number for the server to bind to.pid_dir
- (string) Path to the directory where you want the pid file to be written; default:Dir.pwd
.logger
- (logger) A logger for Sanford to use when handling requests; default:Logger.new
.
Any values specified using the DSL act as defaults for instances of the host. You can overwritten when creating new instances:
host = MyHost.new({ :port => 12000 })
Services
class MyHost
include Sanford::Host
version 'v1' do
service 'get_user', 'MyHost::ServicesV1::GetUser'
end
end
Services are defined on hosts by version. Each named service maps to a 'service handler' class. The version and service name are used to 'route' requests to handler classes.
When defining services handlers, it's typical to organize them all under a common namespace. Use service_handler_ns
to define a default namespace for all handler classes under the version:
class MyHost
include Sanford::Host
version 'v1' do
service_handler_ns 'MyHost::ServicesV1'
service 'get_user', 'GetUser'
service 'get_article', 'GetArticle'
service 'get_comments', '::MyHost::OtherServices::GetComments'
end
end
Service Handlers
Define handlers by mixing in Sanford::ServiceHandler
on a class and defining a run!
method:
class MyHost::Services::GetUser
include Sanford::ServiceHandler
def run!
# process the service call and generate a response
# the return value of this method will be used as
# the response data returned to the client
end
end
This is the most basic way to define a service handler. In addition to this, the init!
method can be overwritten. This will be called after an instance of the service handler is created. The init!
method is intended as a hook to add constructor logic. The initialize
method should not be overwritten.
In addition to these, there are some helpers methods that can be used in your run!
method:
request
: returns the request object the host receivedparams
: returns the params payload from the request objecthalt
: stop processing and return response data with a status code and message
class MyHost::Services::GetUser
include Sanford::ServiceHandler
def run!
User.find(params['user_id']).attributes
rescue NotFoundException => e
halt :not_found, :message => e., :data => request.params
rescue Exception => e
halt :error, :message => e.
end
end
Running Host Daemons
Sanford comes with rake tasks for running hosts:
rake sanford:start
- spin up a background process running the host daemon.rake sanford:stop
- shutdown the background process running the host gracefully.rake sanford:restart
- runs the stop and then the start tasks.rake sanford:run
- starts the server, but don't daemonize it (runs in the current ruby process). Convenient when using the server in a development environment.
These can be installed by requiring it's rake tasks in your Rakefile
:
require 'sanford/rake'
The basic rake tasks are useful if your application only has one host defined and if you only want to run the host on a single port. In the case you have multiple hosts defined or you want to run a single host on multiple ports, use environment variables to set custom configurations.
rake sanford:start # starts the first defined host
SANFORD_HOST=AnotherHost SANFORD_PORT=13001 rake sanford:start # choose a specific host and port to run on with ENV vars
The rake tasks allow using environment variables for specifying which host to run the command against and for overriding the host's configuration. They recognize the following environment variables: SANFORD_HOST
, SANFORD_IP
, and SANFORD_PORT
.
Define a name
on a Host to set a string name for your host that can be used to reference a host when using the rake tasks. If no name is set, Sanford will use the host's class name.
Loading An Application
Typically, a Sanford host is part of a larger application and parts of the application need to be setup or loaded when you start your Sanford server. The task sanford:setup
is called before running any start, stop, or restart task; override it to hook in your application setup code:
# In your Rakefile
namespace :sanford do
task :setup do
require 'config/environment'
end
end
Contributing
- Fork it
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create new Pull Request