AWS-Lambda
view release on metacpan or search on metacpan
lib/AWS/Lambda/Bootstrap.pm view on Meta::CPAN
use 5.026000;
use utf8;
use strict;
use warnings;
use HTTP::Tiny;
use JSON::XS qw/decode_json encode_json/;
use Try::Tiny;
use AWS::Lambda;
use AWS::Lambda::Context;
use AWS::Lambda::ResponseWriter;
use Scalar::Util qw(blessed);
use Exporter 'import';
our @EXPORT = ('bootstrap');
sub bootstrap {
my $handler = shift;
my $bootstrap = AWS::Lambda::Bootstrap->new(
handler => $handler,
);
$bootstrap->handle_events;
lib/AWS/Lambda/Bootstrap.pm view on Meta::CPAN
%args = %{$_[0]};
} else {
%args = @_;
}
my $api_version = '2018-06-01';
my $env_handler = $args{handler} // $ENV{'_HANDLER'} // die '$_HANDLER is not found';
my ($handler, $function) = split(/[.]/, $env_handler, 2);
my $runtime_api = $args{runtime_api} // $ENV{'AWS_LAMBDA_RUNTIME_API'} // die '$AWS_LAMBDA_RUNTIME_API is not found';
my $task_root = $args{task_root} // $ENV{'LAMBDA_TASK_ROOT'} // die '$LAMBDA_TASK_ROOT is not found';
my $self = bless +{
task_root => $task_root,
handler => $handler,
function_name => $function,
runtime_api => $runtime_api,
api_version => $api_version,
next_event_url => "http://${runtime_api}/${api_version}/runtime/invocation/next",
http => HTTP::Tiny->new(
# XXX: I want to disable timeout, but it seems HTTP::Tiny does not support it.
# So, I set a long timeout.
timeout => 365*24*60*60, # 365 days
lib/AWS/Lambda/Bootstrap.pm view on Meta::CPAN
$self->_init or return;
my ($payload, $context) = $self->lambda_next;
my $response = try {
local $AWS::Lambda::context = $context;
local $ENV{_X_AMZN_TRACE_ID} = $context->{trace_id};
$self->{function}->($payload, $context);
} catch {
my $err = $_;
print STDERR "$err";
$self->lambda_error($err, $context);
bless {}, 'AWS::Lambda::ErrorSentinel';
};
my $ref = ref($response);
if ($ref eq 'AWS::Lambda::ErrorSentinel') {
return;
}
if ($ref eq 'CODE') {
$self->lambda_response_streaming($response, $context);
} else {
$self->lambda_response($response, $context);
}
lib/AWS/Lambda/Bootstrap.pm view on Meta::CPAN
}
}
sub lambda_error {
my $self = shift;
my ($error, $context) = @_;
my $runtime_api = $self->{runtime_api};
my $api_version = $self->{api_version};
my $request_id = $context->aws_request_id;
my $url = "http://${runtime_api}/${api_version}/runtime/invocation/${request_id}/error";
my $type = blessed($error) // "Error";
my $resp = $self->{http}->post($url, {
content => encode_json({
errorMessage => "$error",
errorType => "$type",
}),
});
if (!$resp->{success}) {
die "failed to send error of execution: $resp->{status} $resp->{reason}";
}
}
sub lambda_init_error {
my $self = shift;
my $error = shift;
my $runtime_api = $self->{runtime_api};
my $api_version = $self->{api_version};
my $url = "http://${runtime_api}/${api_version}/runtime/init/error";
my $type = blessed($error) // "Error";
my $resp = $self->{http}->post($url, {
content => encode_json({
errorMessage => "$error",
errorType => "$type",
}),
});
if (!$resp->{success}) {
die "failed to send error of execution: $resp->{status} $resp->{reason}";
}
}
lib/AWS/Lambda/Context.pm view on Meta::CPAN
my %args;
if (@_ == 1 && ref $_[0] eq 'HASH') {
%args = %{$_[0]};
} else {
%args = @_;
}
my $deadline_ms = $args{deadline_ms} // die 'deadine_ms is required';
my $invoked_function_arn = $args{invoked_function_arn} // '';
my $aws_request_id = $args{aws_request_id} // '';
my $trace_id = $args{trace_id};
my $self = bless +{
deadline_ms => +$deadline_ms,
invoked_function_arn => $invoked_function_arn,
aws_request_id => $aws_request_id,
trace_id => $trace_id,
}, $class;
return $self;
}
sub get_remaining_time_in_millis {
lib/AWS/Lambda/PSGI.pm view on Meta::CPAN
use AWS::Lambda;
use Scalar::Util qw(reftype);
use JSON::XS qw(encode_json);
sub new {
my $proto = shift;
my $class = ref $proto || $proto;
my $self;
if (@_ == 1 && ref $_[0] eq 'HASH') {
$self = bless {%{$_[0]}}, $class;
} else {
$self = bless {@_}, $class;
}
if (!defined $self->{invoke_mode}) {
my $mode = $ENV{PERL5_LAMBDA_PSGI_INVOKE_MODE}
|| $ENV{AWS_LWA_INVOKE_MODE}; # for compatibility with https://github.com/awslabs/aws-lambda-web-adapter
$self->{invoke_mode} = uc $mode;
}
return $self;
}
lib/AWS/Lambda/ResponseWriter.pm view on Meta::CPAN
package AWS::Lambda::ResponseWriter;
use 5.026000;
use utf8;
use strict;
use warnings;
use Carp qw(croak);
use Scalar::Util qw(blessed);
use MIME::Base64 qw(encode_base64);
use HTTP::Tiny;
my %DefaultPort = (
http => 80,
https => 443,
);
sub new {
my $proto = shift;
lib/AWS/Lambda/ResponseWriter.pm view on Meta::CPAN
my %args;
if (@_ == 1 && ref $_[0] eq 'HASH') {
%args = %{$_[0]};
} else {
%args = @_;
}
my $http = $args{http} // HTTP::Tiny->new;
my $response_url = $args{response_url} // die '$LAMBDA_TASK_ROOT is not found';
my $content_type = $args{content_type} // 'application/json';
my $self = bless +{
response_url => $response_url,
http => $http,
handle => undef,
closed => 0,
}, $class;
return $self;
}
sub _request {
my ($self, $content_type) = @_;
lib/AWS/Lambda/ResponseWriter.pm view on Meta::CPAN
sub _close_with_error {
my ($self, $error) = @_;
if ($self->{closed}) {
# already closed
return;
}
$self->{closed} = 1;
my $handle = $self->{handle};
$handle->write("0\x0D\x0A");
my $type = blessed($error) // "Error";
return $handle->write_header_lines({
"lambda-runtime-function-error-type" => "$type",
"lambda-runtime-function-error-body" => encode_base64("$error", ""),
}, {
"lambda-runtime-function-error-type" => "Lambda-Runtime-Function-Error-Type",
"lambda-runtime-function-error-body" => "Lambda-Runtime-Function-Error-Body",
});
}
1;
( run in 0.611 second using v1.01-cache-2.11-cpan-de7293f3b23 )