MakeFoswikiPSGIConformant

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.

-- 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 smile 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.

  1. 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.
  2. 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.
  3. 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 smile

-- 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... smile

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... smile

-- 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
 
Topic revision: r33 - 27 May 2013, MichaelDaum
The copyright of the content on this website is held by the contributing authors, except where stated elsewhere. See Copyright Statement. Creative Commons License    Legal Imprint    Privacy Policy