-
Notifications
You must be signed in to change notification settings - Fork 41
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: lambda custom runtime #496
base: main
Are you sure you want to change the base?
Conversation
This commit resumes typelevel#276 with some modifications. The main differences between this commit and the PR above are the followings; in terms of module structure, - The original `feral-lambda` module is split into `feral-lambda-kernel` and `feral-lambda-runtime-binding` - `feral-lambda-kernel` contains types shared across runtime - `feral-lambda-runtime-binding` contains facades for AWS Java and JS runtimes - AWS Runtime API stuffs are moved under runtime.api package - correcting `Lambda-Runtime-Client-Identity` to `Lambda-Runtime-Cognito-Identity` - adding `LambdaRuntimeAPIClient` that wraps http4s `Client` - Scala Native support is not included in the commit in terms of behaviors, - the runtime runs next invocation calls and handlers in parallel - the runtime will terminate when Lambda Runtime API returns 500, which implies unrecoverable container error See also - https://docs.aws.amazon.com/lambda/latest/dg/runtimes-api.html Co-Authored-By: Scott Thomson
lambda-runtime/src/main/scala/feral/lambda/runtime/LambdaRuntime.scala
Outdated
Show resolved
Hide resolved
lambda-runtime/src/main/scala/feral/lambda/runtime/LambdaRuntime.scala
Outdated
Show resolved
Hide resolved
Are you sure that AWS Lambda actually support this? i.e. will the |
I think we should avoid running handlers in parallel... |
lambda-runtime/src/main/scala/feral/lambda/runtime/LambdaRuntime.scala
Outdated
Show resolved
Hide resolved
@@ -87,7 +119,8 @@ object Context extends ContextCompanionPlatform { | |||
logStreamName: String, | |||
identity: Option[CognitoIdentity], | |||
clientContext: Option[ClientContext], | |||
remainingTime: F[FiniteDuration] | |||
remainingTime: F[FiniteDuration], | |||
xRayTraceId: Option[String] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
propagate X-Ray-Trace-Id
to handlers via Context
to workaround the limitation that environment variables couldn't be set from JVM runtime.
client | ||
.nextInvocation() | ||
.flatMap(handleSingleRequest(client, settings, run)) | ||
.handleErrorWith { | ||
case ex @ ContainerError => ex.raiseError[F, Unit] | ||
case NonFatal(_) => ().pure | ||
case ex => ex.raiseError | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Running handlers sequentially to comply with AWS Lambda API spec and to follow other implementations.
/** | ||
* AWS Lambda Runtime API Client | ||
*/ | ||
private[runtime] trait LambdaRuntimeAPIClient[F[_]] { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
based on https://docs.aws.amazon.com/lambda/latest/dg/samples/runtime-api.zip
# This document describes the AWS Lambda Custom Runtime API using the OpenAPI 3.0 specification.
#
# A note on error reporting:
#
# Runtimes are free to define the format of errors that are reported to the runtime API, however,
# in order to integrate with other AWS services, runtimes must report all errors using the
# standard AWS Lambda error format:
#
# Content-Type: application/vnd.aws.lambda.error+json:
# {
# "errorMessage": "...",
# "errorType": "...",
# "stackTrace": [],
# }
#
# See '#/components/schemas/ErrorRequest'.
#
# Lambda's default behavior is to use Lambda-Runtime-Function-Error-Type header value to construct an error response
# when error payload is not provided or can not be read.
openapi: 3.0.0
info:
title: AWS Lambda Runtime API
description: AWS Lambda Runtime API is an HTTP API for implementing custom runtimes
version: 1.0.3
servers:
- url: /2018-06-01
paths:
/runtime/init/error:
post:
summary: >
Non-recoverable initialization error. Runtime should exit after reporting
the error. Error will be served in response to the first invoke.
parameters:
- in: header
name: Lambda-Runtime-Function-Error-Type
schema:
type: string
requestBody:
content:
'*/*':
schema: {}
responses:
'202':
description: Accepted
content:
application/json:
schema:
$ref: '#/components/schemas/StatusResponse'
'403':
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'500':
description: >
Container error. Non-recoverable state. Runtime should exit promptly.
/runtime/invocation/next:
get:
summary: >
Runtime makes this HTTP request when it is ready to receive and process a
new invoke.
responses:
'200':
description: >
This is an iterator-style blocking API call. Response contains
event JSON document, specific to the invoking service.
headers:
Lambda-Runtime-Aws-Request-Id:
description: AWS request ID associated with the request.
schema:
type: string
Lambda-Runtime-Trace-Id:
description: X-Ray tracing header.
schema:
type: string
Lambda-Runtime-Client-Context:
description: >
Information about the client application and device when invoked
through the AWS Mobile SDK.
schema:
type: string
Lambda-Runtime-Cognito-Identity:
description: >
Information about the Amazon Cognito identity provider when invoked
through the AWS Mobile SDK.
schema:
type: string
Lambda-Runtime-Deadline-Ms:
description: >
Function execution deadline counted in milliseconds since the Unix epoch.
schema:
type: string
Lambda-Runtime-Invoked-Function-Arn:
description: >
The ARN requested. This can be different in each invoke that
executes the same version.
schema:
type: string
content:
application/json:
schema:
$ref: '#/components/schemas/EventResponse'
'403':
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'500':
description: >
Container error. Non-recoverable state. Runtime should exit promptly.
/runtime/invocation/{AwsRequestId}/response:
post:
summary: Runtime makes this request in order to submit a response.
parameters:
- in: path
name: AwsRequestId
schema:
type: string
required: true
requestBody:
content:
'*/*':
schema: {}
responses:
'202':
description: Accepted
content:
application/json:
schema:
$ref: '#/components/schemas/StatusResponse'
'400':
description: Bad Request
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'403':
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'413':
description: Payload Too Large
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'500':
description: >
Container error. Non-recoverable state. Runtime should exit promptly.
/runtime/invocation/{AwsRequestId}/error:
post:
summary: >
Runtime makes this request in order to submit an error response. It can
be either a function error, or a runtime error. Error will be served in
response to the invoke.
parameters:
- in: path
name: AwsRequestId
schema:
type: string
required: true
- in: header
name: Lambda-Runtime-Function-Error-Type
schema:
type: string
requestBody:
content:
'*/*':
schema: {}
responses:
'202':
description: Accepted
content:
application/json:
schema:
$ref: '#/components/schemas/StatusResponse'
'400':
description: Bad Request
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'403':
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'500':
description: >
Container error. Non-recoverable state. Runtime should exit promptly.
components:
schemas:
StatusResponse:
type: object
properties:
status:
type: string
ErrorResponse:
type: object
properties:
errorMessage:
type: string
errorType:
type: string
ErrorRequest:
type: object
properties:
errorMessage:
type: string
errorType:
type: string
stackTrace:
type: array
items:
type: string
EventResponse:
type: object
Official Java and JS runtime do not expose trace id from handler `Context`. In order to keep both pure Scala runtime context and runtime binding context in sync, this commit modifies `ContextPlatform` constructor so that it reads trace id from environment variables.
part of #134
This commit resumes #276 with some modifications.
The main differences between this commit and the PR above are the followings;
in terms of module structure,
feral-lambda
module is split intoferal-lambda-kernel
andferal-lambda-runtime-binding
feral-lambda-kernel
contains types shared across runtimeferal-lambda-runtime-binding
contains facades for AWS Java and JS runtimesLambda-Runtime-Client-Identity
toLambda-Runtime-Cognito-Identity
LambdaRuntimeAPIClient
that wraps http4sClient
in terms of behaviors,
the runtime runs next invocation calls and handlers in paralleledit: runtime should not run handlers in parallel.See also
Co-Authored-By: Scott Thomson