Sunday, March 23, 2014

Dancer Sessions using PSGI

A few weeks on #dancer channel, a user was having issues using Dancer::Session::PSGI. I've never worked directly with Plack besides reading the handbook and few play apps. (well a few weeks ago, I dug into Dancer::Debug.). Using both together was an intriguing problem stuck in my mind.

The person on the channel was reporting unreliable reading of session data and other odd behavior. As I started to dig into the problem, I realized that i need to create two apps, one pure Plack and one Dancer with middleware wrapper. I created a public repo on github with my test apps: Dancer and Plack session.

Since, I didn't want to deal with html and wanted a bit of structure with return data, I made both test apps return JSON and have pretty simple routes

I started off using the documentation from Plack::Middleware::Session to create this test app:

Next I created a Test Dancer PSGI app, which basically had a way to show value and update it. Here is the non-exciting Dancer app:

I updated bin/app.pl to use Plack::Builder directly instead of creating a wrapper (which I'd like to try as well probably in a branch):

With those all setup, I started both apps using plackup but each with slightly different command lines:

 magic-bus> plackup pure_plack/bin/app.psgi &
 magic-bus> plackup -p 3000 dancer_plack_session/bin/app.pl &

I created a curl_cookie script to use and store cookies and verbose dump out request/response information. I needed to see what cookies where getting sent in and back.

After i fired up each app server, the first set of requests dumped the following:

Well that is odd. A couple quick bullets:

  • plack app did what was expected (the app increments counter in session after return response therefore on 2nd request being set to 1 is ok).
  • dancer app didn't return '2' (since other app has write to the counter twice) plus it appears to be using both 'dancer.session' and 'plack_session'. This is wrong.
After I dug around a bit (since that session name seems wrong), I found two things.
  • A bug with Dancer::Session::Abstract: #1004
  • And in this case, Dancer::Session is only creating the session not retrieving (since it doesn't think there is one yet) which makes sense. (why retrieve when you are first generating the session.)

The initial session being created to the first request to Dancer not finding the existing plack session information. After that initial request, then it would pick up plack session data. The current behavior would lead to this confusing response the 2nd time from Dancer app:

{
   "visits" : 2
}

I fixed up Dancer::Session::Abstract to use 'plack_session' cookie and that resolved the session not getting read on initial request.

A bit unexpectedly, I see that Dancer is setting cookie with different session id than PSGI. PSGI includes its own session cookie. This is expected since the Plack middleware runs after Dancer (think of the onion from handbook: ).

Here is example of response made to Dancer app:

In the end its working now. Dancer is able to pull in session information from Plack session but its still a bit messy. I'm not sure if multiple session cookies is considered a bug or not. I think it might be best to have Dancer not do any cookie stuff and only use the session data if its available in the environment but looking over the Dancer session code, this doesn't look straightforward w/out major changes to core Dancer code.

Any ideas out there?

__END__

Wednesday, March 12, 2014

Template Toolkit Debugging inside of Perl Dancer

The other day someone was asking how to enable Template Toolkit debugging inside of Perl Dancer in the #dancer IRC channel, it seemed like a good time for a write up.

The template engine configuration directive supports passing through various options like start_tag and stop_tag as explained in Dancer::Template::TemplateToolkit POD. And alludes to being able to pass other options.

How

To pass TT options like those found in Template::Constants, there must be a DEBUG section in engines -> template_toolkit, usually found in config.yml.

Example Snippet

Here is an example:

A few notes

  • Remove leading DEBUG_ from TT constants. The option DEBUG_PLUGINS becomes plugins.
  • Multiple options can be separated with a comma. Example:DEBUG: "provider,plugins".
  • Be warned, some of these options can lead to tons of information :)
__END__

Monday, November 4, 2013

What's installed on my ec2

What's installed on my ec2?

I swear between debian/ubuntu/mac os x/irix (well not anymore), I can never remember how to list installed packages on my ec2. 

Here is is:

   sudo yum list installed

Plus or minus sudo depending on who you are. For once, the command is what i'd expect.

__END__

Tuesday, September 24, 2013

Toying around with backbone.js

Toying around with Backbone.js

At $work, we've been using more and more backbone.js to create a more responsive front end experience and help the dev team manage the code.

I like backbone.js and find that its it is very helpful to seperate data and code on the client. But I've found that it challenges me to think in different ways.

I find it helpful to create an app so I did :)

Introducing Brewers Radio Finder

Over the years, i've often driven between Milwaukee and St. Paul, MN. While on the drive, there are areas of the state where finding the close Brewer's radio station is tough and figuring out which station is the closest to you is difficult when looking at the map from Brewers Radio network. Am I currently closer to Reedsburg or Portage?

The app is pretty simple, you can type in or give it your current location and it will show the 3 closest Brewers radio stations to you. 

You can check it out at http://radiofinder.leecarmichael.com/

If anyone is interested I'd be willing to make the code public on github. I didn't do it by default since I had to do some geocoding and storage of the station locations and i'm not sure if i can share that (even though its public). And i haven't dropped a license in there (not sure which one to do).

The app is only a few parts:
  • backbonejs + bootstrap front end 
  • Perl Dancer backend (serving JSON to front end and some initial templates)
  • MySQL Database
  • Use of Google's geocoding library/service (for initial coding of stations) and GIS::Distance
Using Dancer with backbone is very slick. The Dancer json (de)serialization setup is very elegant. Basically set it in the config and you can return data structures in 'ajax' routes and it does its (de)serialization magic. Pretty nice way to hide that complexity.

As a full start from scratch project in backbonejs that didn't involve todo items. It was a good learning experience. I ran into some mental issues using templates w/ widgets that didn't have a model but otherwise it went pretty well. I had some trouble with routes that opened and closed widgets ('about' dialog was a bit of a fight and still isn't perfect). And I still haven't got my mind around using a view and route with something that didn't have a model (the search inputs). I felt like making it a model was a bit of extra cruft that didn't add value (but i bet it might be helpful as the app grew). There are areas, that i'll revisit when i get some time.

A few future things that I'm working on:
  • Displaying current location and stations on a map (this is pretty close)
  • Fixing a few display issues with the responsive layout on smaller screens
  • More unit tests for "live" dev instance
That's all for now.

__END__