8 posts tagged “perl”
I will be giving a talk titled Catalyst & Chained: Bondage for better applications at the Orlando Perl Oasis.
Abstract:
Need
to build a web application and keep hearing about methods you aren't
quite sure of? Know Catalyst but don't feel you really "know" it. We
won't go into carnal knowledge, but we will explore the various
dispatch mechanisms to build robust and extensible web applications.
The primary focus is on Catalyst and the Chained dispatch method, and techniques for getting the most out of this strategy. Employing these techniques allow better extensibility and flexibility.
In this talk, we will cover:
- Benefits of chaining
- Basic chained paths
- Configuring chained paths
- Using controller base classes for unifying chains
- Troubleshooting chains gone wrong
- Exception handling
Knowledge of Catalyst is helpful, but not required. A basic understanding of Object Oriented principles, such as inheritance, will also be helpful.
Perl is a superb language and I'm quite fond of it. It has a powerful OO system with a moderately insane API into it, but Moose takes care of that.
Catalyst takes care of the migration from cgi-lib.pl and CGI.pm into the modern era of actual frameworks.
DBIx::Class is unrivaled in the realm of ORMs. The power of chained result sets and (albeit needing to be refactored) power of SQL::Abstract is second to none. It makes everything fantastically simple to build.
My rec indoor soccer team is shuffling players, and we try to keep several slots open for part-time players and we needed a simple way of managing the roster. There was a Japanese utility that one of the managers pointed out to me, and it seemed like a great fit. After a weekend of hacking, and at first building an overly complicated system, I came up with a roster app. Searching for a name yielded nothing, so it's called Roostermatic.
ROOOOOSTERMATIC. Come on, say it with me.
If you have any sort of a rec league/volunteer-based squad for team-play then go over there, use OpenID to login and you can then create a team and manage your upcoming games. It was a very quick application to write, and the UI took by far the longest time, so please send feedback.
I'm hoping to integrate it into some other apps, but for now it's a good game management app with an Atom feed for upcoming games.
On more technical notes, it's built-up using Catalyst::Controller::REST which means it is REST-based. It requires authentication for most things and I haven't hooked up a webservices auth method yet so it really only operates cleanly in the browser. If I get interest in an API (especially for adding games, since I figure a lot of people will use a scraper to inject games) then I'll get around to it.
It makes usage of Template Toolkit, and sadly not that much Moose. There just wasn't a lot of need for it since the biggest part was validation. That's where DBIx::Class came in so nicely, writing a conduit for Data::FormValidator and the schema classes is a piece of cake. I didn't use anything on CPAN because I have a crazy system that croaks on error with an object that can then be used to populate form stickiness. It's heavily dependent on my TT style and isn't very suited for general purpose consumption, but I'd be happy to share if folks are interested.
I'm using MySQL for the backend RDBMS. Our application stack currently has MySQL Replication going on and I rarely feel like futzing with Pg on an admin/architecture level so MySQL constantly wins that battle. I do prefer PostgreSQL in all other facets and earnestly hope that replication is someday as easy as it is in MySQL.
It's running on a rather complicated app stack that consists of nginx, varnish and external FastCGI. I've nearly given up completely on Apache and find the alternatives much better suited for modern deployments. I have another entry pending that describes the service layout which I hope everybody will find informative... but it's not ready yet, so hang tight.
My wife just returned from shopping and giddily approached me and asked, "How do you spell Catalyst?" After confirming the spelling, she pulls out a box and goes, "It's Catalyst... Cologne!"
I love her for a) knowing the project and b) identifying cologne at a discount store that shares the name and buying it for me.
I was very saddened to see a posting on SoccerTV.com that they're closing up shop after selling their assets. It's a very nice and easy way to just view what upcoming games are going to be on. I only get Fox Soccer Channel, so it isn't that big of a deal but some of my friends have other channels (Setanta, GolTV, etc).
So, I did some quick Christmas hacking, and with the help of Web::Scraper (thanks Miyagawa!) and a quick domain registration I have a new site launched.
Soccer fans enjoy, and let me know what other channels you want me to add in (and I'm adding in more leagues as well) because I want to have a really good single source for soccer lineups.
I Watch Soccer [http://www.iwatchsoccer.com]
Let me know if you encounter any problems. It is running on a pretty limited host, but it is going to be moving to a beefier server soon.
(and yes, there are ads. I do have to pay my server bills... I just want to find the right balance between number of ads and content... feedback welcome)
Overview
At my job, we've just about finished work on the next segment of our Catalyst-based application. It required the implementation of a JobQueue system, and after careful consideration we narrowed down our choices.
Why TheSchwartz?
Aside from the fun statements that are made while working it into every day business conversation, it had a few things that really stood out over the competition. What competition, you say? Well, we really didn't have many options. Our choices for a reliable jobqueue (reliable meaning it handles failure conditions internally, and can guarantee success or failure) were really TheSchwartz, Catalyst::Engine::JobQueue or a home grown solution. TheSchwartz was really the only choice.
Getting it running
Setup was actually very simple. Aside from the hidden doc directory containing the schema, it was all laid out in a sane fashion. We configured one of our higher powered slaves to be the jobqueue database, and created the InnoDB tables. After that, configuring the test cases to use our DB and we were in business. Things couldn't have gone easier, really. Well, maybe if there was more Pod available but I'm not complaining one bit, considering how well it works.
Building Job Producers
Obviously, the worker machines are going to have a variety (nigh, a plethora) of tasks as time goes on. Building a variety of worker classes to dispatch the various commands grows tiring. This is where the ingenuity of one of our developers came into play and Object::Recorder was born. What this module allows us to do is have object-level continuations. This allows us to have a simple model class that uses Object::Recorder to insert jobs into the queue. The worker threads are simple Object::Recorder::Player objects that replay the serialized method calls (including construction). This means that we can modify our JobProducer and underlying worker code without ever having to touch TheSchwartz workers. Everything Just Works. Mostly, but that's what the community and RT is for.
Those in the perl community should know the name. Tatsuhiko Miyagawa (vox: miyagawa) is a very prolific perl author, and has produced some really great stuff.
The one that currently has my fascination is Plagger. Yesterday I had a an idea to combine the RSS feeds at work, with another couple convenience utilities via Jabber. After diving into POE::Component::Jabber I remembered Plagger, and how most of the hard work is already done for me. Unfortunately, there was no notification engine for Jabber. No matter, I took a gander at the IRC notification scripts (plagger-ircbot and Plagger::Notify::IRC) and realized that it is trivial to convert these over to notification over XMPP.
After about 45 minutes of fiddling, I have my very own "J. Shirley Bot" along with Plagger::Notify::Jabber::XMPP and plagger-jabberbot. I'll be sending them towards Miyagawa for hopeful inclusion soon. The only thing that I still have open in my head is how to handle who gets notified. I don't want to add just anybody who is on the buddy list (and gets a packet) because that isn't easily controlled. But maintaining a separate notification list is somewhat of a pain... I'll figure this out, and wrap it up.
Decisions, decisions! Either way, I'm very happy. Huge plug for Plagger being awesome, and many props to Miyagawa.
Today I just pushed a new package to CPAN that introduces a "Graphics" helper. The general idea of the package is to install into any Catalyst application a batch of ready-made images that are useful. The only thing it currently has is an AJAX activity indicator, but I'm currently seeking other images to include.
If you have any ideas for new images to be included in this package, please let me know! I'm "jshirley" on IRC, or you can comment here and my email is always open.
Keep an eye out for some screencasts, coming soon!
With DBIx::Class, there are a couple brilliant nuggets that make using the ORM absolutely delightful.
The extensibility of ResultSets is definitely one of those brilliant nuggets of joy. How clean they can make code is really amazing. For the purposes of toEat.com, I want to be able to have shared syntax for an entire Restaurant ResultSet (more than one record) versus a single Restaurant record. A good example is to have tags. I want to know what tags are applicable based upon any group of restaurants, and in client code, there should be no difference between a Restaurant record and a ResultSet. Small things like that keep things tidy.
Using ResultSet extensions, this is easily accomplished. Inside of your DBIx::Class schema object, you can easily instruct DBIx::Class to use a specific ResultSet class, instead of using the base DBIx::Class ResultSet (remember, Perl has multiple inheritance that is very flexible).
The syntax is quite simple:
package toEat::Schema::Restaurants;
__PACKAGE__->table('restaurant_table');
__PACKAGE__->resultset_class('toEat::ResultSet::RestaurantResultset');
Now, I just have to define my RestaurantResultset package:
package toEat::ResultSet::RestaurantResultset;
use strict;
use warnings;use base 'DBIx::Class::ResultSet';
sub labels {
my ( $self ) = @_;
return $self->search_related('label_map')->search_related(
'label', undef, { distinct => 1 });
}
Now, labels is a relation to any Restaurant object as defined in my schema. So, I could use that on any specific Restaurant record, but now I can call labels on a full ResultSet and get back the same results.
This yields consistent syntax, and thus makes template and other front-end code extremely simple:
my $labelRS = $restaurantRS->labels;
print "Restaurant ResultSet labels: " . $labelRS->count . "\n";
while ( my $label = $labelRS->next ) {
print "\t", $label->label, "\n";
}# Consistent syntax!
print $restaurantRS->first->name, "'s labels: " . $labelRS->count . "\n";
$labelRS = $restaurantRS->first->labels;
while ( my $label = $labelRS->next ) {
print "\t", $label->label, "\n";
}
Which executes as:
1..2
ok 1 - use toEat::Schema;
ok 2 - loading schema and connecting to db
Restaurant ResultSet labels: 16
coffee
burger
pizza
chinese
italian
deli
cafe
buffet
sushi
fast food
sandwiches
asian
other
sandwich
burgers
mexican
toEat.com Test Restaurant (32100)'s labels: 16
other