-
Notifications
You must be signed in to change notification settings - Fork 29
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Later interval doesn't work well with RestRserve
and doesn't run with Rscript
#179
Comments
For some more context here is what I'm trying to do. This is an example of a toy REST API using #!/usr/bin/env Rscript
box::use(RestRserve)
box::use(later)
box::use(jsonlite)
# Function to fetch and prepare data
fetch_data <- function() {
print("New data...")
# Fetch data from external API
data <- rnorm(100, 0, 1)
# Save data to a file or a database
saveRDS(data, "data.rds")
# Schedule the next data fetch
later::later(fetch_data, delay = 2)
}
# --------------------------------------------
# private event loop so as not to block RestRserve
private_loop <- later$create_loop()
later$with_loop(private_loop, {
later$later(fetch_data, delay = 2)
later$run_now()
})
# --------------------------------------------
# Function to serve data
serve_data <- function(.req, .res) {
# Load data from a file or a database
data <- readRDS("data.rds")
# Serve data
.res$set_body(data)
.res$set_content_type("application/json")
.res$set_status_code(200L)
}
# Create an application
app <- RestRserve$Application$new()
# Add a route to serve data
app$add_route("/", "GET", serve_data)
# Start the server
server <- RestRserve$BackendRserve$new()
server$start(app) # This will block the script I discovered that if I ran the server in interactive mode (which I'm not supposed to do) and I can use the server and go to the end point. However the later loops are never ran. If I quit the process by doing CMD + C then the server shuts down and I can see my later process loop starting running. Is
|
After experimenting, I was able to determine that it was indeed the I was able to put this together where I run the Does anyone know another way of doing this? Note this script can also be written the reverse way where my "Hello world" loop is in the background process. #!/usr/bin/env Rscript
# This works, the way this works is that the server is started in a separate R process
# and the main R process is used to run the event loop
box::use(later)
box::use(callr)
# Create a separate event loop
private_loop <- later$create_loop()
# Define the function to be called for the 2-second loop
print_hello_world <- function() {
print("Hello world")
later$later(print_hello_world, 2, loop = private_loop)
}
# Schedule the function to be called in the separate loop
later$later(print_hello_world, 0, loop = private_loop)
# --------------------------------------------
# Run the RestRserve backend in a separate R process using callr
server_process <- callr::r_bg(\() {
box::use(RestRserve)
# Create a new RestRserve application
app <- RestRserve$Application$new()
# Add the "echo" endpoint to the application
app$add_get("/echo", function(.req, .res) {
.res$set_body("hello")
.res$set_content_type("text/plain")
})
# Create a RestRserve backend
backend <- RestRserve$BackendRserve$new()
# Start the RestRserve backend
backend$start(app, http_port = 8080)
}, stdout = "server.log", stderr = "server.log")
# --------------------------------------------
# Run the separate event loop to print "Hello world" every 2 seconds
while (TRUE) {
later$run_now(loop = private_loop)
Sys.sleep(1)
} |
Finally, I want to add that I thought about creating two separate scripts, one for my REST API and another for my interval logic. However, I need these to run together as I want to be able to receive commands from the API and pass them to my logic being run in the interval. In short, I'm building a trading bot for academic purposes in Edit: I am finally circling back to the original title of my post. If I use Edit: I believe the issue with I've done some experiments trying to keep the process open when using I noticed any time I used an infinite while loop even in interactive mode later does not execute. Does later only work in interactive mode? In summary: If I run in interactive mode library("later")
setInterval <- function(func, interval, loop) {
func <- rlang::as_function(func)
loop <- later::create_loop()
repeat_func <- function() {
func()
later::later(repeat_func, interval, loop = loop)
}
later::later(repeat_func, interval, loop = loop)
return(loop)
}
clearInterval <- function(id) {
later::destroy_loop(id)
}
setTimeout <- function(func, delay, loop, ...) {
func <- rlang::as_function(func)
loop <- later::create_loop()
later::later(\() {
func(...)
}, delay, loop = loop)
}
keep_alive <- function() {
while(TRUE) {
Sys.sleep(Inf)
}
}
# ----------------------------------------------
hello <- function() {
print("Hello world.")
}
loop <- setInterval(hello, 2, later::global_loop())
# if run interactively without `while` loop then this works
# we get "Hello world." and it stops after 5 seconds
setTimeout(\(hello) {
clearInterval(loop)
}, 5, later::global_loop(), hello = "Killing loop")
# but if run with `while` loop then we don't see "Hello world."
keep_alive() |
Rscript
RestRserve
RestRserve
RestRserve
and doesn't run with Rscript
Edit: I updated the title of my issue. Now I'm looking for a way to run later and RestRserve together and communicate between the two. Please skip to this comment:
#179 (comment)
I will leave my previous comments for context.
Hello, I'm still learning about
later
and event loops. I would appreciate any help.I wrote this script to test
later
and create a "private event loop". I'm still learning about these. Is there any documentation somewhere with examples of how to use them? All I found was the help pages but with no examples - toy use case demos would be very helpful - I want to use it to get data from an API and run a REST API without blocking the global even loop (the REST API).I'm more familiar with just using
later::later
by itself but not with private event loops.Anywho, I wrote this script that runs well in interactive mode but only opens and closes with no printing if run with
Rscript
. In the end this script I want to write with the loop is meant to be server side code so I have to be able to run it usingRscript
.I plan on using this in a
RestRserve
server, so I need this to run without blocking the global event loop - hence, I started looking into private event loops.I tried to keep the global loop open by sleeping for 10 seconds; the initial print of "Hello world!" worked, but not my loop.
The text was updated successfully, but these errors were encountered: