Browse files

Update docs and examples for environment variable interface

  • Loading branch information...
1 parent c2edca3 commit ba1a2d67152ee1a3d9c683cd3b59185f490a8cb9 @gdb gdb committed Sep 27, 2012
Showing with 25 additions and 29 deletions.
  1. +13 −14 bin/einhorn
  2. +5 −4 example/thin_example
  3. +7 −11 example/time_server
@@ -45,24 +45,23 @@ You can communicate your running Einhorn process via `einhornsh`:
If your process is a server and listens on one or more sockets,
Einhorn can open these sockets and pass them to the workers. You can
-specify the addresses to bind by setting the EINHORN_SRVS environment
-variable to an address or an array of addresses:
+specify the addresses to bind by passing one or more `-b ADDR`
+ einhorn -b my-command
+ einhorn -b,r -b my-command
Each address is specified as an ip/port pair, possibly accompanied by options:
ADDR := (IP:PORT)[<,OPT>...]
-The opened file descriptors will be represented as an array in EINHORN_FDS:
+In the worker process, the opened file descriptors will be represented
+as a space-separated list of file descriptor numbers in the
+EINHORN_FDS environment variable (respecting the order that the `-b`
+options were provided in):
- EINHORN_FDS = [FD, FD, ...]
-Where each FD is the file descriptor number of the corresponding
-socket. If EINHORN_SRVS is a string, EINHORN_FDS will be a 1-element
+ EINHORN_FDS="6 7" #,r
Valid opts are:
@@ -71,11 +70,11 @@ Valid opts are:
You can for example run:
- $ EINHORN_SRVS=,r einhorn -m manual -n 4 example/time_server
+ $ einhorn -b,r -m manual -n 4 -- example/time_server
Which will run 4 copies of
- EINHORN_FDS=[6] example/time_server
+ EINHORN_FDS=6 example/time_server
Where file descriptor 6 is a server socket bound to ``
and with `SO_REUSEADDR` set. It is then your application's job to
@@ -131,7 +130,7 @@ string
to the UNIX socket pointed to by the environment variable
`EINHORN_SOCK_PATH`. (Be sure to include a trailing newline.)
-To make things even easier, you can pass a `-b` to Einhorn, in which
+To make things even easier, you can pass a `-g` to Einhorn, in which
case you just need to `write()` the above message to the open file
descriptor pointed to by `EINHORN_SOCK_FD`.
@@ -28,8 +28,10 @@ end
def einhorn_main
puts "Called with #{ARGV.inspect}"
- if ARGV.length == 0
- raise "Need to call with at least one argument. Try running 'einhorn #{$0} srv:,r,n srv:,r,n' and then running 'curl' or 'curl'"
+ einhorn_fds = Einhorn::Worker.einhorn_fds
+ unless einhorn_fds
+ raise "Need to call with at least one bound socket. Try running 'einhorn -b,r,n -b,r,n #{$0}' and then running 'curl' or 'curl'"
Einhorn::Worker.graceful_shutdown do
@@ -39,8 +41,7 @@ def einhorn_main
Einhorn::Worker.ack! do
- ARGV.each_with_index do |arg, i|
- sock = Integer(arg)
+ einhorn_fds.each_with_index do |sock, i|
srv =,, :reuse => true)
@@ -1,28 +1,24 @@
#!/usr/bin/env ruby
# A simple example showing how to use Einhorn's shared-socket
-# features. Einhorn translates the srv:(addr:port[,flags...]) spec in
-# the arg string into a file descriptor number.
+# features. Einhorn translates the (addr:port[,flags...]) bind spec in
+# into a file descriptor number in the EINHORN_FDS environment variable.
# Invoke through Einhorn as
-# einhorn ./time_server srv:,r
+# einhorn -b,r ./time_server
# or, if you want to try out preloading:
-# einhorn -p ./time_server ./time_server srv:,r
+# einhorn -b,r -p ./time_server ./time_server
require 'rubygems'
require 'einhorn/worker'
def einhorn_main
- puts "Called with #{ARGV.inspect}"
- if ARGV.length != 1
- raise "Need to call with a port spec as the first argument. Try running 'einhorn #{$0} srv:,r' and then running 'nc 2345'"
- end
+ puts "Called with ENV['EINHORN_FDS']: #{ENV['EINHORN_FDS']}"
- socket = Socket.for_fd(Integer(ARGV[0]))
+ fd_num = Einhorn::Worker.socket!
+ socket = Socket.for_fd(fd_num)
# Came up successfully, so let's set up graceful handler and ACK the
# master.

0 comments on commit ba1a2d6

Please sign in to comment.