Here is one suggestion:
First, divide the example that you specified (at least) into two files: One file contains the application definition, which in your example is the value of the app parameter for the Rhttpd$add() function. Another file is RScript, which launches the application defined in the first file.
For example, if the name of your application function has the name pingpong defined in a file called Rook.R , then Rscript might look something like this:
#!/usr/bin/Rscript --default-packages=methods,utils,stats,Rook # This script takes as a single argument the port number on which to listen. args <- commandArgs(trailingOnly=TRUE) if (length(args) < 1) { cat(paste("Usage:", substring(grep("^--file=", commandArgs(), value=T), 8), "<port-number>\n")) quit(save="no", status=1) } else if (length(args) > 1) cat("Warning: extra arguments ignored\n") s <- Rhttpd$new() app <- RhttpdApp$new(name='pingpong', app='Rook.R') s$add(app) s$start(port=args[1], quiet=F) suspend_console()
As you can see, this script takes one argument that defines the listening port. Now you can create a shell script that will call this Rscript several times to start multiple instances of your server, listening on different ports to enable some concurrency in response to HTTP requests.
For example, if the Rscript above is in a file called start.r , then such a shell script might look something like this:
#!/bin/sh if [ $# -lt 2 ]; then echo "Usage: $0 <start-port> <instance-count>" exit 1 fi start_port=$1 instance_count=$2 end_port=$((start_port + instance_count - 1)) fifo=/tmp/`basename $0`$$ exit_command="echo $(basename $0) exiting; rm $fifo; kill \$(jobs -p)" mkfifo $fifo trap "$exit_command" INT TERM cd `dirname $0` for port in $(seq $start_port $end_port) do ./start.r $port & done
The above shell script takes two arguments: (1) the lowest port number to listen on and (2) the number of instances to run. For example, if the shell script is in an executable file called start.sh , then
./start.sh 9000 3
will launch three instances of your Rook application listening on ports 9000, 9001, and 9002, respectively.
You see that the last line of the shell script reads from fifo, which prevents the script from exiting until it is called by the received signal. When one of the specified signals is trapped, the shell script destroys all the processes of the Rook server that it started before it exited.
Now you can configure a reverse proxy to forward incoming requests to any of the server instances. For example, if you use Nginx , your configuration might look something like this:
upstream rookapp { server localhost:9000; server localhost:9001; server localhost:9002; } server { listen your.ip.number.here:443; location /pingpong/ { proxy_pass http://rookapp/custom/pingpong/; } }
Your service may then be available on the public Internet.
The last step is to create a script control with parameters such as start (to call the above shell script) and stop (to send a TERM signal to stop your servers). Such a script will handle things like launching a shell script to run as a daemon and tracking its process id. Install this script control in the appropriate location and it will start the Rook application servers when the machine boots. How to do this will depend on your operating system, the identity of which is not in your question.
Notes
For an example of how a fifo in a shell script can be used to take various actions based on received signals, see this question .
Jeffrey Horner presented an example of a complete Rook server application .
You will see that the example shell script exceeds only INT and TERM traps. I chose those because INT result of entering a-C control command on the terminal, and TERM is the signal used by the control scripts in my operating system to stop the services. You can customize the selection of signals for the trap depending on your circumstances.