Search code examples
rrserve

How to make an upstart service to Rserve?


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 ?


Solution

  • 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)