thomasp85 / fiery Goto Github PK
View Code? Open in Web Editor NEWA flexible and lightweight web server
Home Page: https://fiery.data-imaginist.com
License: Other
A flexible and lightweight web server
Home Page: https://fiery.data-imaginist.com
License: Other
Currently everything is documented under the Fire object which is suboptimal - this needs to be split up somehow
Prepare for release:
devtools::check()
devtools::check_win_devel()
rhub::check_for_cran()
revdepcheck::revdep_check(num_workers = 4)
Submit to CRAN:
usethis::use_version('patch')
cran-comments.md
devtools::submit_cran()
Wait for CRAN...
usethis::use_github_release()
usethis::use_dev_version()
Dear Thomas,
when I try to install the latest CRAN version, the installation stops at the testing step as shown below.
I'm using the latest fedora and I have try both "terminal" R 3.4.1 and rstudio. How can I help?
Erwan
R version 3.4.1 (2017-06-30) -- "Single Candle"
Copyright (C) 2017 The R Foundation for Statistical Computing
Platform: x86_64-redhat-linux-gnu (64-bit)
R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under certain conditions.
Type 'license()' or 'licence()' for distribution details.
Natural language support but running in an English locale
R is a collaborative project with many contributors.
Type 'contributors()' for more information and
'citation()' on how to cite R or R packages in publications.
Type 'demo()' for some demos, 'help()' for on-line help, or
'help.start()' for an HTML browser interface to help.
Type 'q()' to quit R.
> install.packages("fiery")
Installing package into β/home/lepennec/R/x86_64-redhat-linux-gnu-library/3.4β
(as βlibβ is unspecified)
--- Please select a CRAN mirror for use in this session ---
trying URL 'https://ftp.gwdg.de/pub/misc/cran/src/contrib/fiery_1.0.0.tar.gz'
Content type 'application/octet-stream' length 45562 bytes (44 KB)
==================================================
downloaded 44 KB
* installing *source* package βfieryβ ...
** package βfieryβ successfully unpacked and MD5 sums checked
** R
** preparing package for lazy loading
** help
*** installing help indices
converting help for package βfieryβ
finding HTML links ... done
Fire html
event_doc html
fake_request html
fiery-package html
plugin_doc html
Rd warning: /tmp/Rtmp5rAFdd/R.INSTALL3a4d65823c9a/fiery/man/plugin_doc.Rd:25: missing file link βsetRefClassβ
*** copying figures
** building package indices
** testing if installed package can be loaded
Recognise the fireplace DESCRIPTION entry that defines an expression returning a Fire object
Add firestarter()
function to start package based servers
hi,
I follow your blog A Simple Prediction Web Service Using the New fiery Package
run the script , return an error: error: object 'PATH_INFO' not found
how to fix it ?
thank lots~
`
sessionInfo()
R version 3.4.3 (2017-11-30)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Ubuntu 16.04.3 LTS
Matrix products: default
BLAS: /usr/lib/openblas-base/libblas.so.3
LAPACK: /usr/lib/libopenblasp-r0.2.18.so
locale:
[1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C LC_TIME=en_US.UTF-8
[4] LC_COLLATE=en_US.UTF-8 LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8
[7] LC_PAPER=en_US.UTF-8 LC_NAME=C LC_ADDRESS=C
[10] LC_TELEPHONE=C LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] shiny_1.0.5 jsonlite_1.5 fiery_1.1.0
loaded via a namespace (and not attached):
[1] Rcpp_0.12.15 rstudioapi_0.7 xml2_1.2.0 reqres_0.2.1 webutils_0.6
[6] uuid_0.1-2 xtable_1.8-2 R6_2.2.2 globals_0.11.0 tools_3.4.3
[11] parallel_3.4.3 brotli_1.1 htmltools_0.3.6 yaml_2.1.16 assertthat_0.2.0
[16] digest_0.6.14 crayon_1.3.4 later_0.6 codetools_0.2-14 triebeard_0.3.0
[21] glue_1.2.0 mime_0.5 stringi_1.1.6 compiler_3.4.3 urltools_1.7.0
[26] future_1.6.2 httpuv_1.3.5 listenv_0.7.0
`
Extract the enclosing function name that threw the error when catching errors for logging
It'd be awesome if console output was colored sensibly based on event
/request$status
values -- perhaps via https://github.com/r-lib/crayon#readme
(from my Twitter comment):
In https://github.com/thomasp85/fiery/blob/master/R/FutureStack.R#L59, if private$futures[[id]]
is a future (Future object created by future()
) then I think
resolved(private$futures[[id]]$expr, timeout = 0.05)
should be
resolved(private$futures[[id]], timeout = 0.05)
because resolved()
operates on a single future, a list or environment of them.
Prepare for release:
git pull
urlchecker::url_check()
devtools::build_readme()
devtools::check(remote = TRUE, manual = TRUE)
devtools::check_win_devel()
revdepcheck::revdep_check(num_workers = 4)
cran-comments.md
git push
Submit to CRAN:
usethis::use_version('minor')
devtools::submit_cran()
Wait for CRAN...
usethis::use_github_release()
usethis::use_dev_version(push = TRUE)
I just read the fiery reference manual from CRAN. I have several questions (maybe silly).
The "minimal example" shutdown automatically after several seconds. It seems the following code does it.
# Count the number of cycles (internal loops)
app$on('cycle-start', function(server, ...) {
server$set_data('cycles', server$get_data('cycles') + 1)
})
# Terminate the server after 50 cycles
app$on('cycle-end', function(server, ...) {
if (server$get_data('cycles') > 50) {
message('Ending...')
flush.console()
server$extinguish()
}
})
What is the block "Count the number of cycles (internal loops)" does? i.e., what does internal loops mean? How the cycles
becomes greater than 50? What's cycle in cycle-start
and cycle-end
?
In the Life Cycle Events, there are before-message
, message
, after-message
. I don't know what is websocket message. Is there any explanation about it? Or I should read some document/book (any suggestion?)
What does the block
argument in app$ignite(block = TRUE)
do? How this argument affect the server? i.e., Does it mean a new process/session start when two or more users request the same resource in the same time?
Consider the following simple GET listener
library(fiery)
app <- Fire$new()
app$port <- 9000
app$host <- "127.0.0.1"
app$on('request', function(server, id, request, ...) {
if (request$REQUEST_METHOD == "GET") {
list(
status = 200L,
headers = list('Content-Type' = 'text/html'),
body = paste('Get it!')
)
}
})
app$start(block = FALSE)
If you ping this URL with any request that is not a GET, my RStudio crashes. I'm on Windows 7.
I was looking at some of the tutorials at https://vuejs.org and was very interested to see that vue.js is reactive. Reactivity is, of course, one of Shiny's killer features. I started looking around to see if anyone had tried to link vue.js and R (or fiery).
@hrbrmstr's fiery example provides a nice illustration of using fiery but it would be great to see how to connect that to a basic user front-end, e.g., using vue.js. @timelyportfolio has some interesting work on embedding vue.js in R (https://github.com/timelyportfolio/vueR) but I haven't seen anything that uses R server-side and vue.js on the client side.
If anyone has an example of using R / fiery with vue.js I'd be very interested to see it.
In general, I think some (simple) examples using fiery to show how to generate plots and tables in a browser would make this very promising tool much more accessible.
I'm looking into this package as an option for serving data science models at my company. We have a security compliance policy that dictates we can only use http server frameworks that support/ are compatible with TLS 1.2 or higher. Does fiery meet this requirement?
I want to get the plotly code generated through R plotly and serve it on an API may be as plain text and then consume it on front end. How's that possible
Trying to write an authentication plugin to use with fiery
and and routr
but I cannot figure how to block the process if a condition is not met: e.g. return an error directly from the plugin.
A very minimal example would be something like this:
Basic <- R6Class('Basic',
public = list(
initialize = function() {
},
name = 'Basic',
on_attach = function(server, ...) {
server$on('before-request', function(request,...) {
if (request$headers$Auth == 'foo') {
# continue
}
else {
# return error response
}
})
}
))
basic = Basic$new()
route <- Route$new()
route$add_handler('post', '/', function(request, response, keys, ...) {
response$status <- 200L
response$body <- 'request handled'
TRUE
})
router <- RouteStack$new()
router$add_route(route, 'app_router')
app <- Fire$new()
app$attach(basic)
app$attach(router)
app$ignite(block = TRUE)
How should I do that ?
Hi,
I was so impressed and amazed at this package, it seemed to have the right balance between complexity and customization, I found you through this post (https://www.r-bloggers.com/a-simple-prediction-web-service-using-the-new-fiery-package/).
I tired to modify your example to handle a JSON as input, specifically using C5.0 decision tree, however I could not manage to do so. I was hoping you could have a document/pdf on github which would use a complex model (random forest, or anything using Caret) where instead of single parameter we send in a JSON.
I know it may seem a rich of me to ask you to do so, but I see tremendous potential to your package, unlike openCPU this is so easier to setup. Thank you so much for this again!
With the version of later that will be released soon, the following test fails:
fiery/tests/testthat/test-Fire.R
Lines 188 to 193 in 761a18d
This is because run_now()
has changed: previously, if any errors/warnings/messages happened in a callback, they would pass all the way through to the caller of run_now()
. In the new version of later, run_now
uses R_TopLevelExec
to invoke the callbacks, and errors/warnings/messages are not passed through R_TopLevelExec
. (They will, however, still display at the console.)
You can install the upcoming version of later with:
devtools::install_github('r-lib/[email protected]')
I currently don't know of any way to capture the message generated by a callback invoked by run_now()
, so I think your only recourse at this point may be to remove the test. If you can somehow move the expect_message()
into the later callback, that would work. But your code may not be structured for that.
Interested in a hand from someone far too entrenched in infosec?
I just started looking at this and will keep this list up to date but for starters:
host
should default to 127.0.0.1
and absolutely not 0.0.0.0
. I can go into "why" but this is pretty much the standard best practice (hate that term) and the only way to help users not shoot themselves in the foot.Things such as port and host should be able to set on creation time
Playing around with the routr/fiery doc examples, and I'm successfully crashing as soon as I hit the hello/anything/ endpoint
it did work once, but then I pinged from localhost:8080 once and it crashed, and now on subsequent times it is crashing every time from http://127.0.0.1:8080/hello/mars/
I thought it might have been a port conflict so changed that but still no good.
Prepare for release:
git pull
devtools::build_readme()
urlchecker::url_check()
devtools::check(remote = TRUE, manual = TRUE)
devtools::check_win_devel()
rhub::check_for_cran()
revdepcheck::revdep_check(num_workers = 4)
cran-comments.md
git push
Submit to CRAN:
usethis::use_version('patch')
devtools::submit_cran()
Wait for CRAN...
git push
usethis::use_github_release()
usethis::use_dev_version()
git push
This package is great! Thanks very much for your excellent work.
I'm confused for passing value from outside into Fiery. The example may be like this:
The output depends on the input val
=10, I want to get(10*2):
{
"v": 20,
}
Thank you very much for your help.
I noticed that fiery 0.2.1 gives an error on the CRAN Windows server, cf.
https://cran.r-project.org/web/checks/check_results_fiery.html
FYI, Uwe Ligges who runs the Windows CRAN checks well as http://win-builder.r-project.org/, (re-)confirmed in person last week that the Windows CRAN machines / tests are identical to the win-builder ones. In other words, you should be able to use win-builder to reproduce the CRAN errors.
FYI, instead of:
can_fork <- NULL
#' @importFrom parallelly availableCores
on_load({can_fork <- availableCores("multicore") > 1L})
you could use parallelly::supportsMulticore()
. Other than being more clear, the advantage would be to that it returns TRUE also when there's a single core available.
Hi @thomasp85 - I recently created a post on the Dash for R forum, am seeking advice regarding HTTPS routing for a Dash for R app, which (according to the documentation here) "uses the Fiery web framework under the hood." Reproducing my post below in case this is a more appropriate forum for it:
I am hosting a Dash for R web app on a Heroku Hobby Dyno using a custom domain with automatic SSL/TLS enabled (i.e., when you explicitly navigate to https://examplewebsite.org, the connection is secure. However, I would like to redirect from http://examplewebsite.org to HTTPS (i.e., force the site to use SSL/TLS). I have read the Heroku documentation which:
Indicates that redirects must be performed at the application level - I must code the redirect logic into my Dash app.
Recommends the use of GoogleCloudPlatform/flask-talisman for Flask apps in Python. However, I am using Dash for R, regarding which the documentation provides no recommendations. Even if I had the R-equivalent of Talisman installed, I am not sure how to explicitly access the Flask app object in Dash for R to attempt to apply it.
I've looked through the fiery::Fire
and Dash::dash
documentation, but can't seem to find anything that would force HTTPS. I also looked at your heroku-fiery-demo
repo, but don't see anything there either.
I haven't been able to find a solution to this issue and kindly request any guidance. Thanks so much!
We're considering DashR's eventual support inside Jupyter notebooks (DashR uses Fiery as its web server). Can Fiery run in a background process / thread, so that the Jupyter REPL isn't blocked?
(Sister issue for Dash for Julia ("Dash.Jl"): plotly/Dash.jl#48)
Need to come up with a flexible API for handling of logging.
Current idea:
Fire gets a log(event, message)
method and all internals will call it. The log
method will dispatch the logging to a user defined logger which can write to a db, output to console, etc. If none exists it will be a zero-operation...
fiery
is awesome! It makes some project much more easy.
I'm using fiery with node: write a app and use node to fetch
this.
While, there is a CORS problem:
Chorme console:
XMLHttpRequest cannot load http://localhost:9123/XXXXXXXXXXX. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access.
I think it could be handled in the fiery, wondering if there is any method to set Access-Control-Allow-Origin in the header.
library(fiery)
# Create a New App
app <- Fire$new()
# Handle requests
app$on('request', function(server, request, ...) {
response <- request$respond()
response$status <- 200L
response$body <- paste0('<h1>This is indeed a test. You are number ', server$get_data('visits'), '</h1>')
response$type <- 'html'
})
# works as expected
app$set_logger(logger_console())
# doesn't work
# app$set_logger(logger_console(combined_log_format))
app$ignite(showcase = TRUE)
More generally, it seems like errors/warnings from the logger itself should be reported in some way to help debug these sort of issues
Sent a POST request to the server with body:
curl -d 'Hello' -X POST http://127.0.0.1:8080
On the fiery side the body is always null. Do I have to call a certain function to get the body property filled?
Currently if a delayed expression fails to evaluate it will not get cleared from the stack...
Hi. The 'multiprocess' backend has been deprecated since future 1.20.0 (Oct 2020). The fiery package uses it in the code and mentions it in the docs, e.g.
Lines 96 to 104 in da9c27f
Using it produces a deprecation warning:
Warning message:
Detected creation of a 'multiprocess' future. Strategy 'multiprocess' is deprecated in future (>= 1.20.0)
[2020-10-30]. Instead, explicitly specify either 'multisession' (recommended) or 'multicore'. Starting
with future 1.31.0 [2023-01-31], 'multiprocess' is the same as 'sequential'.
But this soon become a defunct error. When that happens, R CMD check
on the fiery package will break:
* checking tests ... ERROR
Running βtestthat.Rβ
Running the tests in βtests/testthat.Rβ failed.
Complete output:
> library(testthat)
> library(fiery)
>
> test_check("fiery")
[ FAIL 1 | WARN 0 | SKIP 1 | PASS 253 ]
ββ Skipped tests βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β’ On CRAN (1)
ββ Failed tests ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
ββ Error ('test-Fire.R:368'): futures can be added and called ββββββββββββββββββ
<defunctError/error/condition>
Error: Detected creation of a 'multiprocess' future. Strategy 'multiprocess' is defunct in future (>= 1.20.0) [2020-10-30
]. Instead, explicitly specify either 'multisession' (recommended) or 'multicore'.
Backtrace:
β
1. ββapp$async(...) at test-Fire.R:368:4
2. ββprivate$ASYNC$add(substitute(expr), then, substituted = TRUE)
3. ββprivate$make_future(expr, then, ...)
4. ββbase::do.call(private$catcher, list(expr = expr, lazy = private$lazy))
5. ββfuture::multiprocess(...)
6. ββfuture (local) dfcn(msg = msg, package = .packageName)
7. ββbase::.Defunct(...)
[ FAIL 1 | WARN 0 | SKIP 1 | PASS 253 ]
Error: Test failures
Execution halted
Can you please fix?
PS. This one went under my revdepcheck radar, because it called multiprocess()
directly. Please avoid that and use the recommended plan(...)
approach instead. (It might be that we one day will replace all those backend functions with backend configuration objects with the same names)
At the moment the event cycle should be a zero-operation unless handlers have been attached. Still, I need to look into the efficiency of the cycle, as well as the event flushing mechanism to make sure it is as performant as possible
I think it's time r have is own rest api framework. Merging it vue can get us somewhere close to it.
How can I create a function which can setup a barebone project like
https://github.com/vikram-rawat/VueApp?files=1
So that l anybody can setup a base project
Writing to the log within a loop, results in the last value to be written 'N' times. I'm guessing this is because of the future evaluation, but I'm not sure how to get around it.
test_data <- data.frame(id = 1:5, data = LETTERS[1:5], stringsAsFactors = FALSE)
for (i in seq_len(nrow(test_data))) {
message('Writing to log: ', jsonlite::toJSON(test_data[i, ]))
server$log('test', jsonlite::toJSON(list(input = test_data[i, ])))
}
outputs:
Fire started at 127.0.0.1:8080
2019-02-26 13:53:01 - start: 127.0.0.1:8080
2019-02-26 13:53:01 - message: Writing to log: [{"id":1,"data":"A"}]
2019-02-26 13:53:01 - test: {"input":[{"id":5,"data":"E"}]}
2019-02-26 13:53:01 - message: Writing to log: [{"id":2,"data":"B"}]
2019-02-26 13:53:01 - test: {"input":[{"id":5,"data":"E"}]}
2019-02-26 13:53:01 - message: Writing to log: [{"id":3,"data":"C"}]
2019-02-26 13:53:01 - test: {"input":[{"id":5,"data":"E"}]}
2019-02-26 13:53:01 - message: Writing to log: [{"id":4,"data":"D"}]
2019-02-26 13:53:01 - test: {"input":[{"id":5,"data":"E"}]}
2019-02-26 13:53:01 - message: Writing to log: [{"id":5,"data":"E"}]
2019-02-26 13:53:01 - test: {"input":[{"id":5,"data":"E"}]}
2019-02-26 13:53:01 - message: 1
2019-02-26 13:53:01 - request: 127.0.0.1 - ID_127.0.0.1 [26/Feb/2019:13:53:01 +0100] "GET / HTTP/1.1" 200 48
2019-02-26 13:53:06 - message: Goodbye
2019-02-26 13:53:06 - stop: 127.0.0.1:8080
complete example based on the minimal fiery example:
library(fiery)
# Create a New App
app <- Fire$new()
app$set_logger(logger_console())
# Setup the data every time it starts
app$on('start', function(server, ...) {
server$set_data('visits', 0)
server$set_data('cycles', 0)
})
# Count the number of cycles (internal loops)
app$on('cycle-start', function(server, ...) {
server$set_data('cycles', server$get_data('cycles') + 1)
})
# Count the number of requests
app$on('before-request', function(server, ...) {
server$set_data('visits', server$get_data('visits') + 1)
})
# Handle requests
app$on('request', function(server, request, ...) {
response <- request$respond()
response$status <- 200L
response$body <- paste0('<h1>This is indeed a test. You are number ', server$get_data('visits'), '</h1>')
response$type <- 'html'
test_data <- data.frame(id = 1:5, data = LETTERS[1:5], stringsAsFactors = FALSE)
for (i in seq_len(nrow(test_data))) {
message('Writing to log: ', jsonlite::toJSON(test_data[i, ]))
server$log('test', jsonlite::toJSON(list(input = test_data[i, ])))
}
TRUE
})
# Show number of requests in the console
app$on('after-request', function(server, ...) {
message(server$get_data('visits'))
flush.console()
})
# Terminate the server after 50 cycles
app$on('cycle-end', function(server, ...) {
if (server$get_data('cycles') > 50) {
message('Ending...')
flush.console()
server$extinguish()
}
})
# Be polite
app$on('end', function(server) {
message('Goodbye')
flush.console()
})
app$ignite(showcase = TRUE)
It seems as though fiery/routr/reqres based apps don't currently have a mechanism for reporting trace stacks (of errors), which makes debugging complex applications difficult. Here's a minimal example of the information reported in a request error (BTW, any idea why the error is being reported twice?):
library(fiery)
library(routr)
app <- Fire$new()
route <- Route$new()
route$add_handler('get', '*', function(request, response, keys, ...) {
response$type <- 'html'
response$status <- 200L
response$body <- '<h1>All your AI are belong to us</h1>'
1 + "a"
FALSE
})
router <- RouteStack$new()
router$add_route(route, "main")
app$attach(router)
app$ignite(showcase = TRUE)
Fire started at 127.0.0.1:8080
error: non-numeric argument to binary operator
error: non-numeric argument to binary operator
With shiny, if you run an app that is saved to disk, it reports the line at which the error occurs -- would it be possible to add something similar to the fiery/routr/reqres stack?
library(shiny)
ui <- fluidPage(
plotOutput("p")
)
server <- function(input, output, ...) {
output$p <- renderPlot({
1+"a"
qplot(1:10)
})
}
shinyApp(ui, server)
runApp('test-app-shiny.R')
Listening on http://127.0.0.1:5017
Warning: Error in +: non-numeric argument to binary operator
161: renderPlot [~/test-app-shiny.R#10]
159: func
119: drawPlot
105: <reactive:plotObj>
92: drawReactive
79: origRenderFunc
78: output$p
1: runApp
After a few years of using Shiny and we have had lots of issues with it, e.g. it is too opinionated and it does not support concurrent requests on the open source version.
I wonder Fiery support concurrent requests?
We would like to use fiery as an API only and use Nuxt or Angular to send the requests, so we need CORS, does Fiery support CORS then?
Similar to python's flask-seasurf flask extension.
Hi, @thomasp85
I've run your example code on both Windows 10(my own PC) and Linux Ubuntu(on the server). When on Windows, it runs OK, but when on Ubuntu, it comes with "Error in attributes(.Data)... "
My Ubuntu environment is below,
> sessionInfo()
R version 3.4.0 (2017-04-21)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Ubuntu 14.04.5 LTS
Matrix products: default
BLAS: /usr/lib/libblas/libblas.so.3.0
LAPACK: /usr/lib/lapack/liblapack.so.3.0
locale:
[1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C
[3] LC_TIME=en_US.UTF-8 LC_COLLATE=en_US.UTF-8
[5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8
[7] LC_PAPER=en_US.UTF-8 LC_NAME=C
[9] LC_ADDRESS=C LC_TELEPHONE=C
[11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] fiery_1.0.0
loaded via a namespace (and not attached):
[1] Rcpp_0.12.12 codetools_0.2-15 brotli_1.0 listenv_0.6.0
[5] future_1.6.0 digest_0.6.12 later_0.3 assertthat_0.2.0
[9] R6_2.2.2 jsonlite_1.5 stringi_1.1.5 uuid_0.1-2
[13] xml2_1.1.1 webutils_0.6 urltools_1.6.0 reqres_0.2.0
[17] tools_3.4.0 triebeard_0.3.0 httpuv_1.3.3 parallel_3.4.0
[21] compiler_3.4.0 globals_0.10.2
And my code is just yours, (some rows deleted)
> library(fiery)
>
> app <- Fire$new()
> app$host <- '192.168.1.22' #This is the host of server
> app$port <- 19177
>
> # Setup the data every time it starts
> app$on('start', function(server, ...) {
+ server$set_data('visits', 0)
+ server$set_data('cycles', 0)
+ })
>
> # Count the number of cycles (internal loops)
> app$on('cycle-start', function(server, ...) {
+ server$set_data('cycles', server$get_data('cycles') + 1)
+ })
>
> # Count the number of requests
> app$on('before-request', function(server, ...) {
+ server$set_data('visits', server$get_data('visits') + 1)
+ })
>
> # Handle requests
> app$on('request', function(server, request, ...) {
+ response <- request$respond()
+ response$status <- 200L
+ response$body <- paste0('<h1>This is indeed a test. You are number ', server$get_data('visits'), '</h1>')
+ response$type <- 'html'
+ })
>
> # Show number of requests in the console
> app$on('after-request', function(server, ...) {
+ message(server$get_data('visits'))
+ flush.console()
+ })
>
>
> # Be polite
> app$on('end', function(server) {
+ message('Goodbye')
+ flush.console()
+ })
>
> app$ignite(showcase = TRUE)
Fire started at 192.168.1.22:19177
Error in attributes(.Data) <- c(attributes(.Data), attrib) :
'names' attribute [8] must be the same length as the vector [7]
ERROR: [on_request_read] parse error
Error in attributes(.Data) <- c(attributes(.Data), attrib) :
'names' attribute [8] must be the same length as the vector [7]
ERROR: [on_request_read] parse error
The same code I run on Windows do not come with any error (the host I set is '127.0.0.1'). However, when on Windows, I couldn't let other people in the local area network(LAN) visit my app whatever host I set(e.g. app$host <- '0.0.0.0'
or app$host <- '127.0.0.1'
or app$host <- '192.168.1.144'
(my IPv4 address on Windows))
So, there are 2 questions I want to consult,
1, how to solve the Ubuntu 'Error in attributes(.Data)...'?
2, how to set the host address to let others visit my app if I use Windows 10?
Waiting for your reply~
Thank you~
library(fiery)
server <- Fire$new()
server2 <- server$clone()
server2$set_logger(fiery::logger_console("{event}: {message}"))
Error in private$logger <- logger :
cannot change value of locked binding for 'logger'
Otherwise one cannot run multiple test suites in parallel. Or test suites for multiple versions of fiery, like we do in revdepcheck.
any plan to add dockerfile for official repo?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.