The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Plack::Middleware::ActiveMirror - mirror parts of your app e.g. for offline hacking

VERSION

version 0.01

SYNOPSIS

    enable_if { $_[0]->{PATH_INFO} =~ m{^/-/} }
        ActiveMirror => (
            cache => CHI->new(
                driver    => 'RawMemory',
                datastore => {},
            ),
        );

    mount '/-/' => 'Plack::App::Proxy' => (
        remote  => 'http://rest.example.com',
        backend => 'LWP',
    );

DESCRIPTION

Hi, CPAN. My name is Shawn. I have a connectivity problem.

We have beautifully-designed Web Services (implemented by handsome fellows!) for our $client project, but we don't always have connectivity to them. I like to hack from cafés with crappy internet, which means lots of pain just to load a page since each page has to make multiple requests to our web services.

So I got to thinking, why not cache the web services responses? As long as the responses form a coherent, reasonably current snapshot, it should work fine. Sure, I can't expect to do everything my app supports just with these cached responses, but at least my JavaScript loads, and that lets me limp along well enough to continue generating billable hours. It's also fast as hell.

I tried using off-the-shelf tools first, like the wonderful Charles Proxy (http://www.charlesproxy.com/) and other Plack middleware, but none of them quite met my needs. They can mirror sets of paths just fine, but once you add query parameters into the mix, things start to go south. I needed a bit more control in what was cached, and how.

I also wanted to make sure that in the normal case of perfect connectivity, my application would behave normally: every request would proxy to my web services as usual. There would be an additional side effect of every response being put into a cache, effectively generating a partial, static mirror of your web services. Then, when connectivity goes down the drain, I can flip a switch and now ActiveMirror can serve responses out of cache on behalf of the now-inaccessible web services.

THE CACHE

Plack::Middleware::ActiveMirror relies on CHI to manage its cache. This gives you enormous flexibility in how your responses are stored: in memory, on disk, in a database, whatever CHI supports. This means that you must pass an instance of CHI to get yourself going. (The only CHI API that this module uses is ->get($key) and ->set($key, $value) so if you're sneaky you can provide any kind of cache object -- but! I explicitly do not promise that this module will continue using only those two methods with those arguments in perpetuity).

OPTIONS

cache

An initialized CHI object that will hold your cached responses. This parameter is required.

vary

An array reference containing the methods to call on Web::Request to build a cache key. By default, we vary the cache key by path, method (GET, POST, etc), and all_parameters.

always_fetch

If set to a true value, then ActiveMirror will not serve any requests out of cache. The request will always be serviced by upstream. The point of this option (instead of just removing ActiveMirror) is to build up your cache for when you lose connectivity. So, by default, set always_fetch, but then when you go offline, turn off always_fetch.

json

An instance of JSON simply kept around to avoid having to initialize it every request. You can pass in your own JSON object if you need different options for some reason; be sure to set canonical!

SEE ALSO

Plack::Middleware::Cache

AUTHOR

Shawn M Moore <code@sartak.org>

COPYRIGHT AND LICENSE

This software is copyright (c) 2012 by Infinity Interactive.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.

1 POD Error

The following errors were encountered while parsing the POD:

Around line 109:

Non-ASCII character seen before =encoding in 'cafés'. Assuming UTF-8