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 )