Saturday, 15 November 2014

A matter of time

Strehler 1.3.0 is released. This means that all the problems with Dancer2 0.15x are solved. More than that, requirement about Dancer2 moved up from Dancer2 0.11 to Dancer 0.15002.

In the previous episodes we saw that Dancer2 App, from version 0.15, try to find their configuration file in a directory near the one they are installed, ignoring where is the script that uses them. This was very bad for Strehler becase Strehler apps like Strehler::Admin are installed using CPAN so they are in the local repository, a place where no configuration file can be stored.

Only available solution (for now) is overriding thi behaviour setting environment variable DANCER_CONFDIR to the path where our config.yml actually is. Can we do it inside a script so that we can use this solution in any context, like CPAN tests? The answer is yes, if you know the right things about perl.

First of all, any perl script can access environment variables through the %ENV hash,  a read/write variable always available. So, first step should be to write in your code:

$ENV{DANCER_CONFDIR} = /the/directory/I/want

Now you can think that, including my app, all will work, so you're thinking about something like this:

$ENV{DANCER_CONFDIR} = /the/directory/I/want
use Strehler::Admin

Don't run too fast, this code WILL NOT work.

There's a lot of interesting concepts about perl interpreter behind this problem. Concepts, I hope, one day you'll be curious about. For now it's enough to say that "use" directive will run before DANCER_CONFDIR assignment even though you write it in the end of your file.

 Modules must be loaded before any other piece of code because consistency of any piece of code can be verified only with all the module loaded. Perl interpreter does it without asking nothing, ignoring that you necessary need to do something before.

Can you change this behaviour? Yes, two ways to do it:

  • BEGIN directive will run all the code inside its block before any other code, including use.
BEGIN
{
   $ENV{DANCER_CONFDIR} = /the/directory/I/want
}
use Strehler::Admin;

  • require directive instead of use load the module only when someone ask for it,with no precedence on anything.

$ENV{DANCER_CONFDIR} = /the/directory/I/want
require Strehler::Admin;

You can see an example of this here.

Here are described many ways to configure DANCER_CONFDIR.

Why don't I want to consider this as the definitive solution for the problem? Because I think it's still a dirty way to do things because force you to use an environment variable and disable the original App behaviour that allow each of them to have a separated config file, something that could come useful in some situations.

Sunday, 9 November 2014

Plack::Test and Dancer Session

PSGI is very easy to understand: a black box, something goes in, something goes out. What goes in: a request made of a path and headers. What goes out: a response with a content and more headers.

Plack::Test follows this structure. What you have to test is the black box, you inject the request in it and analyze the response you receive back.

Important thing to understand is that Plack::Test is something very different from an emulation of a browser like LWP::UserAgent. Most important difference is, obviously, in session management, because that's something that should survive between calls and in Plack::test every call is a test by itself, with no memory of what happens around it.

What do you have to do  if you want to test something like a login using Plack::Test? Well, the solution is very easy because the concept of session is AN ILLUSION throughout all the web. It's not just Plack::Test, the HTTP protocol itself is session-less. The "session" you see is just a set of tricks that clients and servers do under the hood.

As we said: a request go, a response returns, nothing more, so the session is something that must be hidden there. In particular, session is controlled throught headers, in particular headers that control browser cookies.

There're a lot of documentation about how cookies and response headers have to interact and probably studying it could be very interesting, but HTTP::Cookies module contains all the knowledge you need so learn to use it will be enough.

Let's do a login and get the response from it:

$r = $cb->( POST '/admin/login', [ user => 'admin', password => 'admin' ] );

Response object $r contain many headers, one of that ask the client to write in a cookie the identifier of dancer session. We can use HTTP::Cookies to extract this information.

my $jar = HTTP::Cookies->new;
$jar->extract_cookies($r);

Now we want that, in the next call, the server find us logged in.

When a browser does a request to a site, it passes in the request all the informations related to the cookies it has. This way it can say to the server what is its dances session identifier. Using that, the server can retrieve any information about the caller, like its status as logged user.

Let's cook a call for admin homepage.

my $req = HTTP::Request->new(GET => $site . '/admin');

WARNING: Considering interaction with HTTP::Cookies do not use HTTP::Request::Common to build the request. HTTP::Cookies can't simply manage a request made that way.

