File Coverage

blib/lib/App/Memcached/Roaster.pm
Criterion Covered Total %
statement 32 75 42.6
branch 0 18 0.0
condition 0 14 0.0
subroutine 11 16 68.7
pod 0 4 0.0
total 43 127 33.8


line stmt bran cond sub pod time code
1             package App::Memcached::Roaster;
2              
3 1     1   1097 use strict;
  1         2  
  1         38  
4 1     1   6 use warnings;
  1         1  
  1         48  
5 1     1   54 use 5.010_001;
  1         4  
6             use Class::Accessor::Lite (
7 1         6 ro => [qw/ds/],
8 1     1   548 );
  1         1018  
9              
10 1     1   56 use Carp;
  1         1  
  1         63  
11 1     1   668 use Cache::Memcached::Fast;
  1         4662  
  1         35  
12 1     1   713 use Getopt::Long qw(:config posix_default no_ignore_case no_ignore_case_always);
  1         8486  
  1         5  
13 1     1   209 use List::Util qw(first);
  1         1  
  1         81  
14 1     1   546 use POSIX qw(strftime);
  1         5160  
  1         4  
15 1     1   1368 use Time::HiRes;
  1         1044  
  1         3  
16              
17 1     1   589 use version; our $VERSION = 'v0.2.1';
  1         1965  
  1         4  
18              
19             my $DEFAULT_NAMESPACE = 'memcached-roaster:';
20             my $DEFAULT_PORT = 11211;
21             my $DEFAULT_ADDR = '127.0.0.1:' . $DEFAULT_PORT;
22             my $DEFAULT_MAX_BYTES = 1_000_000;
23             my $DEFAULT_DATA_NUM = 100;
24             my $INTERVAL = 100;
25              
26             sub new {
27 0     0 0   my $class = shift;
28 0           my %params = @_;
29              
30 0   0       my $addr = $params{addr} // $DEFAULT_ADDR;
31 0 0         my $ds = Cache::Memcached::Fast->new(+{
32             servers => [$addr],
33             namespace => $DEFAULT_NAMESPACE,
34             connect_timeout => 3,
35             }) or confess "Can't connect to $addr !";
36 0 0         unless ($ds->server_versions->{$addr}) {
37 0           confess "Can't get memcached versions! server = $addr";
38             }
39 0           $params{ds} = $ds;
40              
41 0           bless \%params, $class;
42             }
43              
44             sub parse_args {
45 0     0 0   my $class = shift;
46 0           my @args = @_;
47              
48 0 0         Getopt::Long::GetOptionsFromArray(
49             \@args, \my %opts, 'addr|a=s', 'num|n=s',
50             'max-size|S=s', 'debug|d', 'help|h', 'man',
51             ) or return +{ help => 1 };
52 0 0         warn "Unevaluated args remain: @args" if (@args);
53              
54 0 0 0       if ($opts{'max-size'} && ($opts{'max-size'} =~ m/^(\d+)[kK]$/)) {
55 0           $opts{'max-size'} = $1 * 1000;
56             }
57              
58 0           return \%opts;
59             }
60              
61             sub run {
62 0     0 0   my $self = shift;
63 0           put("[start] random-generate");
64              
65             my @data = (+{
66             max_size => $self->{'max-size'} || $DEFAULT_MAX_BYTES,
67 0   0       num => $self->{num} || $DEFAULT_DATA_NUM,
      0        
68             });
69              
70 0           my $i = 0;
71 0           for my $data (@data) {
72 0           $i++;
73 0           my $pos = 0;
74 0           local $| = 1; # disable output buffering
75 0           print "{$i}:[";
76 0           for my $j (1..$data->{num}) {
77 0           my $size = int( rand() * $data->{max_size} );
78 0           my $key = join(q{:}, "random-generate$i", "data$j");
79 0 0         unless ($self->ds->set($key, 'x' x $size)) {
80 0           warn "failed to set $key, $size B";
81             }
82 0 0         if ( (my $_pos = int($j*20 / $data->{num})) > $pos ) {
83 0           $pos = $_pos;
84 0           print '.';
85             }
86 0 0         Time::HiRes::sleep(0.1) if ($j % $INTERVAL == 0);
87             }
88 0           print "]\n";
89 0           put("random-generate $i ... complete.");
90             }
91              
92 0           put("[end] random-generate");
93 0           return;
94             }
95              
96             sub put {
97 0     0 0   my ($message, $level) = @_;
98 0   0       $level ||= 'info';
99 0           printf "%s [$level] $message\n", strftime('%F %T', localtime time());
100             }
101              
102             sub DESTROY {
103 0     0     my $self = shift;
104 0 0         if ($self->ds) { $self->ds->disconnect_all }
  0            
105             }
106              
107             1;
108             __END__