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 ?
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.
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)