Skip to content

Commit

Permalink
Merge branch 'master' of github.com:plainblack/webgui
Browse files Browse the repository at this point in the history
  • Loading branch information
daviddelikat committed Feb 10, 2012
2 parents 3fbf953 + 202d073 commit 57bef51
Show file tree
Hide file tree
Showing 2,522 changed files with 61,731 additions and 88,913 deletions.
1 change: 1 addition & 0 deletions .proverc
@@ -0,0 +1 @@
--recurse
47 changes: 47 additions & 0 deletions README
@@ -0,0 +1,47 @@
This is the PSGI branch of WebGUI8

To try this out:

0) Start from WebGUI 7.10.23 or the example .conf and create.sql that comes with WebGUI 8.
1) Run testEnvironment.pl to install all new requirements.
2) Get a new wgd from http://haarg.org/wgd
3) Copy etc/WebGUI.conf.original to www.whatever.com.conf; edit it and set dbuser, dbpass,
dsn, and uploadsPath (eg to /data/domains/www.example.com/public/uploads/)
4) Set WEBGUI_CONFIG to point at your new config file
5) $ export PERL5LIB='/data/WebGUI/lib'
6) $ wgd reset --upgrade
7) $ cd /data/WebGUI (or whereever you unpacked it)
8) $ rsync -r -a (or cp -a) /data/WebGUI/www/extras /data/domains/www.example.com/public/

To start it:

8) $ plackup app.psgi

See docs/install.txt for more detailed installation instructions.

Currently, the best performance is achieved via:

plackup -E none -s Starman --workers 10 --disable-keepalive

You can benchmark your server via:

ab -t 3 -c 10 -k http://dev.localhost.localdomain:5000/ | grep Req

I'm currently getting 370 requests/second, whereas I'm getting 430/second on the non-PSGI WebGUI8 branch.

= ARCHITECTURE =

* The root level app.psgi file loads all the config files found and
loads the site specific psgi file for each, linking them to the
proper host names.
* The site psgi file uses the WEBGUI_CONFIG environment variable to find the config.
* It instantiates the $wg WebGUI object (one per app).
* $wg creates and stores the WebGUI::Config (one per app)
* $wg creates the $app PSGI app code ref (one per app)
* WebGUI::Middleware::Session is wrapped around $app at the outer-most layer so that it can open and
close the $session WebGUI::Session. Any other wG middleware that needs $session should go in between
it and $app ($session created one per request)
* $session creates the $request WebGUI::Session::Request and $response WebGUI::Session::Response
objects (one per request)


21 changes: 21 additions & 0 deletions TODO
@@ -0,0 +1,21 @@
TODO
* Deprecate WebGUI::Session::HTTP - replace with WebGUI::Request/Response
* Investigate moving Cookie handling into middleware
* Reinstate WebGUI::authen with something equivalent
* Refactor assets to use streaming response
* Fix WebGUI::Form::param

DONE
* $session->request is now a Plack::Request object
* serverObject gone from WebGUI::Session::open()
* WebGUI::authen API changed
* urlHandler API changed - no longer gets server, config
* Streaming response body
* Mostly decoupled WebGUI from Log4perl
* Exception handling and error doc mapping
* Plack::Middleware::Debug panels
* Replaces all URL Handlers with Middleware

NB
* Periodically do a big stress-test and check for leaks, mysql overload etc..
ab -t 100 -c 10 -k http://dev.localhost.localdomain:5000 | grep 'Req'
161 changes: 161 additions & 0 deletions WebGUI-Session-Plack.pm
@@ -0,0 +1,161 @@
package WebGUI::Session::Plack;

# This file is deprecated - keeping it here for reference until everything has been ported

use strict;
use warnings;
use Carp;

=head1 DESCRIPTION
This class is used instead of WebGUI::Session::Request when wg is started via plackup
=cut

