Hello folks, I'm embarking on a project to embed R into the Apache web server, and I'd like your help. Currently, I'm looking for a way for R code to call back into a shared library from which the R shared library was loaded. Essentially, apache starts and loads mod_R.so which runs an initialization routine which calls Rf_initEmbeddedR() and the following code: /* override to call apache library write routine */ ptr_R_WriteConsole = Rapache_WriteConsole; /* load source(). I assume this is appropriate. I could always move this to the code that handles the requst */ PROTECT(R_source_fun = allocVector(LANGSXP, 2)); SETCAR(R_source_fun, Rf_install("source")); SETCAR(CDR(R_source_fun), R_source_arg = NEW_CHARACTER(1)); Then each request is serviced by the following code: /* r is apache request, r->filename is url translated to apsolute path to filename */ SET_STRING_ELT(R_source_arg, 0, COPY_TO_USER_STRING(r->filename)); errorOccurred=1; /* R code: source(filename) */ val = R_tryEval(R_source_fun,NULL,&errorOccurred); if (errorOccurred){ // Send a message to stderr (apache redirects this to the error log) fprintf(stderr,"apache2_mod_R: source(%s) failed!\n",r->filename); fflush(stderr); } else { return ok; } I would like to write R routines which hook into apache specific library calls to get at the CGI and system data. The apache specific calls need a request structure (the r variable) which is available in mod_R.so (already loaded) on each request. If I use the .C, .Call, or .External interface, then I must load a shared library with the appropriate routines. I would like to place those routines in mod_R.so to take advantage of access to the request structure. Is this doable? Another approach is to turn the CGI data into R variables and just place those in the top level environment, foregoing any callbacks into apache again until the R code has run to completion. This is similar to how PHP is embedded into Apache. Other languages that _do_ provide callbacks into apache include Perl, Python, and Ruby. -- Jeffrey Horner Computer Systems Analyst School of Medicine 615-322-8606 Department of Biostatistics Vanderbilt University
Building the callbacks is possible. Basically, you need to construct a fake DllInfo object for Apache and then use R_registerRoutines to attach the callbacks to R as it if were a normal R package registering its routines. I might have a simple example of this lying around, I'll see if I can find it (especially since it seems I'll be needing it myself soon :-)) On Aug 18, 2004, at 1:08 PM, Jeffrey Horner wrote:> Hello folks, > > I'm embarking on a project to embed R into the Apache web server, and > I'd like your help. Currently, I'm looking for a way for R code to > call back into a shared library from which the R shared library was > loaded. > > Essentially, apache starts and loads mod_R.so which runs an > initialization routine which calls Rf_initEmbeddedR() and the > following code: > > /* override to call apache library write routine */ > ptr_R_WriteConsole = Rapache_WriteConsole; > > /* load source(). I assume this is appropriate. I could > always move this to the code that handles the requst */ > PROTECT(R_source_fun = allocVector(LANGSXP, 2)); > SETCAR(R_source_fun, Rf_install("source")); > SETCAR(CDR(R_source_fun), R_source_arg = NEW_CHARACTER(1)); > > Then each request is serviced by the following code: > > /* r is apache request, r->filename is url translated to > apsolute path to filename */ > SET_STRING_ELT(R_source_arg, 0, COPY_TO_USER_STRING(r->filename)); > errorOccurred=1; > /* R code: source(filename) */ > val = R_tryEval(R_source_fun,NULL,&errorOccurred); > if (errorOccurred){ > // Send a message to stderr (apache redirects this to the error log) > fprintf(stderr,"apache2_mod_R: source(%s) failed!\n",r->filename); > fflush(stderr); > } else { > return ok; > } > > I would like to write R routines which hook into apache specific > library calls to get at the CGI and system data. The apache specific > calls need a request structure (the r variable) which is available in > mod_R.so (already loaded) on each request. If I use the .C, .Call, or > .External interface, then I must load a shared library with the > appropriate routines. I would like to place those routines in mod_R.so > to take advantage of access to the request structure. Is this doable? > > Another approach is to turn the CGI data into R variables and just > place those in the top level environment, foregoing any callbacks into > apache again until the R code has run to completion. This is similar > to how PHP is embedded into Apache. Other languages that _do_ provide > callbacks into apache include Perl, Python, and Ruby. > > > -- > Jeffrey Horner Computer Systems Analyst School of > Medicine > 615-322-8606 Department of Biostatistics Vanderbilt > University > > ______________________________________________ > R-devel@stat.math.ethz.ch mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel >--- Byron Ellis (bellis@hsph.harvard.edu) "Oook" -- The Librarian
Jeff, Does apache use threads? If it does, I would recommend *not* directly putting R into the apache server for the simple reason that R is not thread-safe. You might find it simpler (and cleaner) to use the RSOAP (http://rsoap.sf.net) interface to connect R with apache. I originally created RSOAP to get allow me to connect the ZOPE web application system's web server to R. -Greg> -----Original Message----- > From: r-devel-bounces@stat.math.ethz.ch > [mailto:r-devel-bounces@stat.math.ethz.ch]On Behalf Of Jeffrey Horner > Sent: Friday, August 20, 2004 3:17 PM > To: Byron Ellis > Cc: r-devel@stat.math.ethz.ch > Subject: Re: [Rd] R as shared library > > > Byron Ellis wrote: > > Building the callbacks is possible. Basically, you need to > construct a > > fake DllInfo object for Apache and then use > R_registerRoutines to attach > > the callbacks to R as it if were a normal R package registering its > > routines. > > > > I might have a simple example of this lying around, I'll > see if I can > > find it (especially since it seems I'll be needing it > myself soon :-)) > > Yes. I thought about that, but that solution may break on future R > releases and may hinder porting to other platforms outside of > the UNIX > family. I'm going to try Duncan's suggestion of a third dll > which will > install like a traditional R package. > > -- > Jeffrey Horner Computer Systems Analyst School > of Medicine > 615-322-8606 Department of Biostatistics Vanderbilt > University > > ______________________________________________ > R-devel@stat.math.ethz.ch mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel >LEGAL NOTICE\ Unless expressly stated otherwise, this messag...{{dropped}}
>From: A.J. Rossini [mailto:rossini@blindglobe.net] > >Jeffrey Horner <jeff.horner@vanderbilt.edu> writes: > >> Good point. However, I chose this route to 1) understand R and its >> internals, which is more complicated than I thought, 2) write an >> apache module, which I've always wanted to do, and 3) leverage >> Apache's robust server technology. In my opinion, no other server >> software is as scalable and reliable as Apache. Plus, it has a module >> API to plugin other code, like an R interpreter. > >All good reasons. But what is the final API going to look like? Are >you planning on SSI's for the general interface?For my prototype which already works, it's as simple as placing your code in a .R file accessible from the web server. That means your R code is responsible for generating HTML, similar to other languages embedded into Apache like Perl and Python. PHP is different in that the interpreter is only entered once a special tag is seen: file.php ------------- <html> <body> <?php /* php code here */ ?> </body> </html> ------------- And you can jump into and out of the interpreter an unlimited number of times. This allows for embedding parts of the HTML document within your code. Whether or not this is a good thing is debatable. The problem I'm working on right now, and which was talked about in the previous emails, is how to expose the CGI data to the R interpreter. Another part of this is how tight should R hook into Apache. Languages like Perl and Python expose many different parts of the http request to be overidden by language specific handlers, whereas PHP doesn't. My intent is to release a proof of concept prototype and then work with the R developer community to determine how it should evolve. Jeff [[alternative HTML version deleted]]