Mojo-UserAgent-Cached
view release on metacpan or search on metacpan
lib/Mojo/UserAgent/Cached.pm view on Meta::CPAN
expires_on_backend => $ENV{MUAC_CACHE_EXPIRES_ON_BACKEND} // 1,
max_key_length => 140,
%{ shift->cache_opts || {} },
)
};
has 'cache_opts' => sub { {} };
has 'cache_url_opts' => sub { {} };
has 'key_generator' => sub { \&key_generator_cb; };
has 'logger' => sub { Mojo::Log->new() };
has 'access_log' => sub { $ENV{MUAC_ACCESS_LOG} || '' };
has 'use_expired_cached_content' => sub { $ENV{MUAC_USE_EXPIRED_CACHED_CONTENT} // 1 };
has 'accepted_error_codes' => sub { $ENV{MUAC_ACCEPTED_ERROR_CODES} || '' };
has 'sorted_queries' => 1;
has 'created_stacktrace' => '';
sub new {
my ($class, %opts) = @_;
my %mojo_agent_config = map { $_ => $opts{$_} } grep { exists $opts{$_} } qw/
ca
cert
connect_timeout
cookie_jar
inactivity_timeout
insecure
ioloop
key
local_address
max_connections
max_redirects
max_response_size
proxy
request_timeout
server
transactor
/;
my $ua = $class->SUPER::new(%mojo_agent_config);
# Populate attributes
map { $ua->$_( $opts{$_} ) } grep { exists $opts{$_} } qw/
local_dir
always_return_file
cache_opts
cache_agent
cache_url_opts
logger
access_log
use_expired_cached_content
accepted_error_codes
sorted_queries
/;
$ua->created_stacktrace($ua->_get_stacktrace);
return bless($ua, $class);
}
sub invalidate {
my ($self, $key) = @_;
if ($self->is_cacheable($key)) {
$self->logger->debug("Invalidating cache for '$key'");
return $self->cache_agent->remove($key);
}
return;
}
sub expire {
my ($self, $key) = @_;
if ($self->is_cacheable($key)) {
$self->logger->debug("Expiring cache for '$key'");
return $self->cache_agent->expire($key);
}
return;
}
sub build_tx {
my ($self, $method, $url, @more) = @_;
$url = ($self->always_return_file || $url);
if ($url !~ m{^(/|[^/]+:)}) {
if ($self->local_dir) {
$url = 'file://' . File::Spec->catfile($self->local_dir, "$url");
} elsif ($self->always_return_file) {
$url = 'file://' . "$url";
} elsif ($url !~ m{^(/|[^/]+:)}) {
$url = 'file://' . Cwd::realpath("$url");
}
}
$self->transactor->tx($method, $url, @more);
}
sub start {
my ($self, $tx, $cb) = @_;
my $url = $tx->req->url->to_unsafe_string;
my $method = $tx->req->method;
my $headers = $tx->req->headers->to_hash(1);
my $content = $tx->req->content->asset->slurp;
delete $headers->{'User-Agent'};
delete $headers->{'Accept-Encoding'};
my @opts = (($method eq 'GET' ? () : $method), (keys %{ $headers || {} } ? $headers : ()), $content || ());
my $key = $self->generate_key($url, @opts);
my $start_time = time;
# Fork-safety
$self->_cleanup->server->restart if $self->{pid} && $self->{pid} ne $$;
$self->{pid} //= $$;
# We wrap the incoming callback in our own callback to be able to cache the response
my $wrapper_cb = $cb ? sub {
my ($ua, $tx) = @_;
$cb->($ua, $ua->_post_process_get($tx, $start_time, $key, @opts));
lib/Mojo/UserAgent/Cached.pm view on Meta::CPAN
# Example:
# Returning fetched 'https://graph.facebook.com?ids=http%3A%2F%2Fexample.com%2Flivet%2F20...-lommebok&access_token=1234' => 200 for A.C.Facebook:133,185,183,A.M.F.ArticleList:19,9,A.M.Selector:47,responsive/modules/most-shared.html.tt:15,15,13,temp...
Format:
Returning <cache-status> '<URL>' => 'HTTP code' for <request_stacktrace> (<created_stacktrace>)
cache-status: (cached|fetched|cached+expired)
URL: the URL requested, shortened when it is really long
request_stacktrace: Simplified stacktrace with leading module names shortened, also includes TT stacktrace support. Line numbers in the same module are grouped (order kept of course).
created_stacktrace: Stack trace for creation of UA object, useful to see what options went in, and which object is used. Same format as normal stacktrace, but skips common parts.
Example:
created_stacktrace: A.C.Facebook:68,E.C.Sandbox_874:7,A.C.Facebook:133,<common part replaced>,main:14
stacktrace: A.C.Facebook:133,< common part: 185,183,A.M.F.ArticleList:19,9,A.M.Selector:47,responsive/modules/most-shared.html.tt:15,15,13,templates/inc/macros.tt:125,138,templates/responsive/frontpage.html.tt:10,10,16,Template:66,A.G.C.Article:3...
=head2 access_log
A file that will get logs of every request, the format is a hybrid of Apache combined log, including time spent for the request.
If provided the file will be written to. Defaults to C<$ENV{MUAC_ACCESS_LOG} || ''> which means no log will be written.
=head2 use_expired_cached_content
Indicates that we will send expired, cached content back. This means that if a request fails, and the cache has expired, you
will get back the last successful content. Defaults to C<$ENV{MUAC_EXPIRED_CONTENT} // 1>
=head2 accepted_error_codes
A list of error codes that should not be considered as errors. For instance this means that the client will not look for expired
cached content for requests that result in this response. Defaults to C<$ENV{MUAC_ACCEPTED_ERROR_CODES} || ''>
=head2 sorted_queries
Setting this to a true value will sort query parameters in the resulting URL. This means that requests will be identical if the key/value pairs
are the same. This helps when URLs have been built up using hashes that may have random orders.
=head1 OVERRIDEN ATTRIBUTES
In addition L<Mojo::UserAgent::Cached> overrides the following L<Mojo::UserAgent> attributes.
=head2 connect_timeout
Defaults to C<$ENV{MOJO_CONNECT_TIMEOUT} // 2>
=head2 inactivity_timeout
Defaults to C<$ENV{MOJO_INACTIVITY_TIMEOUT} // 5>
=head2 max_redirects
Defaults to C<$ENV{MOJO_MAX_REDIRECTS} // 4>
=head2 request_timeout
Defaults to C<$ENV{MOJO_REQUEST_TIMEOUT} // 10>
=head1 METHODS
L<Mojo::UserAgent::Cached> inherits all methods from L<Mojo::UserAgent> and
implements the following new ones.
=head2 invalidate
$ua->invalidate($key);
Deletes the cache of the given $key.
=head2 expire
$ua->expire($key);
Set the cache of the given $key as expired.
=head2 set
my $tx = $ua->build_tx(GET => "http://localhost:$port", ...);
$tx = $ua->start($tx);
my $cache_key = $ua->generate_key("http://localhost:$port", ...);
$ua->set($cache_key, $tx);
Set allows setting data directly for a given URL
=head2 generate_key(@params)
Returns a key to be used for the cache agent. It accepts the same parameters
that a normal ->get() request does.
=head2 validate_key
my $status = $ua4->validate_key('http://example.com');
Fast validates if key is valid in cache without doing fetch.
Return 1 if true.
=head2 sort_query($url)
Returns a string with the URL passed, with sorted query parameters suitable for cache lookup
=head1 OVERRIDEN METHODS
=head2 new
my $ua = Mojo::UserAgent::Cached->new( request_timeout => 1, ... );
Accepts the attributes listed above and all attributes from L<Mojo::UserAgent>.
Stores its own attributes and passes on the relevant ones when creating a
parent L<Mojo::UserAgent> object that it inherits from. Returns a L<Mojo::UserAgent::Cached> object
=head2 get(@params)
my $tx = $ua->get('http://example.com');
Accepts the same arguments and returns the same as L<Mojo::UserAgent>.
It will try to return a cached version of the $url, adhering to the set or default attributes.
In addition if a relative file path is given, it tries to return the file appended to
the attribute C<local_dir>. In this case a fake L<Mojo::Transaction::HTTP> object is returned,
populated with a L<Mojo::Message::Request> with method and url, and a L<Mojo::Message::Response>
with headers, code and body set.
=head1 ENVIRONMENT VARIABLES
C<$ENV{MUAC_CLIENT_WRITE_LOCAL_FILE_RES_DIR}> can be set to a directory to store a request in:
# Re-usable local file with headers and metadata ends up at 't/data/dir/lol/foo.html?bar=1'
$ENV{MUAC_CLIENT_WRITE_LOCAL_FILE_RES_DIR}='t/data/dir';
Mojo::UserAgent::Cached->new->get("http://foo.com/lol/foo.html?bar=1");
=head1 SEE ALSO
L<Mojo::UserAgent>, L<Mojolicious>, L<Mojolicious::Guides>, L<http://mojolicio.us>.
=head1 COPYRIGHT
Nicolas Mendoza (2015-), ABC Startsiden (2015)
=head1 LICENSE
Same as Perl licence as per agreement with ABC Startsiden on 2015-06-02
=cut
( run in 0.642 second using v1.01-cache-2.11-cpan-2398b32b56e )