[Catalyst-commits] r14191 - in trunk/examples/CatalystAdvent/root:
2011 static/images static/images/2011
jnapiorkowski at dev.catalyst.perl.org
jnapiorkowski at dev.catalyst.perl.org
Tue Dec 6 16:10:14 GMT 2011
Author: jnapiorkowski
Date: 2011-12-06 16:10:14 +0000 (Tue, 06 Dec 2011)
New Revision: 14191
Added:
trunk/examples/CatalystAdvent/root/2011/6.pod
trunk/examples/CatalystAdvent/root/static/images/2011/
trunk/examples/CatalystAdvent/root/static/images/2011/querylog.png
Log:
day 6 article
Added: trunk/examples/CatalystAdvent/root/2011/6.pod
===================================================================
--- trunk/examples/CatalystAdvent/root/2011/6.pod (rev 0)
+++ trunk/examples/CatalystAdvent/root/2011/6.pod 2011-12-06 16:10:14 UTC (rev 14191)
@@ -0,0 +1,217 @@
+=head1 Overview
+
+This is a short article that shows how one can use the new L<Plack> based
+L<Catalyst> to integrate middleware components designed to assist developers
+understand how your database is performing. We also will discuss how having
+L<Plack> as a core L<Catalyst> technology can assist us in broadening our
+software ecosystem and involve a larger developer base. An example of the
+approach taken to port a L<Catalyst> specific role to L<Plack> middleware is
+given.
+
+The distributions discussed will include: L<Plack::Middleware::DBIC::QueryLog>,
+L<Plack::Middleware::Debug::DBIC::QueryLog> and a trait for the L<Catalyst>
+L<DBIx::Class> model (L<Catalyst::Model::DBIC::Schema>) called
+L<Catalyst::TraitFor::Model::DBIC::Schema::QueryLog::AdoptPlack>.
+
+Additionally, having some familiarity with L<Plack> and with its debugging
+middleware, L<Plack::Middleware::Debug> would be valuable.
+
+=head1 Catalyst and Plack
+
+One of the things that has been great about being a L<Catalyst> developer is in
+how the project has been both able to maintain long term backward compatibility
+as well as adopt Perl / CPAN's latest and greatest. For example, a few years
+ago we ported the L<Catalyst> codebase to L<Moose>. This gave us a solid base
+not only for the core L<Catalyst> code, but for people building websites on top
+of it.
+
+Recently we completed the project to port L<Catalyst> to use L<Plack> as a core
+technology. I believe this will have a powerful impact on our future coding
+goals, since it will allow us to concentrate our available programming talent
+on the things that make L<Catalyst> the most powerful and flexible MVC system
+for Perl. Over time I foresee much of what lives in the L<Catalyst::Plugin>
+namespace become simple wrappers on top of L<Plack::Middleware> This is a
+total win - win situation since it means we have less code that is specific to
+L<Catalyst> (meaning even more time for core developers to spend on the most
+unique aspect of L<Catalyst>) and it also means that we can levage the concentrated
+efforts of developers across the CPAN ecosystem. Not everyone is a L<Catalyst>
+developer, and even those of us that are don't always need the full power and
+complexity of L<Catalyst>. Having more code in Plack Middleware means that on
+those projects where I want a more light weight approach (such as L<Web::Simple>)
+I have access to the same tools as I do with L<Catalyst> for solving common
+problems like authentication and sessioning.
+
+=head1 Integrating Plack::Middleware::Debug::DBIC::QueryLog with Catalyst
+
+If you have been using L<Catalyst> and L<DBIx::Class> for a while, you probably
+have used L<DBIx::Class::QueryLog>, which is a great tool for giving you better
+insight into how your database is performing. For quite a while we've had
+L<Catalyst::TraitFor::Model::DBIC::Schema::QueryLog>, which is a trait that
+enables querylogging per request to your L<Catalyst> application. However this
+great feature is locked into L<Catalyst> using this approach. Instead, let's
+see what can happen if we extract that functionality.
+
+=head2 Plack::Middleware::DBIC::QueryLog
+
+L<Plack::DBIC::QueryLog> is a simple bit of L<Plack> middleware that places an
+instance of L<DBIx::Class::QueryLog> into your L<Plack> C<$env> under the key
+C<plack.middleware.dbic.querylog>. It also exposes some helper methods designed
+to be a consistent interface for finding and creating that key. Here's how it
+might look in your application:
+
+ use Plack::Builder;
+ use MyDatabaseEnabledCatalystApplication;
+
+ my $app = MyDatabaseEnabledCatalystApplication->psgi_app;
+
+ builder {
+ enable 'DBIC::QueryLog';
+ $app;
+ };
+
+Now when you startup the application using C<plackup> your will have a fresh
+instance of L<DBIx::Class::QueryLog> available for logging.
+
+This middleware accepts arguments which match the interface given in
+L<DBIx::Class::QueryLog>. Anything that you can pass to the C<new> method
+of that class you can set via C<querylog_args>:
+
+ builder {
+ enable 'DBIC::QueryLog',
+ querylog_args => {passthrough => 1};
+ $app;
+ };
+
+C<passthrough> is one of the more useful options, since it makes sure that the
+querylog allows any database events it intercepts pass through done to whatever
+logging you might be doing at your L<Catalyst> application level. In many
+cases when you are developing you might use the C<DBIC_TRACE> environment
+variable to help you understand what L<DBIx::Class> is doing (in addition to
+the Querylogger). Setting the passthrough option will allow you to do both.
+
+=head2 Catalyst::TraitFor::Model::DBIC::Schema::QueryLog::AdoptPlack
+
+Next, lets look at how to get this new querylog exposed to L<Catalyst>. If
+you are using L<DBIx::Class> with L<Catalyst>, you are probably using
+L<Catalyst::Model::DBIC::Schema>. This model gives you the basic functionality
+to connect to a database and expose your DBIC classes to your L<Catalyst>
+application. It also has a clean interface for extending its functionality,
+which is based on L<Moose> and L<Moose::Role>. Basically you can wrap traits
+(which are just L<Moose::Role>s) at setup on top of your Catalyst DBIC
+model. Since this is a configuration option, this means that you can have
+different traits applied in different environments. For example, in production
+you might be using replication, and you'd apply the trait
+L<Catalyst::TraitFor::Model::DBIC::Schema::Replicated>. On the flip side, in
+development you might want to use the querylogger to help developers understand
+bottlenecks in their SQL. Here's an example:
+
+Assuming you have a class called L<MyDatabaseEnabledCatalystApplication::Model::Schema>
+which looks something like this:
+
+ package MyDatabaseEnabledCatalystApplication::Model::Schema;
+ use parent 'Catalyst::Model::DBIC::Schema';
+
+ 1;
+
+Then, in your configuration file, you have something like this (assuming you
+are using the standard L<Config::General>)
+
+ <Model::Schema>
+ schema_class MyDatabaseEnabledCatalystApplication::Schema
+ traits QueryLog::AdoptPlack
+ <connect_info>
+ dsn dbi:Pg:dbname=mypgdb
+ user postgres
+ password ""
+ </connect_info>
+ </Model::Schema>
+
+Again, a trait is just a L<Moose::Role> that gets applied at setup time, via
+configuration, which will make it easy to have your debugging trait in development
+but not in production. Please review the documentation for L<Catalyst::Plugin::ConfigLoader>
+if you need a refresher on how to use a configuration file and have different
+configurations for different purposes.
+
+So that is it! Now, when L<Catalyst> runs a request, any L<DBIx::Class> events
+will be logged via the L<DBIx::Class::QueryLog> which you have enabled via the
+L<Plack> middleware you added above.
+
+=head2 Plack::Middleware::Debug::DBIC::QueryLog
+
+You are now logging queries, but you have no reporting tools or way to see the
+results of that logging. Luckily, L<Plack::Middleware::Debug> offers us a
+standard approach for adding debuggin panels to your web application. Building
+on top of this system is straightforward. Here's how to take that querylog and
+have it displayed as a nicely formated debugging panel:
+
+ use Plack::Builder;
+ use Plack::Middleware::Debug;
+ use MyDatabaseEnabledCatalystApplication;
+
+ my $app = MyDatabaseEnabledCatalystApplication->psgi_app;
+ my $panels = Plack::Middleware::Debug->default_panels;
+
+ builder {
+ enable 'DBIC::QueryLog';
+ enable 'Debug', panels =>['DBIC::QueryLog', @$panels];
+ $app;
+ };
+
+This creates a L<Plack::Middleware::Debug> console that addes your querylog
+report to the default list of panels. If you run your application you should
+get a debug console similar to this one:
+
+=begin xhtml
+
+<img src="/static/images/2011/querylog.png" alt="" />
+
+=end xhtml
+
+=head2 Control and Tweaks
+
+Since the debug panel is a very common use case, it will automatically wrap
+the underlying L<Plack::Middleware::DBIC::QueryLog> for you, which allows you
+to simplify your code a bit:
+
+ builder {
+ enable 'Debug', panels =>['DBIC::QueryLog', @$panels];
+ $app;
+ };
+
+Generally I only manually add L<Plack::Middleware::DBIC::QueryLog> when I have
+some sort of logging that lives outside the debugging panels. Additionally,
+you might want to only add the debug panels when you are in debugging mode, and
+you might wish to pass some arguments to the underlying L<DBIx::Class::QueryLog>
+Here's a complete example:
+
+ use Plack::Builder;
+ use Plack::Middleware::Debug;
+ use MyDatabaseEnabledCatalystApplication;
+
+ my $app = MyDatabaseEnabledCatalystApplication->psgi_app;
+ my $panels = Plack::Middleware::Debug->default_panels;
+
+ builder {
+ enable_if {
+ $ENV{CATALYST_DEBUG}
+ } 'Debug', panels =>[['DBIC::QueryLog', passthrough=>1], @$panels];
+ $app;
+ };
+
+=head1 For More Information
+
+The source code for the three CPAN distributions discussed contain detailed
+examples and test cases, which are a great next step learning tool. I highly
+recommend reviewing them.
+
+=head1 Summary
+
+Having L<Plack> as a core technology in L<Catalyst> broadens the available
+software ecosystem you can access in order to do you job faster and better.
+However this is a two way street, so next time you are thinking of writing some
+L<Catalyst> specific code, such as a plugin or a trait for some existing tool,
+you should consider how that functionality could be brought down to the L<Plack>
+level. The code written to expose L<DBIx::Class::QueryLog> via L<Plack>
+middleware can serve as a decent example of how to do this.
+
+=cut
Added: trunk/examples/CatalystAdvent/root/static/images/2011/querylog.png
===================================================================
(Binary files differ)
Property changes on: trunk/examples/CatalystAdvent/root/static/images/2011/querylog.png
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
More information about the Catalyst-commits
mailing list