File Coverage

blib/lib/IPC/DirQueue/IndexClient.pm
Criterion Covered Total %
statement 9 74 12.1
branch 0 32 0.0
condition 0 7 0.0
subroutine 3 11 27.2
pod 0 6 0.0
total 12 130 9.2


line stmt bran cond sub pod time code
1             =head1 NAME
2              
3             IPC::DirQueue::IndexClient - client for the indexd protocol
4              
5             =head1 DESCRIPTION
6              
7             indexd client.
8              
9             =cut
10              
11             package IPC::DirQueue::IndexClient;
12 23     23   138 use strict;
  23         36  
  23         817  
13 23     23   300 use bytes;
  23         41  
  23         136  
14              
15 23     23   73554 use IO::Socket::INET;
  23         1392441  
  23         198  
16              
17             our @ISA = ();
18              
19             our $DEBUG; # = 1;
20              
21             ###########################################################################
22              
23             sub new {
24 0     0 0   my $class = shift;
25 0           my $opts = shift;
26 0   0       $class = ref($class) || $class;
27              
28 0           my $self = $opts;
29 0   0       $self ||= { };
30              
31 0 0         if ($self->{uri} =~ m,^dq://(\S+?)(\:\d+?)?$,) {
32 0           $self->{host} = $1;
33              
34 0   0       my $p = $2 || '23458';
35 0           $p =~ s/^://;
36 0           $self->{port} = $p;
37             }
38             else {
39 0           die "unparseable URI: $self->{uri}";
40             }
41              
42 0           bless ($self, $class);
43 0           $self;
44             }
45              
46             sub dbg {
47 0 0   0 0   $DEBUG and warn "debug: ".join('', @_);
48             }
49              
50             ###########################################################################
51              
52             sub enqueue {
53 0     0 0   my ($self, $qdir, $qfile) = @_;
54 0           my $qid = $self->_get_dir_id($qdir);
55 0           $qfile =~ s,^.*queue/,,;
56 0           $self->sock_send("ENQ q=$qid|f=$qfile\r\n");
57             }
58              
59             sub sock_send {
60 0     0 0   my ($self, $str) = @_;
61              
62 0 0         if (!$self->_connect()) {
63 0           die "connect to indexd failed";
64             }
65              
66 0 0         $DEBUG and dbg "--> ".$str;
67 0 0         if (!$self->{socket}->print($str)) {
68 0           die "print to indexd failed";
69             }
70              
71 0           my $rstr = $self->{socket}->getline();
72 0 0         $DEBUG and dbg "<-- ".$rstr;
73              
74 0 0         if ($rstr =~ /(2\d\d) /) {
    0          
75 0           return $1;
76             }
77             elsif ($rstr =~ /(2\d\d)-/) {
78 0           return -($1);
79             }
80             else {
81 0           warn "indexd replied with error: $rstr";
82 0           return;
83             }
84             }
85              
86             sub dequeue {
87 0     0 0   my ($self, $qdir, $qfile) = @_;
88 0           my $qid = $self->_get_dir_id($qdir);
89 0           $qfile =~ s,^.*queue/,,;
90 0           $self->sock_send("DEQ q=$qid|f=$qfile\r\n");
91             }
92              
93             sub ls {
94 0     0 0   my ($self, $qdir) = @_;
95 0           my $qid = $self->_get_dir_id($qdir);
96              
97 0           my $resp = $self->sock_send("LS q=$qid|\r\n");
98 0 0         if ($resp != -201) {
99 0           die "need 201- response for LS";
100             }
101            
102 0           my @list = ();
103 0           while (1) {
104 0           my $str = $self->{socket}->getline();
105 0 0         $DEBUG and dbg "<-- ".$str;
106 0 0         if ($str =~ /^202-(\S+)/) {
    0          
107              
108 0           my $withqid = $1;
109 0 0         $withqid =~ s,^q=\Q$qid\E\|f=,, or warn "$withqid sub failed";
110 0           push (@list, $withqid);
111             }
112             elsif ($str =~ /^200 /) {
113 0           last;
114             }
115             else {
116 0           die "bad response from indexd on ls: $str";
117             }
118             }
119              
120 0           return @list;
121             }
122              
123             ###########################################################################
124              
125             sub _get_dir_id {
126 0     0     my ($self, $qdir) = @_;
127              
128             # chop off the "queue" part
129             # t/log/qdir/queue -> t/log/qdir
130 0           $qdir =~ s,([^/]+)/+queue/*$,$1,;
131              
132             # the ID string is: "dirname/inode"
133             # where dirname is the final part of the path, inode is the inode
134             # number of that dir.
135              
136 0           my @s = stat $qdir;
137 0 0         if (!@s) {
138 0           die "stat $qdir failed";
139             }
140              
141 0           return "$1/$s[1]";
142             }
143              
144             sub _connect {
145 0     0     my ($self) = @_;
146              
147 0 0         return 1 if ($self->{socket});
148              
149 0           my $sock = IO::Socket::INET->new (
150             PeerAddr => $self->{host},
151             PeerPort => $self->{port},
152             Proto => "tcp",
153             );
154              
155 0 0         if (!$sock) {
156 0           warn "connect failed to '$self->{host}':$self->{port}: $!";
157 0           return;
158             }
159              
160 0           $self->{socket} = $sock;
161 0           return 1;
162             }
163              
164             1;