Previous conversation available at rev 11
At
FoswikiCamp2011, I made a start at converting Foswiki to PSGI. This will give us the following benefits:
The idea is to:
- Remove
Foswiki::Engine::*
-
Foswiki::Engine
will be the entry point for psgi
- Replace
Foswiki::Request
and Foswiki::Response
with CPAN:Plack::Request and CPAN:Plack::Response
- Although for compatibility the
Foswiki::
objects will be subclasses of the Plack::
for backwards compatibility, and may provide compatibility functions
- Ship the
Plack::
modules in lib/CPAN
- Remove the
bin/
directory
- Documentation
It is currently being developed on Github at
https://github.com/andrewrjones/foswiki/tree/psgi, in the
psgi
branch. Please see
core/foswiki.psgi
for current progress.
The current state of unit tests can be found at
http://ci.arjones.co.uk/waterfall?show=foswiki-psgi.
This is still at an early stage. My current focus is to get the unit tests passing.
Please feel free to discuss and contribute.
Why Move to PSGI?
Moving to PSGI will give us the following benefits:
- Easier installation and configuration across a wider number of platforms
- Less code to maintain in Foswiki core
- Ability to use Plack::Middleware::
It is important to note that Foswiki will continue to run on a variety of back ends (cgi, mod_perl, fcgi, etc).
We plan to ship the dependencies of Plack with Foswiki, which will ensure Foswiki stays easy to install on shared hosting, etc.
Getting Started
Firstly, get the code from Github. Then, get the
psgi
branch:
git fetch origin psgi:psgi
and switch to it.
Next, get Foswiki configured:
cd core; perl -T pseudo-install.pl -A developer
. Check
lib/LocalSite.cfg
is correct.
Then, install
Task::Plack
to get everything you need (and more).
cpanm Task::Plack
Finally, start the server:
cd core; plackup foswiki.psgi
. You can connect at
http://localhost:5000.
Links
--
AndrewJones - 18 Dec 2011
Discussion
Would be nice rid of authentication handlers out of FW to middleware level. In this way it is possible easily use Kerberos, LDAP Basic and any authentication methods, especially Plack::Middleware::OAuth for Facebook/Twitter/Google or so - what will add another level to foswiki's "social app level". See:
--
JozefMojzis - 18 Dec 2011
Yeah, I agree. Think this was discussed briefly at the camp. The more we can offload to Plack the better.
--
AndrewJones - 18 Dec 2011
That would need imo separate discusion - how to map external auth schemes to internal FW's WikiUserNames, because on the internal usernames relies access control..
--
JozefMojzis - 18 Dec 2011
first up - Andrew, good work
I'm looking forward to trying it in the new year.
Jozef - mapping to
WikiUserNames
is separate from the authentication - thats done by the mappers.
replacing
ApacheLogin and
TemplateLogin with Plack Auth middleware should be a simpler affair.
--
SvenDowideit - 22 Dec 2011
Feedback Required: Do
Foswiki::Request
and
Foswiki::Response
need to be backwards compatible, or can we replace them with
Plack::Request
and
Plack::Response
?
I initially tried to make
FW::Request
and
FW::Response
subclasses of the Plack equivalents, overriding to provide compatibility, but there are too many cases where they use the same method name for verry different methods, so I don't think this is viable.
So now, I think we have three options.
- Remove
FW::Request
and FW::Response
and replace with Plack in all core code.
- I will fix all core code, and
Unit::Request
, Unit::Response
. Only problem is, any plugins that have used Foswiki::Func::getRequestObject
will be getting a slightly different object, and may need to be fixed. I will volunteer to fix these plugins if they are available on FW.org, but obviously I can't fix private plugins.
- Remove
FW::Request
and FW::Response
and replace with Plack in all core code, but ensure Foswiki::Func::getRequestObject
continues to return a new Foswiki::Request
object, populated from Plack::Request
- Halfway solution. Can depreciate
Foswiki::Func::getRequestObject
in favour of Foswiki::Func::getRequest
(or similar) which returns Plack::Request
.
- Don't use
Plack::Request
and Plack::Response
, but update FW::Request
and FW::Response
so they are compatible with Plack.
- This means we will have to maintain our own solutions instead of using the standard, well tested Plack option.
I personally prefer 1, followed by 2, and really don't like 3. What do other people think?
I would like to gather feedback before the weekend, so I can work on this over the holidays, and hopefully have something working in the new year.
--
AndrewJones - 22 Dec 2011
As stated on IRC, I prefer 1, but Gilmar should know better
--
OlivierRaginel - 22 Dec 2011
I'd prefer 1 from a maintainence pov (I presume there's a way to make
./view
work from the commandline in Plack).
however, that presumes that we can make a cross platform (ie, non-XS)
tgz
that non-CPANers and those unfortuant to be behind a horrible firewall to un-tar and run.
(I just worked with a business group in that situation - we wasted about 3 days finding ways around corporate policies)
--
SvenDowideit - 22 Dec 2011
Yep, should be able to make ./view
work, using CPAN:Plack::Handler::CGI Done.
I don't think Plack has any XS
dependencies, so we could put them all in
lib/CPAN
.
In future, we could investigate something like
CPAN:carton, which can cache all dependencies in a directory. Still early days for that tool at the moment, but looks interesting.
--
AndrewJones - 22 Dec 2011
Imo, the right way is the 4th variant - what is the combination of 2 and 3 - what you want do at first...
Don't remove FW::Request, but
subclass it from Plack::Request With this way
- making a bridge between FW::Request and Plack::Requst only in one place
- will use the well tested Plack::Request
- and probably will not break anything at FW::Request level
If this is not usable, then I prefer 1.
BTW, any
plugin (not core) what want use the Plack::Request is probably bad by design and need rethink it how to push the plugin to the middleware level, but with the above method they should work...
--
JozefMojzis - 23 Dec 2011
Thinking again about the question, and i'm not sure about the Request, Response.
When looking for cut away as much as possible from FW to Plack suite and middlewares (because less code to maintain), like Request/Respond, static file-serving, authentication, maybe session management (usable for another PSGI apps) etc, the right answer is
subclass (or if the subclassing is not an usable way - then the 1st variant).
But, when (sometime in the future and nearby galaxy) foswiki will/coluld/should be an fully CPAN-ized and full featured PSGI compatible
framework (like Dancer, Mojolicious) and maybe will want enable mounting PSGI apps
into foswiki, and will support request dispatching (routing) then the 3rd variant is the right way.
This approach was chosen e.g. by WebGUI.
So, the answer depends a bit on the vision of where FW is want to go...
--
JozefMojzis - 27 Dec 2011
Whatever approach we choose, there must be some way to still run latest plugins on a non-psgi foswiki. So these need a way to get access to the request
and response object to perform at least the most common operations, i.e. get url params. There are some plugins that also change http headers and/or generate the output body by themselves, that is don't use
writeCompletePage
. Porting
TopicInteractionPlugin might become tricky as well as it implements chunked vs non-chunked and multipart vs streamed uploads. Not sure how that feels like going thru plack...
--
MichaelDaum - 27 Dec 2011
Michael, why exactly doe we need a non-psgi-foswiki? or do you mean pre-2.0 foswiki?
--
SvenDowideit - 27 Dec 2011
MichaelDaum - When FW will have PSGI support (and several its parts will be moved into middleware level as mentioned above - Static file serving, authentication etc...) maintain two versions of FW will be pain, imo. What's a point in the need of non-psgi-fw?
--
JozefMojzis - 27 Dec 2011
Don't get me wrong: I am ALL for moving to psgi; I don't need a non-psgi foswiki-2.0. That would be b*s*.
Yet the issue at hand should be all too obvious: there will be a considerable transition phase of maybe over 1 year where people won't upgrade to a psgi foswiki. It normally takes a considerably time for the newest foswiki core engine to reach say 90% of all running foswiki engines installed out there. People touch a running system, not until they feel enuf of a pain to actually do upgrade the core engine for whatever reason.
For instance foswiki-1.0.9 was an excellent release and still is widely in use.
However, in contrast to that, people do upgrade individual plugins far far more frequent.
So we must not force people to immediately upgrade their core engine as well just to upgrade some plugins.
Similarly, we better don't want to end up with most plugins being incompatible with foswiki-2.0.
That's why from a plugins' perspective things might get complicated. Plugin authors need a way to run plugins on both flavors of foswiki. Moving to psgi is the kind of paradigm shift that potentially forces users into decisions that they don't like.
We better make them
like psgi instead of creating
pain to follow that paradigm shift.
--
MichaelDaum - 28 Dec 2011
thankyou for clearing up what you meant by 'non-psgi' (in that you mean the support of pre-foswiki2.0
its true that we will need a compatibility layer for that.
--
SvenDowideit - 28 Dec 2011
Foswiki::Request
was a drop-in replacement of
CGI.pm
.
Foswiki::Func::getRequestObject
was introduced to replace a function that returned a CGI object. I don know Plack API yet, but if it's so different I'd vote for option #2. Besides, it's
very important to figure out an elegant way to make plugins work with pre-psgi- and psgi- foswiki versions, as Michael pointed (that deserves dedicated documentation about).
--
GilmarSantosJr - 29 Dec 2011
See this great presentation:
Deploying Plack Web Applications: OSCON 2011
--
MichaelDaum - 27 May 2013