Pike ScriptRunner
Pike ScriptRunner allows you to run {link:Pike|http://pike.ida.liu.se} scripts and [PikeApps/PSP] files under non-pike based web servers. Pike ScriptRunner is a FastCGI or SCGI application that will (hopefully) run under pretty much any web server that supports FastCGI or SCGI (see compatibility note below).
Because ScriptRunner uses {link:FastCGI|http://www.fastcgi.com} or {link:SCGI|http://mems-exchange.org/software/scgi}, its performance should be close to embedded language solutions like mod_perl, but with a lot less worries about security and overflows. With ScriptRunner you can
introduce all of your friends to Pike without forcing them to suffer
bad performance or (more likely) give up their attachment to Apache or other web servers. In addition, ScriptRunner does a lot of the unpleasant work of parsing incoming
requests, allowing you to get right to the task of writing your code.
Right now, it's pretty early on in its development, so there are a lot of
niceties present in Roxen or Caudium that aren't available, and it's not
terribly well tested, so it could have some nasty bugs. Enough raw
functionality is available to be highly useful; hopefully there will be
interest in improving things in this area. ScriptRunner contains code
written by others over the years; this is really more of a gathering of
snippets into something more readily useful to others.
__News__
February 2, 2006: ScriptRunner 0.5 is released! Check out the [PikeApps/Pike ScriptRunner/CHANGES].
December 22, 2005: ScriptRunner 0.4 is released! Check out the [PikeApps/Pike ScriptRunner/CHANGES].
October 10, 2005: ScriptRunner 0.3 is released! Check out the [PikeApps/Pike ScriptRunner/CHANGES].
__FAQs__
Check out the [PikeApps/Pike ScriptRunner/FAQ] page in progress to see if your question is already answered.
__Requirements:__
- Pike 7.6+ (available from http://pike.ida.liu.se)
- libfastcgi for FastCGI support (available from http://www.fastcgi.com)
- Public.Web.FastCGI for FastCGI support (available from http://www.siriushosting.com/pike/fastcgi.html)
__Features:__
- Multi-threaded request handling
- Persistent interpreter
- Compiled object caching
- Session handling (optional on a per-page/script basis)
- Incoming requests are parsed and passed to you in a RequestID object.
- Handles FCGI or SCGI processing for you. Just return a string or control mapping from your parse() method.
- Preliminary Pike Server Pages support, which allows you to mix HTML and Pike in the same page.
- Tested to work with mod_fastcgi and mod_actions on Apache 1.3+
- Tested to work with mod_fastcgi and mod_scgi on lighttpd 1.4.9
- Tested to work with lighttpd/scgi on Windows XP.
__Download:__
- http://hww3.riverweb.com/dist/scriptrunner/scriptrunner-0.5.tar.gz
- CVS browsing and snapshot downloads at http://hg.welliver.org/scriptrunner
__Installation:__
~~Apache users~~: see the file INSTALL.Apache in the source distribution for information on configuring Apache support for FastCGI.
Make sure that you have satisified the prerequisites before continuing.
1. Install and configure FastCGI support for your webserver so that *.fcgi files are treated as FastCGI applications.
2. Run the configure script in the ScriptRunner distribution. Pass the optional --prefix= or --with-pike= command line options, if desired.
3. Install the application to prefix/scriptrunner by running "make install".
4. Edit the scriptrunner application, specify an optional log file (recommended), and verify any settings you'd like to change.
5. Add a redirect to convert all requests to (*.pike) to
/path/to/scriptrunner.fcgi($1) (actual syntax will vary based on the
redirector you're using.
For example, if I've installed ScriptRunner so that the ScriptRunner.fcgi
is called by the following request:
{code}
www.mysite.com/path/to/ScriptRunner.fcgi
{code}
and I put a pike script in /some/other/path.pike on my website, I need my
redirect to internally change
{code}
www.mysite.com/some/other/path.pike
{code}
to
{code}
www.mysite.com/path/to/ScriptRunner.fcgi/some/other/path.pike
{code}
This is a common technique used by PHP and other languages. Alternately,
you could use mod_actions to do the same thing:
{code}
AddHandler scriptrunner-pike-script asis
AddHandler scriptrunner-pike-script .pike
AddHandler scriptrunner-pike-script .psp
Action scriptrunner-pike-script /path/to/ScriptRunner.fcgi
{code}
In the long run, this may be a simpler option.
A third option:
{code}
AddHandler fcgid-script .fcgi
AddHandler scriptrunner-pike-script .pike
Action scriptrunner-pike-script /ScriptRunner.fcgi
AddHandler scriptrunner-pike-server-page .psp Action scriptrunner-pike-server-page /ScriptRunner.fcgi
{code}
__Lighttpd Configuration__
Lighttpd comes with fcgi and scgi support out of the box, so if you've got a working ScriptRunner.fcgi/scgi, you can enable support by adding the following to your lighttpd.conf:
{code}
scgi.server = ( ".pike" => ((
"host" => "127.0.0.1",
"port" => 9999
)) )
{code}
It appears that the scgi module doesn't auto-start the process, so you'll need to start ScriptRunner.scgi with the appropriate ~~--port=~~ option to get things working, but it should work right out of the gate.
{code}
fastcgi.server = (".pike" =>
( "localhost" =>
(
"socket" => "/tmp/scriptrunner.socket",
"check-local" => "disable",
"bin-path" => "/path/to/scriptrunner/ScriptRunner.fcgi",
"min-procs" => 1,
"max-procs" => 5,
"idle-timeout" => 30
)
)
)
{code}
__Multithreaded operation__
ScriptRunner can be run in either single or multithreaded mode. Basically, this means that you can either have one thread processing all requests, or have a set of threads processing requests concurrently. Note that multithreaded operation doesn't necessarily mean that your scripts will run faster. In fact, single threaded operation tends to run about 4-5% faster on simple requests. You may find multithreading useful when performing large numbers of operations such as Image manipulations or SQL transactions, which are typically performed in C libraries, which often allow concurrent operations.
To enable (or disable) threaded operation, simply uncomment (or comment) the line in ScriptRunner.fcgi that looks like this:
{code}
#define RUN_THREADED
{code}
And restart ScriptRunner.fcgi (which may involve restarting your web server software). You can verify that ScriptRunner is running in single or multithreaded mode by making multiple requests to ScriptRunner.fcgi without a file argument. The first line following the version will indicate the thread handling the request. If the thread changes, you're running multiple handler threads; if it stays zero (0) across multiple requests, you're in singlethreaded mode.
__Platform Specific Notes__
Linux
Several users have reported difficulties running ScriptRunner under Ubuntu. The problem centers around Ubuntu ignoring options on the header line, such as:
{code}
#!/usr/local/bin/pike -M/usr/local/scriptrunner/lib
{code}
Two simple workarounds include writing a wrapper script that simply executes ScriptRunner with the appropriate options, or moving the contents of the ~~scriptrunner/lib~~ directory to your system's Pike modules path.
__Compatibility__
ScriptRunner has been tested to work with the following web servers in the following modes (note that just because the combination you'd like to use isn't listed, doesn't mean it won't work):
Apache 1.3/2.0 runs happily in FastCGI mode. ~~Note:~~ there are some "defects" in the way that mod_scgi works on Apache that may cause your scripts to behave improperly. We're working with the author of mod_scgi to work out a fix.
lighttpd 1.4.x runs happily in both FastCGI and SCGI mode, though we weren't smart enough to figure out how to get lighttpd to spawn ScriptRunner automatically using either mode. Pre-starting ScriptRunner seemed to work just fine, though.
Caudium 1.4 will run ScriptRunner in FastCGI mode using either the FastCGI or FastUniscript modules.
We'd be pleased to hear of any success stories (as well as configurations) that you've had success (or trouble) with. Drop the author a note at hwww3 __at__ riverweb __dot__ com.
__What does a script look like?__
Pike scripts look a lot like C or Java, but the first thing you'll notice is that they're far less verbose. One of the nice things about Pike is that a lot of powerful language constructs and methods are available to you out of the box. For example, the following script will render the contents of the form variable "input" as text on a PNG image:
{code}
mapping parse(object id)
{
// note that all of the most commonly used pieces of the request are
// assembled in the request id object.
if(!id->variables->input)
id->variables->input = "Default Text";
// the last argument is set to 1 to ensure we get a font back, even
// if we don't have the one we're looking for.
object fnt = Image.Fonts.load_font("Times New Roman", 72, 0, 1);
object img = fnt->write(id->variables->input);
string output = Image.PNG.encode(img);
return (["data": output, "type": "image/png"]);
}
{code}
The following example demonstrates Pike's database-independent SQL API. In this example, we're running a database query and returning the results as a table. Also note that we've added some code to speed processing: we keep the database connection open between requests.
{code}
object sql;
string sql_url = "mysql://user:pass@localhost/mydb";
string parse(object id)
{
if(!sql)
sql = connect_sql(sql_url);
// note that we use 'sprintf' like features here. the replacement variables
// get automatically quoted as appropriate for the underlying database.
// we're also using the 'simple query' interface that returns the result
// as an array of mappings (hashes)
array sql_result = sql->query("SELECT firstname, lastname, phone FROM addresses WHERE lastname like %s", "Smith%");
if(!sizeof(sql_result))
return "sorry, there were no entries.";
String.Buffer r = String.Buffer();
// In addition to standard object oriented method calls,
// Pike supports operator overloading, which allows objects to
// appear as though they were simple datatypes. This allows us to
// start with strings, and very simply replace the more efficient
// string buffer object, with only 2 changes to our code
r += " ";
// let's loop through the result set
foreach(sql_result; int index; mapping row)
r += sprintf("%s, %s | %s | ",
row->lastname, row->firstname, row->phone);
r+=" ";
// we could have just as easily cast the buffer to a string.
return r->get();
}
object connect_sql(string url)
{
object s;
if(catch(s = Sql.Sql(url)))
throw(Error.Generic("Unable to connect to the database.\n"));
return s;
}
{code}
Some example scripts (they all start with test) are included to give you a head start. More extensive documentation is available in the source distribution.
__Session Support__
As of version 0.3, ScriptRunner supports session state persistence. Currently the session storage engine uses a hash directory and serialization files, which means that it's not optimized for performance. Additional engines are welcome, some potential options include: RAM, SQL and Memcache.
To use sessions in your Pike Script, simply add an integer "\_\_participates_in_session" with a value of 1. See the class ScriptRunner.SRPikeScript for details. If this value is set, ScriptRunner will create a session cookie (if necessary), and retrieve any previously set session variables. The session information can be found within the following mapping in your RequestID object:
{code}
request->misc->session_variables
{code}
The session identifier string is stored as
{code}
request->misc->session_id
{code}
Simply place any data (no objects or programs yet, please!) you wish to persist into this mapping, and it will be saved between requests. Do note that the more data you place into this mapping, the slower your session will run, as it must be (currently serialized) and saved between requests.
For information on setting a PSP to use sessions, see the [PikeApps/PSP] page.
__Known Problems__
No currently known problems.
__Support__
Pike ScriptRunner is free software made available under the GPL/LGPL/MPL licenses. We're just getting started, so we're not totally organized yet. For the time being, send email to the Pike mailing list: pike __at__ roxen __dot__ com or to the author: bill __at__ gotpike __dot__ org.
Powered by PikeWiki2
|
|