Now we want that this call carry information about the cookies of the previous call, where logged in user session was configured. We just have to get information out from the cookie jar.

$jar->add_cookie_header($req);

Now this req will been seen by the server as the logged user from the previous call did it.

Well, if you configured in a clever way the server too.

Remember? There's no memory between requests client-side AS server-side. Client memory is in the cookies and HTTP::Cookies helps us to manage it. Where is server memory?

Standard session management in Dancer leave session information in RAM. On a development server this is enough, but a development server is something that stay alive between different calls so you can consider information stored in RAM persistent. Plack::Test instantiate the black box fresh new at every call so information about sessions is always trashed at the end of it.

Harddisk is more reliable if you want to store persisten information so switch session management to YAML when doing this kind of test.

Here is a little example of what we said.



Tuesday, 4 November 2014

The darkest hour

I've been away from this place for long time, I know, and I also know that also Strehler has been left with no updates for many months. There're technical questions about all this silence and I want to explain them here.

This summer Dancer2 reached release 0.150000, quite an improvement! A lot of things changed with this release of the framework, most of them related to the concept of App.

Major architectural changes are something I know I have to deal with, talking about Strehler's developement. Dancer2 code is not stable, it's usually considered alpha and I know that chasing its releases is one of the most difficult but important tasks for me as mantainer of a module based on it.

Problem is 0.150000 Dancer2 was too much. I described the issue introduced by this release here, Briefly, an App installed in your local repository gives a lot of trouble when it's time to read configuration files, because App uses its own path to find site resources, ignoring the path of the script that manage site startup.

For now, in my opinion, there's no way to solve the question fixing Strehler. Problem is inside Dancer2 architecture so I hope that the Dancer2 development team will do something. Waiting for it, this is what I can say if you want to use Strehler:


  • Strehler latest release is perfectly working with any Dancer2 0.14x release. So, if you don't update Dancer2 packages too much you have nothig to fear.
  • You can make Strehler works with Dancer2 0.15. You just have to ignore all the tests and run your site setting the environmental variable DANCER_CONFDIR as the directory where your config file is. It's quite simple and I know I could consider it the definitive fallback, but it's not clean and still I don't know how to use it to run the test suit, so I take this as a temporary workaround.
Well, I don't have much more to say, this is the situation at today. I hope it will change soon and I think it will, but patience, for a bit, has to be your new best friend.

Last announcement: Strehler has now a site. Click here for it. Important articles from this blog will be reported there, as a place to aggregate every communication about the development.

Sunday, 20 July 2014

Strehler 1.2.1: the hive

Strehler made the jump from 1.1.x to 1.2.x. Obviously, the first attempt had a dirty bug related to old perl versions, so the package we cleebrate now is the 1.2.1.

Strehler 1.2.1 is about Strehler frontend. No real front-end will be ever developed in the Strehler project, Strehler will never become a Wordpress or a Joomla! (but a CMS like them could be built on top of it). Otherwise, 1.1.x system is too limited, because it gives you no way to access contents you created. Yes, you can write a site that do that, but there's nothing out-of-the-box.

Most trendy way to serve contents in our days is through APIs, preferably APIs that some clever JS library like AngularJS can manage. So I added to the projct a package, Strehler::API, that, using the same logic of the admin views, generate paths to return Strehler contents in JSON(p) format.

Here below, the rules I found on internet about APIs that I used developing Strehler's (just a reminder for myself):

  • Return format is JSON. It's the most friendly for javascript and open systems. Other formats will probably follow in further development.
  • Along with JSON you can ask data in JSONp format in any situation, just adding a callback parameter. This is important when working with cross-domain platforms and... it's so easy to do that not implementing it would be just cruel.
  • JSON response content-type is 'application/json', JSONp response content-type is 'application/javascript' (don't laugh, there're many questions on Stackoverflow about this).
  • API path contains a reference to API version, so is /api/v1/... I can't imagine, now, a reason API version can change but it's always better to expect the unexpected.
  • Error codes are returned with a JSON content with the error message. In my opinion is right that error "pages" are JSON too, because whatever is calling your API, you can assume it's not a human being using a browser. Giving him back a kitten with a sorry face on 404 will be probably not easly understood by IT. (probably this feature should be improved a little, considering 1.2.1 version of the package)
  • Singular and no ending slash => an element, Plural and ending slash => a list. "Ending slash" rule is not written anywhere, it's just how I like things. I think it works well.

