From 6142ac364892e0617fc87398d3e9eebde5254788 Mon Sep 17 00:00:00 2001 From: "Moritz Grosch (LittleFox)" Date: Fri, 8 Sep 2017 08:42:40 +0200 Subject: [PATCH] Added perl environment (#311) Perl runtime environment and example function. --- environments/perl/Dockerfile | 9 +++++++ environments/perl/README.md | 30 +++++++++++++++++++++++ environments/perl/server.pl | 46 ++++++++++++++++++++++++++++++++++++ examples/perl/hello.pm | 18 ++++++++++++++ 4 files changed, 103 insertions(+) create mode 100644 environments/perl/Dockerfile create mode 100644 environments/perl/README.md create mode 100755 environments/perl/server.pl create mode 100644 examples/perl/hello.pm diff --git a/environments/perl/Dockerfile b/environments/perl/Dockerfile new file mode 100644 index 00000000..12e67ce6 --- /dev/null +++ b/environments/perl/Dockerfile @@ -0,0 +1,9 @@ +FROM perl:latest + +RUN cpanm -n Twiggy Getopt::Args Dancer2 + +COPY server.pl /server.pl +WORKDIR / + +EXPOSE 8888 +ENTRYPOINT ["/server.pl"] diff --git a/environments/perl/README.md b/environments/perl/README.md new file mode 100644 index 00000000..d7704c3b --- /dev/null +++ b/environments/perl/README.md @@ -0,0 +1,30 @@ +# Fission Perl environment + +This is an environment to execute perl code. + +It is implemented using the lightweight web application framework +[Dancer2](https://metacpan.org/pod/Dancer2) and the async I/O webserver +[Twiggy](https://metacpan.org/pod/Twiggy). + +Since Twiggy is implemented with [AnyEvent](https://metacpan.org/pod/AnyEvent), +you can write async code using AnyEvent in your function. + +## Usage + +The function you upload is actually a perl package returning a coderef (see the +example). + +You can use other packages and add more subs, but only the coderef you returned +from the package is executed directly. + +Your main-function gets exactly one argument: the Dancer2 request object. You +may want to `use Dancer2` to get functions like `send_error`. + +## Example + +```perl +# hello.pm +return sub { + return 'Hello, Perl!'; +} +``` diff --git a/environments/perl/server.pl b/environments/perl/server.pl new file mode 100755 index 00000000..1145f998 --- /dev/null +++ b/environments/perl/server.pl @@ -0,0 +1,46 @@ +#!/usr/bin/env perl + +use utf8; +use strict; +use warnings; + +use Getopt::Args; +use Plack::Handler::Twiggy; + +opt codepath => ( + isa => 'Str', + default => '/userfunc/user', + comment => 'Path to the user code', +); + +opt port => ( + isa => 'Int', + default => 8888, + comment => 'Port to listen on', +); + +my $options = optargs(); + +{ + package App::Fission::Perl; + + use Dancer2; + + our $userfunc; + + post '/specialize' => sub { + if($userfunc) { + send_error('Not a generic container', 400); + } + + $userfunc = require($options->{codepath}); + return ''; + }; + + any '/' => sub { + return $userfunc ? $userfunc->(request) : send_error('Not yet specialized', 500); + }; +} + +my $handler = Plack::Handler::Twiggy->new(port => $options->{port}); +$handler->run(App::Fission::Perl->to_app); diff --git a/examples/perl/hello.pm b/examples/perl/hello.pm new file mode 100644 index 00000000..0710a26b --- /dev/null +++ b/examples/perl/hello.pm @@ -0,0 +1,18 @@ +=pod + +You return a CODEREF from the package that will be called as your function. + +The code in the server is something like this (simplified): + + my $sub = require('hello.pm'); + $sub->(request); + +As you can see, you get the L object as first argument +to your function. You can use it to retrieve params given to your function or +anything else Dancer2 offers. You can also use Dancer2 and use its DSL. + +=cut + +return sub { + return 'Hello, ' . (shift->param('name') // 'world'); +};