NAME

Mojo::UserAgent::Role::Cache - Role for Mojo::UserAgent that provides caching

SYNOPSIS

General

# Apply the role
my $ua_class_with_cache = Mojo::UserAgent->with_roles('+Cache');
my $ua = $ua_class_with_cache->new;

# Change the global cache driver
use CHI;
$ua_class_with_cache->cache_driver_singleton(CHI->new(driver => "Memory", datastore => {}));

# Or change the driver for the instance
$ua->cache_driver(CHI->new(driver => "Memory", datastore => {}));

# The rest is like a normal Mojo::UserAgent
my $tx = $ua->get($url)->error;

Module

package MyCoolModule;
use Mojo::Base -base;

has ua => sub {
  return $ENV{MOJO_USERAGENT_CACHE_STRATEGY}
    ? Mojo::UserAgent->with_roles('+Cache') : Mojo::UserAgent->new;
};

sub get_mojolicious_org {
  return shift->ua->get("https://mojolicious.org/");
}

Using the MOJO_USERAGENT_CACHE_STRATEGY inside the module is a very effective way to either use the global cache set up by a unit test, or run with the default Mojo::UserAgent without caching.

Test

use Mojo::Base -strict;
use Mojo::UserAgent::Role::Cache;
use MyCoolModule;
use Test::More;

# Set up the environment and change the global cache_driver before running
# the tests
$ENV{MOJO_USERAGENT_CACHE_STRATEGY} ||= "playback";
Mojo::UserAgent::Role::Cache->cache_driver_singleton->root_dir("/some/path");

# Run the tests
my $cool = MyCoolModule->new;
is $cool->get_mojolicious_org->res->code, 200, "mojolicious.org works";

done_testing;

DESCRIPTION

Mojo::UserAgent::Role::Cache is a role for the full featured non-blocking I/O HTTP and WebSocket user agent Mojo::UserAgent, that provides caching.

The "SYNOPSIS" shows how to use this in with tests, but there's nothing wrong with using it for other things as well, where you want caching.

WARNING

Mojo::UserAgent::Role::Cache is still under development, so there will be changes and there is probably bugs that needs fixing. Please report in if you find a bug or find this role interesting.

https://github.com/jhthorsen/mojo-useragent-role-cache/issues

Below is a list of known issues: (Contributions are more than welcome)

  • cache files

    Mojo::UserAgent::Role::Cache::Driver::File is very basic now. Need better directory and filename structure.

  • cache key

    The cache key is just HTTP method and URL. Need to also include a digest of the body and headers (?)

  • strategy for storing

    Should add a custom strategy for calulating the cache key and also reject storing the result at all.

ATTRIBUTES

cache_driver

$obj = $self->cache_driver;
$self = $self->cache_driver(CHI->new);

Holds an object that will get/set the HTTP messages. Default is Mojo::UserAgent::Role::Cache::Driver::File, but any backend that supports get() and set() should do.

cache_strategy

$code = $self->cache_strategy;
$self = $self->cache_strategy(sub { my $tx = shift; return "passthrough" });

Used to set up a callback to return a cache strategy. Default value is read from the MOJO_USERAGENT_CACHE_STRATEGY environment variable or "playback_or_record".

The return value from the $code can be one of:

  • passthrough

    Will disable any caching.

  • playback

    Will never send a request to the remote server, but only look for recorded messages.

  • playback_or_record

    Will return a recorded message if it exists, or fetch one from the remote server and store the response.

  • record

    Will always fetch a new response from the remote server and store the response.

METHODS

cache_driver_singleton

$obj = Mojo::UserAgent::Role::Cache->cache_driver_singleton;
Mojo::UserAgent::Role::Cache->cache_driver_singleton($obj);

Used to retrieve or set the default "cache_driver". Useful for setting up caching globally in unit tests.

AUTHOR

Jan Henning Thorsen

COPYRIGHT AND LICENSE

This program is free software, you can redistribute it and/or modify it under the terms of the Artistic License version 2.0.

SEE ALSO

Mojo::UserAgent, https://metacpan.org/pod/Mojo::UserAgent::Cached and https://metacpan.org/pod/Mojo::UserAgent::Mockable.