Sanford TCP protocol server for hosting services. Define servers for services. Setup handlers for the services. Run the server as a daemon.
# define a server class MyServer include :: port 8000 pid_file '/path/to/server.pid' # define some services router do service 'get_user', 'MyServer::GetUser' end end # define handlers for the services class MyServer::GetUser include :: 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
To define a Sanford server, include the mixin
Sanford::Server on a class and use the DSL to configure it. A few options can be set:
name- (string) A name for the server, this is used to set the process name and in logging.
ip- (string) A hostname or IP address for the server to bind to; default:
port- (integer) The port number for the server to bind to.
pid_file- (string) Path to where you want the pid file to be written.
logger- (logger) A logger for Sanford to use when handling requests; default:
class MyServer include :: router do service 'get_user', 'MyServer::GetUser' end end
Services are defined on servers via a router block. Each named service maps to a 'service handler' class. The service name is 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 MyServer include :: router do service_handler_ns 'MyServer' service 'get_user', 'GetUser' service 'get_article', 'GetArticle' service 'get_comments', '::OtherServices::GetComments' end end
Define handlers by mixing in
Sanford::ServiceHandler on a class and defining a
class MyServer::GetUser include :: 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
request: returns the request object the host received
params: returns the params payload from the request object
halt: stop processing and return response data with a status code and message
class MyServer::GetUser include :: 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
To run a server, Sanford needs a config file to be defined:
require 'my_server' run MyServer.new
This file works like a rackup file. You require in your server and call
passing an instance of the server. To use these files, Sanford comes with a CLI:
sanford CONFIG_FILE start- spin up a background process running the server.
sanford CONFIG_FILE stop- shutdown the background process running the server gracefully.
sanford CONFIG_FILE restart- "hot restart" the process running the server.
sanford CONFIG_FILE run- starts the server, but doesn't daemonize it (runs in the current ruby process). Convenient when using the server in a development environment.
Sanford will use the configuration of your server to either start a process or manage an existing one. A servers ip and port can be overwritten using environment variables:
sanford my_server.sanford start # starts a process for `MyServer` SANFORD_IP="18.104.22.168" SANFORD_PORT=13001 sanford my_server.sanford start # run the same server on a custom ip and port
This allows running multiple instances of the same server on ips and ports that are different than its configuration if needed.
- 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