AnyEvent-SparkBot
view release on metacpan or search on metacpan
lib/AnyEvent/HTTP/Spark.pm view on Meta::CPAN
default=>1,
);
has retryTimeout=>(
isa=>Int,
is=>'ro',
default=>1,
);
has retryAfter=>(
isa=>Int,
is=>'ro',
default=>10,
);
has retries=>(
isa=>HashRef,
is=>'ro',
default=>sub { return {} },
);
=head1 NAME
AnyEvent::HTTP::Spark - Syncrnous/Asyncrnous HTTP Rest Client for Cisco Spark
=head1 SYNOPSIS
use AnyEvent::HTTP::Spark;
my $obj=new AnyEvent::HTTP::Spark(token=>$ENV{SPARK_TOKEN});
=head1 DESCRIPTION
Dual Nature Syncrnous/Asyncrnous AnyEvent friendly Spark v1 HTTP Client library.
=head1 Moo Roles Used
This class uses the following Moo Roles
HTTP::MultiGet::Role
Log::LogMethods
Data::Result::Moo
AnyEvent::SpakBot::SharedRole
=head1 OO Arguments and accessors
Required OO Arguments
token: required for spark authentication
Optional OO Arguments
logger: sets the logging object
agent: AnyEvent::HTTP::MultiGet object
api_url: https://webexapis.com/v1/
# sets the web service the requests point to
retryCount: 1, how many retries to attempt when getting a 429 error
Options set at runtime
retries: anymous hash, used to trak AnyEvent->timer objects
=cut
# This method runs after the new constructor
sub BUILD {
my ($self)=@_;
}
# this method runs before the new constructor, and can be used to change the arguments passed to the module
around BUILDARGS => sub {
my ($org,$class,@args)=@_;
return $class->$org(@args);
};
=head1 OO Web Methods and special Handlers
Each web method has a blocking and a non blocking context.
Any Method with a prefix of que_ can be called in either a blocking or a non blocking context. Most people will use the blocking interface of the client.
Non Blocking context for use with AnyEvent Loops
my $cb=sub {
my ($self,$id,$result,$request,$response)=@_;
if($result) {
print Dumper($result->get_data);
} else {
...
}
};
my $id=$self->que_listPeople($cb,$args);
$self->agent->run_next;
Blocking Context
my $result=$self->listPeople($args);
if($result) {
print Dumper($result->get_data);
} else {
die $result;
}
=head1 People
=head2 Get Me
=over 4
=item * Blocking my $result=$self->getMe()
Returns a L<Data::Result> Object, when true it contains the data, when false it contains why it failed.
=item * Non-Blocking my $id=$self->que_getMe($cb)
Example Callback
$cb=sub {
my ($self,$id,$result,$request,$response,$hashRef)=@_;
lib/AnyEvent/HTTP/Spark.pm view on Meta::CPAN
my $uri=$self->api_url.$url;
my $json=eval {to_json($data)};
return $self->new_false("Failed to convert \$data to json, error was $@") if $@;
my $request=new HTTP::Request(POST=>$uri,$self->default_headers,$json);
return $self->new_true($request);
}
=item * my $id=$self->queue_builder($cb,$method,$url,$data);
Returns the ID of the object in the request for $method.
=cut
sub queue_builder {
my ($self,$cb,$method,$url,$data)=@_;
my $result=$self->$method($url,$data);
return $self->queue_result($cb,$result) unless $result;
my $request=$result->get_data;
my $wrap;
my $count=$self->retryCount;
if($self->is_blocking) {
$wrap=sub {
my ($self,$id,$result,undef,$response)=@_;
return $cb->(@_) if $result or !($response->code==429 and $count-- >0);
my $timeout=looks_like_number($response->header('Retry-After')) ? $response->header('Retry-After') : $self->retryTimeout;
$self->log_warn("Request: $id recived a 429 response, will retry in $timeout seconds");
if($count>0) {
my $next_id=$self->queue_request($request,sub {
my ($self,undef,$result,undef,$response)=@_;
$wrap->($self,$id,$result,$request,$response);
});
$self->add_ids_for_blocking($next_id);
return $self->agent->run_next;
}
sleep $timeout;
my $code=sub {
my ($self,undef,$result,undef,$response)=@_;
$cb->($self,$id,$result,$request,$response);
};
my $next_id=$self->queue_request($request,$code);
$self->add_ids_for_blocking($next_id);
$self->agent->run_next;
};
} else {
$wrap=sub {
my ($self,$id,$result,undef,$response)=@_;
return $cb->(@_) if $result || !(($response->code==429 || $response->code==404) && $count-- >0);
my $timeout=looks_like_number($response->header('Retry-After')) ? $response->header('Retry-After') : $self->retryTimeout;
$self->log_warn("Request: $id recived a 429 response, will retry in $timeout seconds");
if($count>0) {
my $ae;
$ae=AnyEvent->timer(after=>$timeout,cb=>sub {
my $next_id=$self->queue_request($request,sub {
my ($self,undef,$result,undef,$response)=@_;
$wrap->($self,$id,$result,$request,$response);
});
$self->add_ids_for_blocking($next_id);
$self->agent->run_next;
delete $self->retries->{$ae};
undef $ae;
});
return $self->retries->{$ae}=$ae;
}
my $code=sub {
my ($self,undef,$result,undef,$response)=@_;
$cb->($self,$id,$result,$request,$response);
};
my $ae;
$ae=AnyEvent->timer(after=>$timeout,cb=>sub {
my $next_id=$self->queue_request($request,$code);
$self->add_ids_for_blocking($next_id);
$self->agent->run_next;
delete $self->retries->{$ae};
undef $ae;
});
return $self->retries->{$ae}=$ae;
};
}
return $self->queue_request($request,$wrap);
}
=item * my $id=$self->que_post_json($cb,$url,$data);
Queue's a json post and returns the id
=cut
sub que_post_json {
my ($self,$cb,$url,$data)=@_;
return $self->queue_builder($cb,'build_post_json',$url,$data);
}
=item * my $result=$self->build_put_json($url,$data);
Returns a Data::Result object; When true it contains an HTTP::Request Object For $url, the body will consist of $data converted to json. When false it contains why it failed.
=cut
sub build_put_json {
my ($self,$url,$data)=@_;
my $uri=$self->api_url.$url;
my $json=eval {to_json($data)};
return $self->new_false("Failed to convert \$data to json, error was $@") if $@;
my $request=new HTTP::Request(PUT=>$uri,$self->default_headers,$json);
return $self->new_true($request);
}
=item * my $id=$self->que_put_json($cb,$url,$data);
Queue's a json put and returns the id
=cut
sub que_put_json {
my ($self,$cb,$url,$data)=@_;
return $self->queue_builder($cb,'build_put_json',$url,$data);
}
=item * my $result=$self->build_post_form($url,$data);
Returns a Data::Result Object, when true it contains the correctly fromatted HTTP::Request Object, when false it contains why it failed.
( run in 0.982 second using v1.01-cache-2.11-cpan-754626df90b )