sample stasis web services for apache modperl and fastcgi. Both are multithreaded. However, the modperl one is racy. FastCGI is currently the recommended approach
This commit is contained in:
parent
417eec45c4
commit
94b356f837
5 changed files with 224 additions and 0 deletions
22
lang/perl/README.cgi-bin
Normal file
22
lang/perl/README.cgi-bin
Normal file
|
@ -0,0 +1,22 @@
|
|||
This should go in a sites-enabled file, inside a VirtualHost:
|
||||
|
||||
ScriptAlias /stasis-cgi/ /home/sears/stasis/lang/perl/cgi-bin/
|
||||
<Directory "/home/sears/stasis/lang/perl/cgi-bin">
|
||||
AllowOverride None
|
||||
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
|
||||
Order allow,deny
|
||||
Allow from all
|
||||
</Directory>
|
||||
|
||||
|
||||
|
||||
This is the contents of my /etc/apache2/mods-enabled/fastcgi.conf
|
||||
|
||||
<IfModule mod_fastcgi.c>
|
||||
AddHandler fastcgi-script .fcgi
|
||||
#FastCgiWrapper /usr/lib/apache2/suexec
|
||||
FastCgiIpcDir /var/lib/apache2/fastcgi
|
||||
FastCgiConfig -maxClassProcesses 1 -maxProcesses 1 -processSlack 1
|
||||
</IfModule>
|
||||
|
||||
Note that the fastcgi scripts are currently hardcoded to run in ~sears/stasis/www-data2
|
25
lang/perl/README.modperl
Normal file
25
lang/perl/README.modperl
Normal file
|
@ -0,0 +1,25 @@
|
|||
This goes in apache.conf:
|
||||
|
||||
<IfModule mpm_worker_module>
|
||||
StartServers 1
|
||||
# Only want 1 server; this is a correctness constraint for stasis.
|
||||
ServerLimit 1
|
||||
MinSpareThreads 25
|
||||
MaxSpareThreads 75
|
||||
ThreadLimit 150
|
||||
ThreadsPerChild 150
|
||||
MaxClients 150
|
||||
MaxRequestsPerChild 0
|
||||
</IfModule>
|
||||
|
||||
|
||||
This goes in the sites-enabled/???:
|
||||
|
||||
PerlRequire /home/sears/stasis/lang/perl/apache/inc/startup.pl
|
||||
|
||||
<Location /stasis>
|
||||
SetHandler perl-script
|
||||
PerlResponseHandler StasisWeb::Web
|
||||
</Location>
|
||||
|
||||
Note that the modapache scripts are currently hardcoded to look in ~sears/stasis/www-data
|
34
lang/perl/apache/StasisWeb/Web.pm
Normal file
34
lang/perl/apache/StasisWeb/Web.pm
Normal file
|
@ -0,0 +1,34 @@
|
|||
#file:Stasis/Web.pm
|
||||
#----------------------
|
||||
package StasisWeb::Web;
|
||||
|
||||
use threads::shared;
|
||||
my $thelock :shared;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Apache2::RequestRec ();
|
||||
use Apache2::RequestIO ();
|
||||
use Apache2::Const -compile => qw(OK);
|
||||
|
||||
sub handler {
|
||||
my $r = shift;
|
||||
$r->content_type('text/html');
|
||||
print "<html><head></head><body><h1>Stasis</h1>" . `pwd`;
|
||||
my $xid = Stasis::Tbegin();
|
||||
warn "a\n";
|
||||
my %h;
|
||||
tie %h, 'Stasis::Hash', $xid, Stasis::ROOT_RID();
|
||||
|
||||
$h{foo}++;
|
||||
|
||||
print ("$xid $h{foo}\n");
|
||||
|
||||
Stasis::Tcommit($xid);
|
||||
warn "b\n"; $| = 1;
|
||||
|
||||
print "</body></html>\n";
|
||||
|
||||
return Apache2::Const::OK;
|
||||
}
|
||||
1;
|
51
lang/perl/apache/inc/startup.pl
Executable file
51
lang/perl/apache/inc/startup.pl
Executable file
|
@ -0,0 +1,51 @@
|
|||
use threads;
|
||||
use threads::shared;
|
||||
|
||||
use strict;
|
||||
BEGIN {
|
||||
my $thelock :shared;
|
||||
|
||||
$ENV{STASIS_DIR} = '/home/sears/stasis';
|
||||
|
||||
$ENV{STASIS_LOCK} = $thelock;
|
||||
}
|
||||
use lib ($ENV{STASIS_DIR}."/lang/perl/apache/");
|
||||
push @INC, "$ENV{STASIS_DIR}/lang/perl/";
|
||||
|
||||
use Inline (Config =>
|
||||
DIRECTORY => "$ENV{STASIS_DIR}/www-data/",
|
||||
);
|
||||
use Stasis;
|
||||
|
||||
# XXX Ideally, the rest of this would go in a post_config handler, but
|
||||
# I can't get that to work...
|
||||
|
||||
my $data_dir = "$ENV{STASIS_DIR}/www-data/";
|
||||
|
||||
{
|
||||
my $d = `date`;
|
||||
chomp $d;
|
||||
warn "$d: Starting Stasis in $data_dir\n";
|
||||
chdir $data_dir
|
||||
|| die "Could not chdir to $data_dir, which I must own!";
|
||||
|
||||
Stasis::Tinit();
|
||||
$d = `date`;
|
||||
chomp $d;
|
||||
warn "$d: Stasis recovery complete\n";
|
||||
my $xid = Stasis::Tbegin();
|
||||
if(Stasis::TrecordType($xid, Stasis::ROOT_RID()) == Stasis::INVALID_SLOT()) {
|
||||
$d = `date`;
|
||||
chomp $d;
|
||||
warn "$d: Bootstrapping new Stasis store.\n";
|
||||
|
||||
Stasis::ThashCreate($xid);
|
||||
}
|
||||
Stasis::Tcommit($xid);
|
||||
|
||||
$d = `date`;
|
||||
chomp $d;
|
||||
warn "$d: Stasis initialization complete.\n";
|
||||
}
|
||||
|
||||
1;
|
92
lang/perl/cgi-bin/test.fcgi
Executable file
92
lang/perl/cgi-bin/test.fcgi
Executable file
|
@ -0,0 +1,92 @@
|
|||
#!/usr/bin/perl -w
|
||||
|
||||
use strict;
|
||||
|
||||
BEGIN {
|
||||
$ENV{STASIS_DIR} = '/home/sears/stasis';
|
||||
$ENV{STASIS_INLINE_DIRECTORY} = '/home/sears/stasis/www-data2';
|
||||
$ENV{PATH} = '/usr/local/bin:/usr/bin:/bin';
|
||||
# $ENV{LANG} = 'en_US.UTF-8';
|
||||
# $ENV{SHELL} = '/bin/sh';
|
||||
|
||||
# warn `env`;
|
||||
chdir "$ENV{STASIS_DIR}/www-data2" || die;
|
||||
# warn "begin succeeded";
|
||||
push @INC, "$ENV{STASIS_DIR}/lang/perl";
|
||||
}
|
||||
|
||||
use threads;
|
||||
use threads::shared;
|
||||
|
||||
use Stasis;
|
||||
|
||||
use IO::Handle;
|
||||
use FCGI;
|
||||
|
||||
my $count = 0;
|
||||
my $tot :shared = 0;
|
||||
my $concurrent :shared = 0;
|
||||
|
||||
my $in = new IO::Handle;
|
||||
my $out = new IO::Handle;
|
||||
my $err = new IO::Handle;
|
||||
|
||||
my $num_procs = 25;
|
||||
|
||||
|
||||
Stasis::Tinit();
|
||||
my $xid = Stasis::Tbegin();
|
||||
if(Stasis::TrecordType($xid, Stasis::ROOT_RID()) == Stasis::INVALID_SLOT()) {
|
||||
warn "Creating new database\n";
|
||||
Stasis::ThashCreate($xid);
|
||||
}
|
||||
Stasis::Tcommit($xid);
|
||||
warn "Stasis bootstrap completed; accepting FastCGI requests\n";
|
||||
|
||||
my @thrs;
|
||||
for(my $i = 0; $i < $num_procs; $i++) {
|
||||
push @thrs, threads->create(\&event_loop, $i);
|
||||
}
|
||||
sub event_loop {
|
||||
my $i = shift;
|
||||
# warn "Event loop $i started\n";
|
||||
my $request = FCGI::Request($in, $out, $err);
|
||||
while($request->Accept() >= 0) {
|
||||
my $s;
|
||||
my $tot2;
|
||||
{ lock $concurrent; $concurrent ++; }
|
||||
{
|
||||
lock($tot);
|
||||
$tot ++;
|
||||
$s = $tot;
|
||||
my $xid = Stasis::Tbegin();
|
||||
|
||||
my %h;
|
||||
tie %h, 'Stasis::Hash', $xid, Stasis::ROOT_RID();
|
||||
|
||||
$h{foo}++;
|
||||
|
||||
$tot2 = $h{foo};
|
||||
|
||||
Stasis::TsoftCommit($xid);
|
||||
}
|
||||
# Release lock before waiting for disk force.
|
||||
Stasis::TforceCommits();
|
||||
|
||||
print $out "Content-type: text/html\r\n\r\n" . "$count of $s ($tot2) concurrent: $concurrent";
|
||||
$count ++;
|
||||
{ lock $concurrent; warn "concurr: $concurrent\n"; $concurrent --; }
|
||||
# print $err "Event loop $i accepted request\n";
|
||||
}
|
||||
# warn "Event loop $i done\n";
|
||||
}
|
||||
|
||||
warn "Done spawning worker threads\n";
|
||||
|
||||
foreach my $t (@thrs) {
|
||||
$t->join();
|
||||
}
|
||||
|
||||
Stasis::Tdeinit();
|
||||
|
||||
warn "Stasis cleanly shut down\n";
|
Loading…
Reference in a new issue