Author image Shawn M Moore
and 1 contributors


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


version 0.02


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

    mount '/-/' => 'Plack::App::Proxy' => (
        remote  => '',
        backend => 'LWP',


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 responses from web services? 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 ( 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 putting every response into a cache, effectively generating a partial, static mirror of my 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.


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 -- anything CHI supports.



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


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.


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.




Shawn M Moore <>


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 102:

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