sub new {
my ( $class, %p ) = @_;

# 'require' rather than 'use' so that non-plebgui doesn't freak out
require Plack::Request;
my $request = Plack::Request->new( $p{env} );
my $response = $request->new_response(200);

bless {
%p,
pnotes => {},
request => $request,
response => $response,
server => WebGUI::Session::Plack::Server->new( env => $p{env} ),
headers_out => Plack::Util::headers( [] ), # use Plack::Util to manage response headers
body => [],
sendfile => undef,
}, $class;
}

our $AUTOLOAD;

sub AUTOLOAD {
my $what = $AUTOLOAD;
$what =~ s/.*:://;
carp "!!plack->$what(@_)" unless $what eq 'DESTROY';
}

# Emulate/delegate/fake Apache2::* subs
sub uri { shift->{request}->path_info }
sub param { shift->{request}->param(@_) }
sub params { shift->{request}->prameters->mixed(@_) }
sub headers_in { shift->{request}->headers(@_) }
sub headers_out { shift->{headers_out} }
sub protocol { shift->{request}->protocol(@_) }
sub status { shift->{response}->status(@_) }
sub sendfile { $_[0]->{sendfile} = $_[1] }
sub server { shift->{server} }
sub method { shift->{request}->method }
sub upload { shift->{request}->upload(@_) }
sub dir_config { shift->{server}->dir_config(@_) }
sub status_line { }
sub auth_type { } # should we support this?
sub handler {'perl-script'} # or not..?

sub content_type {
my ( $self, $ct ) = @_;
$self->{headers_out}->set( 'Content-Type' => $ct );
}

# TODO: I suppose this should do some sort of IO::Handle thing
sub print {
my $self = shift;
push @{ $self->{body} }, @_;
}

sub pnotes {
my ( $self, $key ) = ( shift, shift );
return wantarray ? %{ $self->{pnotes} } : $self->{pnotes} unless defined $key;
return $self->{pnotes}{$key} = $_[0] if @_;
return $self->{pnotes}{$key};
}

sub user {
my ( $self, $user ) = @_;
if ( defined $user ) {
$self->{user} = $user;
}
$self->{user};
}

sub push_handlers {
my $self = shift;
my ( $x, $sub ) = @_;

# log it
# carp "push_handlers($x)";

# run it
# returns something like Apache2::Const::OK, which we just ignore because we're not modperl
my $ret = $sub->($self);

return;
}

sub finalize {
my $self = shift;
my $response = $self->{response};
if ( $self->{sendfile} && open my $fh, '<', $self->{sendfile} ) {
$response->body($fh);
}
else {
$response->body( $self->{body} );
}
$response->headers( $self->{headers_out}->headers );
return $response->finalize;
}

sub no_cache {
my ( $self, $doit ) = @_;
if ($doit) {
$self->{headers_out}->set( 'Pragma' => 'no-cache', 'Cache-control' => 'no-cache' );
}
else {
$self->{headers_out}->remove( 'Pragma', 'Cache-control' );
}
}

################################################

package WebGUI::Session::Plack::Server;

use strict;
use warnings;
use Carp;

sub new {
my $class = shift;
bless {@_}, $class;
}

our $AUTOLOAD;

sub AUTOLOAD {
my $what = $AUTOLOAD;
$what =~ s/.*:://;
carp "!!server->$what(@_)" unless $what eq 'DESTROY';
}

sub dir_config {
my ( $self, $c ) = @_;

# Translate the legacy WebguiRoot and WebguiConfig PerlSetVar's into known values
return WebGUI->root if $c eq 'WebguiRoot';
return WebGUI->config_file if $c eq 'WebguiConfig';

# Otherwise, we might want to provide some sort of support (which Apache is still around)
return $self->{env}->{"wg.DIR_CONFIG.$c"};
}

################################################

package Plack::Request::Upload;

sub link { shift->link_to(@_) }

