rstudio / plumber

Turn your R code into a web API.
https://www.rplumber.io
Other
1.4k stars 256 forks source link

Plumber stops reacting on Raspberry (server) to Windows 10 (client) #525

Open Toniiiio opened 4 years ago

Toniiiio commented 4 years ago

My plumber file:

# plumber.R

#* Echo back the input
#* @param msg The message to echo
#* @get /echo
function(msg=""){
  list(msg = paste0("The message is: '", msg, "'"))
}

#* Echo back the input
#* @param msg The message to echo
#* @post /echo2
function(msg=""){
  list(msg = paste0("The message is: '", msg, "'"))
}

#* Return the sum of two numbers
#* @param a The first number to add
#* @param b The second number to add
#* @post /sum
function(a, b){
  print("arrived")
  as.numeric(a) + as.numeric(b)
}

Client side:

Get request works:

url <- "http://192.168.1.11:7194/echo"
httr::GET(url = url, body = "msg=asd", timeout = 2) %>% content
$`msg`
$`msg`[[1]]
[1] "The message is: ''"

Describe the problem in detail

Post request does not work.

curl --data "a=4&b=3" "http://192.168.1.11:7194/sum" --> Here, i dont get a response. The client is busy and server as well. (if i quit this request and make a new get request from client (that worked before), the get request will also fail, since the server seems to be still "busy").

Note, that it all worked a few days before, probably before i switched to R 3.6.3 on Raspi pi.

What i tried:

url <- paste0("http://192.168.1.11:7194/sum")
httr::POST(url = url, body = "a=4&b=3", timeout = 2) %>% content

My best guess is that it started failing after migrating to R 3.6.3.

Sometimes, for some strange reason, i start the plumber process and curling the sum still works, but not doing a post request from R.

Then i restart the process and even the get request doesnt work anymore.

System details


  > sessionInfo()
R version 3.6.3 (2020-02-29)
Platform: armv7l-unknown-linux-gnueabihf (32-bit)
Running under: Raspbian GNU/Linux 10 (buster)

Matrix products: default
BLAS:   /usr/local/lib/R/lib/libRblas.so
LAPACK: /usr/local/lib/R/lib/libRlapack.so

locale:
  [1] LC_CTYPE=en_GB.UTF-8       LC_NUMERIC=C
[3] LC_TIME=en_GB.UTF-8        LC_COLLATE=en_GB.UTF-8
[5] LC_MONETARY=en_GB.UTF-8    LC_MESSAGES=en_GB.UTF-8
[7] LC_PAPER=en_GB.UTF-8       LC_NAME=C
[9] LC_ADDRESS=C               LC_TELEPHONE=C
[11] LC_MEASUREMENT=en_GB.UTF-8 LC_IDENTIFICATION=C

attached base packages:
  [1] stats     graphics  grDevices utils     datasets  methods   base

other attached packages:
  [1] plumber_0.4.7.9000 devtools_2.3.0     usethis_1.6.0

loaded via a namespace (and not attached):
  [1] Rcpp_1.0.4.6        magrittr_1.5        pkgload_1.0.2
[4] R6_2.4.1            rlang_0.4.5         fansi_0.4.1
[7] tools_3.6.3         pkgbuild_1.0.6      sessioninfo_1.1.1
[10] cli_2.0.2           withr_2.1.2         ellipsis_0.3.0
[13] remotes_2.1.1       assertthat_0.2.1    digest_0.6.25
[16] rprojroot_1.3-2     crayon_1.3.4        processx_3.4.2
[19] later_1.0.0.9002    callr_3.4.3         promises_1.1.0.9000
[22] fs_1.4.1            ps_1.3.2            curl_4.3
[25] testthat_2.3.2      memoise_1.1.0       glue_1.4.0
[28] stringi_1.4.6       compiler_3.6.3      desc_1.2.0
[31] backports_1.1.6     prettyunits_1.1.1   httpuv_1.5.2.9000
schloerke commented 4 years ago

Make sure you are sending json as the body.

# test.R

# Your plumber file running on port 8000

library(magrittr)

"http://127.0.0.1:8000/echo" %>%
  httr::GET(query = list(msg = "asdf")) %>%
  httr::content()
#> $msg
#> $msg[[1]]
#> [1] "The message is: 'asdf'"

"http://127.0.0.1:8000/echo2" %>%
  httr::POST(body = list(msg = "asdf"), encode = "json") %>%
  httr::content()
#> $msg
#> $msg[[1]]
#> [1] "The message is: 'asdf'"

system("curl --data '{\"msg\":\"asdf\"}' http://127.0.0.1:8000/echo2")
#> {"msg":["The message is: 'asdf'"]}

system("curl --data '{\"a\":40, \"b\":2}' http://127.0.0.1:8000/sum")
#> [42]
Toniiiio commented 4 years ago

Thanks so much for the fast response!

