5

I need to spawn an independent background Julia process from a shiny app that survives once the app is closed.

If the Julia process is called inline: sys::exec_background('nohup', c("julia", "-e sleep(3000)", "&") the child process survives the Shiny app once it get closed.

But if the Julia process is called on a script with just the same sleep(3000) call inside: sys::exec_background('nohup', c("julia", "test.jl", "&") once the Shiny app closes also the Julia process gets killed with error:

signal (2): Interrupt: 2
in expression starting at .../test.jl:1

kevent at /usr/lib/system/libsystem_kernel.dylib (unknown line)
unknown function (ip: 0x0)
Allocations: 2650 (Pool: 2641; Big: 9); GC: 0

Any idea why and any solution on how to have the Julia script process survive the parent app?

Here's the code to reproduce the behaviour. https://gist.github.com/bakaburg1/5d1b5135fb3b4db1a3ca2eb7e8639aa5 Just run the Shiny app and then close it. Only the inline code Julia process survives.

Bakaburg
  • 3,165
  • 4
  • 32
  • 64
  • Maybe I'm confused, but is this possible with any program? What OS are you using? Normally each process has a parent and if you spawn process B from process A, then A would be the parent. And the child B only runs when the parent is running. – MrFlick Nov 02 '21 at 17:49
  • eheh my question is indeed if it is possible at all. Maybe faking that the parent process is not the parent. I'm on MacOs, but it should work everywhere (at least Unix based) – Bakaburg Nov 02 '21 at 17:50
  • You could try using `processx::process$new(supervise = FALSE)` instead of `exec_background`. I currently can't test it as I cannot run Julia in my Ubuntu VM (-cx16 flag error)... – ismirsehregal Nov 16 '21 at 11:34

1 Answers1

5

There are Unix tools such a nohup and & to detach the forked and process and have it alive without their parent.

This works on my machine and should work on yours:

system("bash -c \"nohup julia -e \\\"println(1);sleep(1000);println(2)\\\" &\"")

Depending on platform you might be able to skip bash -c and just have:

system("nohup julia -e \"println(1);sleep(1000);println(2)\" &")
Przemyslaw Szufel
  • 40,002
  • 3
  • 32
  • 62
  • Thanks! it works if I use it on the terminal, but not from the R session! After investigating a bit I think it may be do to the child being in the same process group of the parent. I run these commands from a shiny app. If I don't use nohup once the app is closed also the julia process dies; but with nohup, the julia process prevents the parent R session from being shut down, the only way is force restart the R session (which then closes julia too) – Bakaburg Nov 02 '21 at 18:48
  • 1
    I do not believe it is possible to detach a child process *more* than `nohup` combined with `&`. If you have some more tricky architecture I would consider running a deamon that you can call via eg. a local HTTP request that spawns Julia processes on demand. In that case the deamon could run in a total isolation from your R shiny server. You could even use `sshd` for that purpose - just spawn a ssh session in your localhost only to launch Julia, and `nohup` will prevent it from being terminated. – Przemyslaw Szufel Nov 02 '21 at 19:55
  • I guess it's related to shiny::runApp() running all the code. If I run the code from the RStudio terminal and then close RStudio, the Julia process survives. I'll update my question. Do you have any references about using a deamon? – Bakaburg Nov 02 '21 at 19:59
  • 1
    See https://stackoverflow.com/questions/29142/getting-ssh-to-execute-a-command-in-the-background-on-target-machine on how to use `sshd` (that for sure you have on Mac) for a background job. Another option is just to write a RESTful Julia service and call it via HTTP - for an example you could use Genie.jl for that. Such service could be also written in any other language including R, bash or Python using one of many stacks such as Flask. – Przemyslaw Szufel Nov 02 '21 at 20:31
  • I edited the question adding a reproducible example. The process gets killed if Julia runs on a script but survives if it runs inline code. – Bakaburg Nov 02 '21 at 20:39