Catalyst::Upgrading - Instructions for upgrading to the latest Catalyst
-=head1 Upgrading to Catalyst 5.90
+=head1 Upgrading to Catalyst 5.90040
-The major change is that L<Plack> now replaces most of the subclasses of
-L<Catalyst::Engine>. If you are using one of the standard subclasses of
-L<Catalyst::Engine> this should be a straightforward upgrade for you. It was
-a design goal for this release to be as backwardly compatible as possible.
-However since L<Plack> is different from L<Catalyst::Engine> it would be
-possible that edge case differences would exist. Therefore we recommend care
-be taken with this upgrade and that testing should be greater than would be
-the case with a minor point update.
+This version of L<Catalyst> offers some support for using L<AnyEvent> and
+L<IO::Async> event loops in your application. In order to achieve this goal
+we needed to make some changes to the way the we finalize the HTTP response
+such that sloppy code that closed over $c and leaked memory will no longer
+work in some manner. For example you might accidently have:
-It is highly recommended that you become familar with the L<Plack> ecosystem
-and documentation. Being able to take advantage of L<Plack> development and
-middleware is a major bonus to this upgrade.
+ $c->stash(my_model => sub { $c->model->find(shift) });
-If you have created a custom subclass of L<Catalyst:Engine> you will need to
-convert it to be a subclass of L<Plack::Handler>.
+If you have old code that leaks memory in this way but otherwise seemed to
+work, it will no longer complete the response properly.
+
+If you don't want to fix your code, you can force the old behavior with the
+global configuration key C<aggressively_close_writer_on_finalize_body>. This
+of course will still leave you with a leaky application and you lose the new
+event loop support, but your application will go back to completing its
+response output. For example:
+
+ package MyApp::Web;
+
+ use Moose;
+ use Catalyst;
+
+ __PACKAGE__->config(
+ name => 'MyApp::Web',
+ enable_catalyst_header => 1,
+ disable_component_resolution_regex_fallback => 1,
+ aggressively_close_writer_on_finalize_body => 1,
+ );
+
+ __PACKAGE__->setup;
+
+See L<Catalyst::Component::ContextClosure> for help on how to close over the
+context safely, should you need to do this. See L<CatalystX::LeakChecker>
+and L<Catalyst::Controller::LeakTracker> for help if you want to solve your
+memory leak issues.
+
+=head1 Upgrading to Catalyst 5.9
+
+The major change is that L<Plack>, a toolkit for using the L<PSGI>
+specification, now replaces most of the subclasses of L<Catalyst::Engine>. If
+you are using one of the standard subclasses of L<Catalyst::Engine> this
+should be a straightforward upgrade for you. It was a design goal for
+this release to preserve as much backwards compatibility as possible.
+However, since L<Plack> is different from L<Catalyst::Engine>, it is
+possible that differences exist for edge cases. Therefore, we recommend
+that care be taken with this upgrade and that testing should be greater
+than would be the case with a minor point update. Please inform the
+Catalyst developers of any problems so that we can fix them and
+incorporate tests.
+
+It is highly recommended that you become familiar with the L<Plack> ecosystem
+and documentation. Being able to take advantage of L<Plack> development and
+middleware is a major bonus to this upgrade. Documentation about how to
+take advantage of L<Plack::Middleware> by writing your own C<< .psgi >> file
+is contained in L<Catalyst::PSGI>.
+
+If you have created a custom subclass of L<Catalyst:Engine>, you will
+need to convert it to be a subclass of L<Plack::Handler>.
If you are using the L<Plack> engine, L<Catalyst::Engine::PSGI>, this new
-release supercedes that code.
+release supersedes that code.
-If you are using a subclass of L<Catalyst::Engine> that is aimed at nonstandard
-or internal / testing uses, such as L<Catalyst::Engine::Embeddable> you should
-still be able to continue using that engine.
+If you are using a subclass of L<Catalyst::Engine> that is aimed at
+nonstandard or internal/testing uses, such as
+L<Catalyst::Engine::Embeddable>, you should still be able to continue
+using that engine.
Advice for specific subclasses of L<Catalyst::Engine> follows:
=head2 Upgrading the FastCGI Engine
-No upgrade needed if your myapp_fastcgi.pl script is already upgraded
-enough to use L<Catalyst::Script::FastCGI>.
+No upgrade is needed if your myapp_fastcgi.pl script is already upgraded
+to use L<Catalyst::Script::FastCGI>.
=head2 Upgrading the mod_perl / Apache Engines
-The engines that are build upon the various iterations of mod_perl,
-L<Catalyst::Engine::Apache::MP13> and
-L<Catalyst::Engine::Apache2::MP20> should be seemless upgrades and will
-work using using L<Plack::Handler::Apache1> or L<Plack::Handler::Apache2>
-as required.
+The engines that are built upon the various iterations of mod_perl,
+L<Catalyst::Engine::Apache::MP13> (for mod_perl 1, and Apache 1.x) and
+L<Catalyst::Engine::Apache2::MP20> (for mod_perl 2, and Apache 2.x),
+should be seamless upgrades and will work using using L<Plack::Handler::Apache1>
+or L<Plack::Handler::Apache2> as required.
-L<Catalyst::Engine::Apache2::MP19>, is however no longer supported, as Plack
-does not support mod_perl version 1.99??? FIXME - is this true?
+L<Catalyst::Engine::Apache2::MP19>, however, is no longer supported, as
+Plack does not support mod_perl version 1.99. This is unlikely to be a
+problem for anyone, as 1.99 was a brief beta-test release for mod_perl
+2, and all users of mod_perl 1.99 are encouraged to upgrade to a
+supported release of Apache 2 and mod_perl 2.
=head2 Upgrading the HTTP Engine
=head2 Upgrading the CGI Engine
If you were using L<Catalyst::Engine::CGI> there is no upgrade needed if your
-myapp_cgi.pl script is already upgraded enough to use L<Catalyst::Script::CGI>.
+myapp_cgi.pl script is already upgraded to use L<Catalyst::Script::CGI>.
-=head2 Upgrading the Preforking Engine
+=head2 Upgrading Catalyst::Engine::HTTP::Prefork
If you were using L<Catalyst::Engine::HTTP::Prefork> then L<Starman>
-is automatically loaded.
+is automatically loaded. You should (at least) change your C<Makefile.PL>
+to depend on Starman.
+
+You can regenerate your C<myapp_server.pl> script with C<catalyst.pl>
+and implement a C<MyApp::Script::Server> class that looks like this:
+
+ package MyApp::Script::Server;
+ use Moose;
+ use namespace::autoclean;
-XXX FIXME - note how to run Starman with different options.
+ extends 'CatalystX::Script::Server::Starman';
+
+ 1;
+
+This takes advantage of the new script system, and will add a number of
+options to the standard server script as extra options are added by
+Starman.
+
+More information about these options can be seen at
+L<CatalystX::Script::Server::Starman/SYNOPSIS>.
+
+An alternate route to implement this functionality is to write a simple .psgi
+file for your application, and then use the L<plackup> utility to start the
+server.
=head2 Upgrading the PSGI Engine
-If you were using L<Catalyst::Engine::PSGI> this new release supercedes this
-engine in supporting L<Plack>. By default the Engine is now always L<Plack>.
-As a result, you can stop depending on L<Catalyst::Engine::PSGI> in your
-C<Makefile.PL>. Additionally, if you have an C<app.psgi> script you no longer
-need to specify the PSGI engine. Instead, the L<Catalyst> application class
-now has a new method C<psgi_app> which returns a L<Plack> compatible coderef.
+If you were using L<Catalyst::Engine::PSGI>, this new release supersedes
+this engine in supporting L<Plack>. By default the Engine is now always
+L<Plack>. As a result, you can remove the dependency on
+L<Catalyst::Engine::PSGI> in your C<Makefile.PL>.
+
+Applications that were using L<Catalyst::Engine::PSGI>
+previously should entirely continue to work in this release with no changes.
+
+However, if you have an C<app.psgi> script, then you no longer need to
+specify the PSGI engine. Instead, the L<Catalyst> application class now
+has a new method C<psgi_app> which returns a L<PSGI> compatible coderef
+which you can wrap in the middleware of your choice.
+
+Catalyst will use the .psgi for your application if it is located in the C<home>
+directory of the application.
For example, if you were using L<Catalyst::Engine::PSGI> in the past, you will
-have written (or generated) an C<app.psgi> file similar to this one:
+have written (or generated) a C<script/myapp.psgi> file similar to this one:
use Plack::Builder;
use MyCatalytApp;
sub { MyCatalystApp->run(@_) };
};
-Instead, you should now just do:
+Instead, you now say:
use Plack::Builder;
use MyCatalystApp;
builder {
enable ... #enable your desired middleware
- MyCatalystApp->raw_psgi_app;
+ MyCatalystApp->psgi_app;
};
-Applications that were using and deploying via L<Catalyst::Engine::PSGI>
-previously should entirely continue to work in this release with no changes,
-however if you were using Catalyst::Engine::PSGI previously, then this is
-not compatible with L<Catalyst::Test> in the new version, and instead of
-running a test server
+In the simplest case:
+
+ MyCatalystApp->setup_engine('PSGI');
+ my $app = sub { MyCatalystApp->run(@_) }
+
+becomes
+
+ my $app = MyCatalystApp->psgi_app(@_);
-=head2 Engines which are known broken
+B<NOT>:
-The following engines B<DO NOT> work as of Catalyst version 5.90. The core
-team is extremely happy to work with the developers and/or users of these
-engines to help them port to the new Plack/Engine system, however applications
-which are currently using these engines B<WILL NOT> run without modification
-to the engine code.
+ my $app = sub { MyCatalystApp->psgi_app(@_) };
+ # If you make ^^ this mistake, your app won't work, and will confuse the hell out of you!
+
+You can now move C<< script/myapp.psgi >> to C<< myapp.psgi >>, and the built-in
+Catalyst scripts and your test suite will start using your .psgi file.
+
+B<NOTE:> If you rename your .psgi file without these modifications, then
+any tests run via L<Catalyst::Test> will not be compatible with the new
+release, and will result in the development server starting, rather than
+the expected test running.
+
+B<NOTE:> If you are directly accessing C<< $c->req->env >> to get the PSGI
+environment then this accessor is moved to C<< $c->engine->env >>,
+you will need to update your code.
+
+=head2 Engines which are known to be broken
+
+The following engines B<DO NOT> work as of Catalyst version 5.9. The
+core team will be happy to work with the developers and/or users of
+these engines to help them port to the new Plack/Engine system, but for
+now, applications which are currently using these engines B<WILL NOT>
+run without modification to the engine code.
=over
=item Catalyst::Engine::Wx
+=item Catalyst::Engine::Zeus
+
+=item Catalyst::Engine::JobQueue::POE
+
+=item Catalyst::Engine::XMPP2
+
+=item Catalyst::Engine::SCGI
+
=back
=head2 Engines with unknown status
-The following engines have untested or unknown compatibility. Reports are
-highly welcomed:
+The following engines are untested or have unknown compatibility.
+Reports are highly encouraged:
- Catalyst::Engine::Embeddable - needs testing, should work?
- Catalyst::Engine::XMPP2
- Catalyst::Engine::SCGI
- Catalyst::Engine::Mojo
- Catalyst::Engine::Zeus - broken for ages
- Catalyst::Engine::JobQueue::POE - broken for ages
- Catalyst::Engine::Stomp - fixed
- Catalyst::Engine::Server (Marked as Deprecated)
- Catalyst::Engine::HTTP::POE (Marked as Deprecated)
+=over
+
+=item Catalyst::Engine::Mojo
-=head2 Using middleware
+=item Catalyst::Engine::Server (marked as Deprecated)
-XXX Should this be here or elsewhere?
+=item Catalyst::Engine::HTTP::POE (marked as Deprecated)
-=head2 Making an app.psgi file
+=back
-=head2 Running with plackup?
+=head2 Plack functionality
+
+See L<Catalyst::PSGI>.
+
+=head2 Tests in 5.9
+
+Tests should generally work the same in Catalyst 5.9, but there are
+some differences.
+
+Previously, if using L<Catalyst::Test> and doing local requests (against
+a local server), if the application threw an exception then this
+exception propagated into the test.
+
+This behavior has been removed, and now a 500 response will be returned
+to the test. This change standardizes behavior, so that local test
+requests behave similarly to remote requests.
+
+=head2 Regex dispatch type is deprecated.
+
+The Regex dispatchtype (L<Catalyst::DispatchType::Regex>) has been deprecated.
+
+You are encouraged to move your application to Chained dispatch (L<Catalyst::DispatchType::Chained>).
+
+If you cannot do so, please add a dependency to Catalyst::DispatchType::Regex to your application's
+Makefile.PL
=head1 Upgrading to Catalyst 5.80
is using deprecated code, or relying on side effects, then you could have
issues upgrading to this release.
-Most issues found with pre-existing components have been easy to
+Most issues found with existing components have been easy to
solve. This document provides a complete description of behavior changes
which may cause compatibility issues, and of new Catalyst warnings which
-be unclear.
+might be unclear.
If you think you have found an upgrade-related issue which is not covered in
this document, please email the Catalyst list to discuss the problem.
You can only apply method modifiers after the application's C<< ->setup >>
method has been called. This means that modifiers will not work with methods
-which run during the call to C<< ->setup >>.
+run during the call to C<< ->setup >>.
See L<Catalyst::Manual::ExtendingCatalyst> for more information about using
L<Moose> in your applications.
to resolve methods using C3, rather than the unpredictable dispatch
order of L<NEXT>.
-This issue is characterised by your application failing to start due to an
+This issue manifests itself by your application failing to start due to an
error message about having a non-linear @ISA.
The Catalyst plugin most often causing this is
To be able to generate a linear @ISA, the list of superclasses for each
class must be resolvable using the C3 algorithm. Unfortunately, when
superclasses are being used as mixins (to add functionality used in your class),
-and with multiple inheritence, it is easy to get this wrong.
+and with multiple inheritance, it is easy to get this wrong.
Most common is the case of:
use Test::More;
isnt(BaseClass->can('foo'), Child->can('foo'));
-=head2 Extending Catalyst::Request or other classes in an ad-hoc manner using mk_accessors
+=head2 Extending Catalyst::Request or other classes in an ad hoc manner using mk_accessors
Previously, it was possible to add additional accessors to Catalyst::Request
(or other classes) by calling the mk_accessors class method.
COMPONENT method you would like to inherit is the first (left-hand most)
COMPONENT method in your @ISA.
+=head2 Development server relying on environment variables
+
+Previously, the development server would allow propagation of system
+environment variables into the request environment, this has changed with the
+adoption of Plack. You can use L<Plack::Middleware::ForceEnv> to achieve the
+same effect.
+
=head1 WARNINGS
=head2 Actions in your application class
The first time one of these methods is called, a warning will be emitted:
Class $class is calling the deprecated method Catalyst::Dispatcher::$public_method_name,
- this will be removed in Catalyst 5.9X
+ this will be removed in Catalyst 5.9
You should B<NEVER> be calling any of these methods from application code.