I didn´t encode the body as json before. I will make sure i do that in the future.

However, the problem still occurs.

Even:

"http://192.168.1.11:7194/echo" %>%
  httr::GET(query = list(msg = "asdf")) %>%
  httr::content()

does not get any response anymore and just stays in "waiting modus" for minutes.

I guess i should go back to R 3.5.x and see if the problem still occurs,

meztez commented 4 years ago

Are you running out of memory on the raspberry? Or any other hardware limitation? I get the kind of behavior you are describing when when I set the memory limit of my docker container too low. Could be that, or something else entirely.

I would also check Raspbian logs files for any error in processing the request.

check free -m and df - h for disk.

Toniiiio commented 4 years ago

Thanks for the answer @meztez

It is a good idea. I opened two putty consoles. Started plumber on the first. On the client side I sent requests until the error occurs and then i ran the "memory and disk" commands in the second console.

pi@raspberrypi:~ $ free -m
              total        used        free      shared  buff/cache   available
Mem:           3906         277        3374          42         253        3465
Swap:            99           0          99
pi@raspberrypi:~ $ df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/root        29G  3.6G   25G  13% /
devtmpfs        1.8G     0  1.8G   0% /dev
tmpfs           2.0G     0  2.0G   0% /dev/shm
tmpfs           2.0G  8.5M  1.9G   1% /run
tmpfs           5.0M  4.0K  5.0M   1% /run/lock
tmpfs           2.0G     0  2.0G   0% /sys/fs/cgroup
/dev/mmcblk0p1  253M   53M  200M  21% /boot
tmpfs           391M     0  391M   0% /run/user/1000

I guess in this case it might not be the bottleneck, as the responses are like 3 to 30B.

Clean setup:

Moreover, i took a new SD card flashed a new debian image with imager and installed R 3.5.2 again. But the error still occurs.

I can´t really see a pattern on when the error occurs. Can happen on second up to 30th request. For both GET or POST. I will keep searching. I also tested in two different networks, which should have enough bandwith available.

meztez commented 4 years ago

Does it happen when you send request directly from the server to plumber? Or just when there is routing involved?

I might spin up a docker image of raspbian to see if I'm able to reproduce. Do you have a config script for your server? Any nginx, apache or juste plain R with plumber?

jey1401 commented 4 years ago

Hi,

I'm experiencing the same issue on a Raspberry Pi 4 runing Raspbian GNU/Linux 10 (buster). The freeze occurs both on R3.5.2 and R3.6.3 with plumber_1.0.0. Plumber directly listen to the open port. It answers a few requests then freezes at some unpredictable point.

Cheers

meztez commented 4 years ago

@jey1401 was unable to reproduce, could you provide a reprex?

jey1401 commented 4 years ago

@meztez sure:

rest_logger = function(req){
  cat(req$REQUEST_METHOD, req$PATH_INFO, "\n")
  plumber::forward()
}

r = plumber::Plumber$new()
r$filter("logger", rest_logger)
r$run(host="0.0.0.0", port = 8080, swagger = FALSE)

On distant host, I call $ curl -v http://my.rpi.url:8080/something. It answers for some time with a 404 status (expected). And the logger shows the request in log file. Then I wait for a minute. And when redoing so, plumber "freezes". I mean, the connection occurs. But no response is ever returned. And the logger does not show the request. Here is the output of curl:

*   Trying my.rpi.ip...
* TCP_NODELAY set
* Connected to my.rpi.url (my.rpi.ip) port 8080 (#0)
> GET /something HTTP/1.1
> Host: my.rpi.url:8080
> User-Agent: curl/7.58.0
> Accept: */*
>
jey1401 commented 4 years ago

I should add that I tried to reproduce without success this issue on my laptop under ubuntu with the same R and Plumber versions. It runs perfectly. The freeze seems related to the rpi environment.

meztez commented 4 years ago

Anything in the pi os sys logs? Without buying the actual hardware, there is no way for us to reproduce. I'm sorry.

jey1401 commented 4 years ago

Unfortunately, I cannot find anything related to this in the logs. I guess that, even with the hardware, it would be a hell to debug.

jntrcs commented 2 years ago

Just +1 the exact issue @jey1401 was having. Did you ever make any progress?

charleswg commented 2 years ago

Just had this problem. It turns out that I was running plumber in foreground behind screen and disconnecting screen also disconnected the port of plumber while it's in foreground. Running plumber in background seems to solve the issue behind screen.

epiben commented 2 years ago

Frustratingly, I'm having the same issue. I'm currently running the 32-but version of RPi OS but was wondering if using the 64-bit version with e.g. rocker would fix the problem. @charleswg, were you using Docker? Neither docker-compose up -dnor docker run <container> -dt works; even adding & when Rscripting my server.R file in the ENTRYPOINF had no effect. So, if you could point me in the right direction, that would be awesome!