Monday, 2 June 2014

1.1.10 is da boss + something about AJAX

It's impossible to be sure about something like this, but I think I can consider Strehler 1.1.10 version as the first actual mature version of the product.

When I released on CPAN 1.1.0 I didn't consider it mature because I knew that a lot of features were implemented in the wrong way and many tools were hard to be used by a developer. There were too much cut and past, too much hocus pocus, too complex documentation to read.

Now, in my opinion, a developer can implement his site in a very quick way, understanding what he's doing and with the right level of trust in what I did and in what I will do (for example: update my code).

So, this time i want to make a toast bigger than the ones about previous releases.

Closing the last little bugs about Strehler I found something very interesting about  Dancer2::Plugin::AJAX that I want to share with you.

Dancer2 AJAX plugin is a little piece of code that wrap few interesting features you like to have where you serve an AJAX request.
More than this: it's really easy to use, you should never understimate that.

The strange thing about the plugin is that answer content type default is XML... In my opinion this is a little weird because when I think about AJAX I usually think about Javascript interaction where JSON is easier to use.

You can just configure the plugin to give you back a different content type, but when we modify global configuration I don't completely understand, I become a little paranoid. So my decision for my routes was to force the right content-type directly in the function.

Wednesday, 21 May 2014

Strehler 1.1.9 released

Released but not perfect. There're little problems about documentation and I probably found a little error in strehler script, layout function. Well, as usual...

I'm not sure I can find a way to test Strehler script but I should, at least to check if it gives an error in standard situations. The script, in my opinion, is a very sensitive part of the package. Strehler script go to war on the open ground of user's file system, it can find strange things and fight insidious enemies, it deserves attention. For example, I'm not sure how it works under Windows...

Another point in my TO-DO list is find a way to see how CPAN page will be rendered, after package upload, just to avoid little glitches in documentation as I'm experimenting now.

Well, stop with the bad things, a Strehler release is always something to celebrate, 1.1.9 bring order in FormFu elements and configuration and we love it for that!

Sunday, 18 May 2014

HTML::FormFu Beastmaster

I'm not a great fan of HTML::FormFu package.
Let me explain: HTML..FormFu does a lot of dirty job and give you an easy way to write down forms with a lot of business logic, but when you try to open is source code to do some customization it's quite a labyrinth with too much trolls and few indications about the right road.
In my opinion the module could be ten times more powerful giving an easy way to hack elements and modify them for new purposes.

Writing down Strehler interface I obviously had to manage a lot of forms. I wrote many of them following Strehler business logic to offer easy ways for javascript to work with them, this logic is something built on top on HTML::FormFu elements.

The category selector, probably the most complex widget I had to use, in forms configuration files is something like this:

    - type: Select
      id: category_selector
      name: category
      label: Category
      constraints:
        type: Required
        message: 'Category needed'
    - type: Select
      name: subcategory
      label: Sub-category
      id: subcat
Problem is that Strehler should give other developers the opportunity to implement their own entities and forms managing them. These forms could contain my category selector and I can't ask people to copy and paste all this code in their YML files. It's really clumsy and what if I change this structure? I should call them one by one and ask to change their files.

TIdy implementation wants that, when you need a category selector, you just add in your form configuration:

- type: "+Strehler::FormFu::Element::Category"

An ad hoc HTML::FormFu element.

There's not a real path to implement something like that, best way I found is to hack a HTML::FormFu::Element::Block nailing in it a fixed configuration with the elements of my category selector. The result is here.

You can do a lot of thngs exploiting the after BUILD of the HTML::FormFu::Element sub-classes, but you'll be always limited to the possibilities given by the class and its methods and, for example, you'll not have any chance to add custom configuration entries. So this pattern can be useful when you just want to make a package of some existing configurations, but nothing more.

Strehler::FormFu::Element::EntitySelect is something a bit more smart, as you can see here, but it's still an hack on Select I did after giving up on creating a FormFu::Element completely by myself.

Working on that, I drew a class diagram of HTML::FormFu (still 0.9 version), doing a bit of reverse engeneering on it. Here it is, as a gift from me.