1;
52 changes: 52 additions & 0 deletions app.psgi
@@ -0,0 +1,52 @@

=head1 LEGAL
-------------------------------------------------------------------
WebGUI is Copyright 2001-2012 Plain Black Corporation.
-------------------------------------------------------------------
Please read the legal notices (docs/legal.txt) and the license
(docs/license.txt) that came with this distribution before using
this software.
-------------------------------------------------------------------
http://www.plainblack.com info@plainblack.com
-------------------------------------------------------------------
=cut

use strict;
use Plack::Builder;
use Plack::Util;

use WebGUI::Paths -inc;
use WebGUI::Config;
use WebGUI::Fork;

if ($ENV{PLACK_ENV} ne 'development') {
WebGUI::Paths->preloadAll;
}

WebGUI::Fork->init();

builder {
my $first_app;
WebGUI::Paths->siteConfigs or die "no configuration files found";
for my $config_file (WebGUI::Paths->siteConfigs) {
my $config = WebGUI::Config->new($config_file) or die "failed to log configuration file: $config_file: $!";
my $psgi = $config->get('psgiFile') || WebGUI::Paths->defaultPSGI;
my $app = do {
# default psgi file uses environment variable to find config file
local $ENV{WEBGUI_CONFIG} = $config_file;
Plack::Util::load_psgi($psgi);
} or die;
$first_app ||= $app;
my $gateway = $config->get('gateway');
$gateway =~ s{^/?}{/};
for my $sitename ( @{ $config->get('sitename') } ) {
mount "http://$sitename$gateway" => $app;
}
}

# use the first config found as a fallback
mount '/' => $first_app;
};

Binary file added asset_status.ods
Binary file not shown.
19 changes: 19 additions & 0 deletions benchmark.pl
@@ -0,0 +1,19 @@
# Little script used to run benchmarks against dev.localhost.localdomain
#
# To profile, run "perl -d:NYTProf benchmark.pl"

use lib '/data/WebGUI/lib';
use WebGUI;
use Plack::Test;
use Plack::Builder;
use HTTP::Request::Common;
my $wg = WebGUI->new( root => '/data/WebGUI', site => 'dev.localhost.localdomain.conf' );
my $app = builder {
enable '+WebGUI::Middleware::Session', config => $wg->config;
$wg;
};

test_psgi $app, sub {
my $cb = shift;
$cb->( GET "/" ) for 1..1000;
};
15 changes: 15 additions & 0 deletions docs/changelog/7.x.x.txt
@@ -1,5 +1,20 @@
7.10.25

7.10.24
- fixed #12318: asset error causes asset manager to fail
- fixed #12308: error message used scalar as reference
- fixed #12256: Calendar Search doesn't show admin controls
- fixed #12268: Point of sale form missing from cart screen.
- fixed #12201: AssetReport - no selects.
- fixed #12269: Login / Loginbox with encryptlogin
- fixed #12271: Calendar List View does not always show labels
- fixed Passive Analytics, UI, Progress Bar, server load.
- fixed #12303: Survey custom multiple choice question types
- fixed #12304: Surven packages do not include custom question types
- fixed #12309: Some child assets ignore visitor cache timeouts
- fixed possible values and default values on EMS submission.
- fixed #12312: Shop account plugin has unrendered macro
- fixed #12315: Remove yui tests from git repo.

7.10.23
- fixed #12225: Stock asset, multiple instances on a page
Expand Down
6 changes: 6 additions & 0 deletions docs/changelog/8.x.x.txt
@@ -0,0 +1,6 @@
8.0.0
- Replaced the existing caching mechanism with memcached, which results in a 400% improvement to cache speed. See migration.txt for API changes and gotcha.txt for prereq changes.
- Added "hot sessions" so sessions interact with the database less.
- Added Facebook Auth and FacebookLogin macro.
- Removed the WebGUI statistics program and code.

0 comments on commit 57bef51

Please sign in to comment.