4

I need to start and keep running the rserve from R.

I have these lines in my rserve.r file:

library(Rserve)
Rserve()

So, I'm trying to do something like this in my upstart script:

description "Rserve service"
author      "Valter Silva"

start on filesystem or runlevel [2345]
stop on shutdown

respawn

script
    echo $$ > /var/run/rserve.pid
    exec /usr/bin/R /home/valter/R/rserve.R >> /home/valter/test2.log
end script


pre-start script
    echo "[`date`] Rserve Starting" >> /var/log/rserve.log
end script

pre-stop script
    rm /var/run/rserve.pid
    echo "[`date`] Rserve Stopping" >> /var/log/rserve.log
end script

I know that the service runs because of the output of my file test2.log. But it runs only once. What should I do to keep it running ?

Valter Silva
  • 16,446
  • 52
  • 137
  • 218

2 Answers2

1

The reason that you (and I) are having so much trouble is that we're asking the wrong question. The correct question is "how can we launch Rserve from our client code?" Java (and most other) clients have the capability to StartRserve.

The answer to that question is here for the java library: How to start Rserve automatically from Java?

or here for the C# library: https://github.com/SurajGupta/RserveCLI2/blob/master/RServeCLI2.Test/Rservice.cs


Another approach would be to learn from the best. The Rocker project copies supervisor.conf to /etc/supervisor/conf.d/ (see https://github.com/rocker-org/rocker/blob/master/rstudio/Dockerfile#L61)

your supervisor.conf could add something like

[program:Rserve]
command=/usr/bin/Rserve.sh
stdout_logfile=/var/log/supervisor/%(program_name)s.log
stderr_logfile=/var/log/supervisor/%(program_name)s.log
user=myuser
startsecs=0
autorestart=false
exitcodes=0

BUT ... I did figure it out. So here's the answer. I apologize that it's a bit clumsy and distributed. For me, my biggest obstacle was putting my start/stop scripts in the /usr/bin folder (see discussion below)

/etc/init/Rserve.conf

description "Rserve service"
author "Victor I. Wood"
version "0.01"

# based on
# https://stackoverflow.com/questions/32485131/how-to-make-an-upstart-service-to-rserve

env STARTSCRIPT=/usr/bin/Rserve.sh
env STOPSCRIPT=/usr/bin/Rserve.stop
env LOGFILE=/var/log/Rserve.log


start on runlevel [2345]
stop on runlevel [!2345]

console output

respawn

# tell upstart we're creating a daemon
# upstart manages PID creation for you.
expect fork


pre-start script
    echo "[`date`] Rserve Starting" >> $LOGFILE
    echo $$ > /var/run/Rserve.pid
end script

pre-stop script
    rm /var/run/Rserve.pid
    echo "[`date`] Rserve Stopping" >> $LOGFILE
    exec $STOPSCRIPT >> $LOGFILE
end script


script
        # My startup script, plain old shell scripting here.
        exec $STARTSCRIPT >> $LOGFILE
#       echo $$ > /var/run/rserve.pid
end script

/usr/bin/Rserve.sh

#!/bin/sh
sudo --login --set-home --user=myuser bash -c '~/Rserve.sh >~/Rserve.log 2>&1'

/usr/bin/Rserve.stop

#!/bin/sh
pkill -U myuser Rserve

/home/myuser/Rserve.sh

#!/bin/sh

# launch new Rserve process
R CMD Rserve --RS-conf /home/myuser/Rserve.conf --no-save >~/Rserve.log 2>&1

https://askubuntu.com/questions/62812/why-isnt-my-upstart-service-starting-on-system-boot?lq=1

I started with the script at https://askubuntu.com/questions/62729/how-do-i-set-up-a-service?lq=1 and noted the initctl start which might come in handy for debugging.

https://askubuntu.com/questions/62812/why-isnt-my-upstart-service-starting-on-system-boot?lq=1 noted that the script had to be in /bin (but I used /usr/bin), and had to be owned by root. Some folks like to use a link to a script elsewhere for the script i /bin

as folks here at How to make an upstart service to Rserve? have suggested, I'm using the Rserve start command that I found in the rServe documentation

R CMD Rserve

though I've expanded mine to

R CMD Rserve --RS-conf /home/myuser/Rserve.conf --no-save >~/Rserve.log 2>&1

I'm not exporting the correct pid, so I'm stopping it with a pkill. A more graceful approach would be

RSshutdown(rsc)

How can I shut down Rserve gracefully?

stdout & stderr confuse upstart, so re-direct all output with 2>&1 How to redirect both stdout and stderr to a file

I kinda figured it out by the time I found https://www.digitalocean.com/community/tutorials/the-upstart-event-system-what-it-is-and-how-to-use-it and https://geeknme.wordpress.com/2009/10/15/getting-started-with-upstart-in-ubuntu/ http://blog.joshsoftware.com/2012/02/14/upstart-scripts-in-ubuntu/ but for folks who just want to get started, those are more practical starting places than the official documentation.


Update

This solution assumes Upstart, which was the original question, but Upstart is no longer the default service manager. If you'd like to do this on post-16.04 systems, change back to Upstart with

sudo apt-get install upstart-sysv
sudo update-initramfs -u
sudo apt-get purge systemd

(from http://notesofaprogrammer.blogspot.com/2016/09/running-upstart-on-ubuntu-1604-lts.html)

Community
  • 1
  • 1
woodvi
  • 1,898
  • 21
  • 27
0

As the public documentation of Rserve says, you can start Rserve daemon from a shell script.

Just create a script that executes the following command:

echo 'library(Rserve);Rserve(FALSE,args="--no-save --slave --RS-conf <your_own_path>/rserve.conf")'|<R_bin_path>/R --no-save --slave

For instance, in my MacOS computer I can start Rserve executing this line:

/bin/sh -c "echo 'library(Rserve);Rserve(FALSE,args=\"--slave\")'|/Library/Frameworks/R.framework/Versions/3.2/Resources/bin/exec/R --no-save --slave"

This command outputs something like this:

Starting Rserve:
  /Library/Frameworks/R.framework/Resources/bin/R CMD /Library/Frameworks/R.framework/Versions/3.2/Resources/library/Rserve/libs//Rserve --slave 

Rserv started in daemon mode.

Make sure to specify "--slave" parameter when you start Rserve.

You can create a shell script (or windows script) and tell the OS to execute this script during the startup process.

jfcorugedo
  • 9,793
  • 8
  • 39
  • 47