1# $Id: /mirror/gungho/lib/Gungho/Component/Throttle/Provider.pm 39016 2008-01-16T16:02:45.208801Z lestrrat  $
2#
3# Copyright (c) 2007 Daisuke Maki <daisuke@endeworks.jp>
4# All rights reserved.
5
6package Gungho::Component::Throttle::Provider;
7use strict;
8use warnings;
9use base qw(Gungho::Component);
10
11__PACKAGE__->mk_classdata($_) for qw(request_count max_requests pending_requests);
12
13sub setup
14{
15    my $c = shift;
16    $c->next::method();
17    my $config = $c->config->{throttle}{provider} || {};
18    my $max = $config->{max_requests} || 10;
19    $c->pending_requests( {} );
20    $c->request_count( 0 );
21    $c->max_requests( $max );
22}
23
24sub dispatch_requests
25{
26    my ($c) = @_;
27
28    if ($c->request_count < $c->max_requests) {
29        $c->next::method();
30    } else {
31        $c->log->debug("Max request count " . $c->max_requests . " reached");
32    }
33}
34
35sub send_request
36{
37    my ($c, $request) = @_;
38
39    if ($c->next::method($request)) {
40        if (! $c->pending_requests->{ $request->id }) {
41            $c->pending_requests->{ $request->id } = $request;
42            $c->increment_request_count();
43            $c->log->debug("Incremented: " . $c->request_count);
44        }
45        $c->log->debug( $request->uri );
46    }
47}
48
49sub pushback_request
50{
51    my ($c, $request) = @_;
52
53    $c->next::method($request);
54    if (delete $c->pending_requests->{ $request->id }) {
55        $c->decrement_request_count();
56        $c->log->debug("Decremented: " . $c->request_count);
57    }
58}
59
60sub handle_response
61{
62    my ($c, $request, $response) = @_;
63
64    $c->next::method($request, $response);
65    if (delete $c->pending_requests->{ $request->id }) {
66        $c->decrement_request_count();
67        $c->log->debug("Decremented: " . $c->request_count);
68    }
69}
70
71sub increment_request_count
72{
73    my $c = shift;
74    $c->request_count( $c->request_count + 1 );
75}
76
77sub decrement_request_count
78{
79    my $c = shift;
80    $c->request_count( $c->request_count - 1 );
81}
82
831;
84
85__END__
86
87=head1 NAME
88
89Gungho::Component::Throttle::Provider - Throttle Calls To The Provider
90
91=head1 SYNOPSIS
92
93  components:
94    - Throttle::Provider
95  throttle:
96    provider:
97      max_requests: 10
98
99=head1 DESCRIPTION
100
101This module is still experimental. Use at your own peril.
102
103Often times it is more conveinient to throttle the number of times the Provider
104is invoked to fetch the next request than for the provider to keep tabs of
105how many requests it has sent so far.
106
107This component keeps track of how many URLs have gone through send_request()
108and back to handle_response(), and will prevent Gungho from calling the
109provider to fetch the next request.
110
111=head1 METHODS
112
113=head2 setup
114
115=head2 dispatch_requests
116
117Averts calling the actual C<dispatch_requests> when there are more requests
118than specified by C<max_requests> in the system.
119
120=head2 send_request
121
122=head2 handle_response
123
124=head2 increment_request_count
125
126=head2 decrement_request_count
127
128=cut