Function
The cloud.Function resource represents a serverless function for performing short, stateless tasks.
Functions are typically used to run business logic in response to events, such as a file being uploaded to a bucket, a message being pushed to a queue, or a timer expiring.
When a function is invoked on a cloud provider, it is typically executed in a container/host which is provisioned on demand.
Functions may be invoked more than once, and some cloud providers may automatically retry failed invocations. For performance reasons, most cloud providers impose a timeout on functions, after which the function is automatically terminated.
Usage
A function can be invoked in two ways:
- invoke() - Executes the function with a payload and waits for the result.
- invokeAsync() - Kicks off the execution of the function with a payload and returns immediately while the function is running.
bring cloud;
bring util;
// defining a cloud.Function resource
let countWords = new cloud.Function(inflight (payload: Json?): Json => {
return "{payload?.tryAsStr()?.split(" ")?.length ?? 0}";
}) as "countWords";
let longTask = new cloud.Function(inflight () => {
util.sleep(30s);
log("done!");
});
new cloud.Function(inflight () => {
let sentence = "I am a sentence with 7 words";
// invoking cloud.Function from inflight context
let wordsCount = countWords.invoke(sentence);
log("'{sentence}' has {wordsCount ?? "0"} words");
longTask.invokeAsync("");
log("task started");
}) as "Invoke Me";
Function container reuse
Most cloud providers will opportunistically reuse the function's container in additional invocations.
It is possible to leverage this behavior to cache objects across function executions using inflight new and inflight fields.
The following example reads the bigdata.json file once and reuses it every time query() is called.
bring cloud;
let big = new cloud.Bucket();
big.addObject("bigdata.json", Json.stringify({
"my-key": "my-value"
}));
class MyDatabase {
inflight bigdata: Json;
inflight new() {
// download big data once
this.bigdata = big.getJson("bigdata.json");
}
pub inflight query(key: str): Json {
return this.bigdata.get(key);
}
}
let db = new MyDatabase();
new cloud.Function(inflight () => {
log(Json.stringify(db.query("my-key")));
});
Target-specific details
Simulator (sim)
The sim implementation of cloud.Function runs the inflight code as a JavaScript function.
By default, a maximum of 10 workers can be processing requests sent to a cloud.Function concurrently, but this number can be adjusted with the concurrency property:
bring cloud;
new cloud.Function(inflight () => {
// ... code that shouldn't run concurrently ...
}, concurrency: 1);
AWS (tf-aws and awscdk)
The AWS implementation of cloud.Function uses AWS Lambda.
Adding custom IAM permissions
To add extra IAM permissions to the function, you can use the aws.Function class as shown below.
bring aws;
bring cloud;
let f = new cloud.Function(inflight () => {
log("Hello world!");
});
if let lambdaFn = aws.Function.from(f) {
lambdaFn.addPolicyStatements(
aws.PolicyStatement {
actions: ["ses:sendEmail"],
effect: aws.Effect.ALLOW,
resources: ["*"],
},
);
}
Accessing the Lambda context
To access the AWS Lambda context object, you can use the aws.Function class as shown below.
bring aws;
bring cloud;
let f = new cloud.Function(inflight () => {
if let ctx = aws.Function.context() {
log(ctx.logGroupName); // prints the log group name
log(ctx.logStreamName); // prints the log stream name
let remainingTime = ctx.remainingTimeInMillis();
assert(remainingTime > 0);
}
});
The context() method returns nil when ran on non-AWS targets.
Adding Lambda layers
To add a Lambda layer to the function, you can use the aws.Function class as shown below.
bring aws;
bring cloud;
let f = new cloud.Function(inflight () => {
log("Hello world!");
});
if let lambdaFn = aws.Function.from(f) {
lambdaFn.addLambdaLayer("arn:aws:lambda:us-west-2:123456789012:layer:my-layer:1");
}
In some scenarios, you might want to a Lambda layer to be automatically added to all Lambda function's that use a class's inflight methods.
You can achieve this by using the onLift or onLiftType hook.
bring aws;
bring cloud;
class Datadog {
pub inflight fetchMetrics() {
// ...implementation...
}
pub onLift(host: std.IInflightHost, ops: Array<str>) {
// Note: the "ops" argument is an array of inflight methods that were used
// so you could conditionally add the layer based on the methods called
if let lambdaFn = aws.Function.from(host) {
lambdaFn.addLambdaLayer("arn:aws:lambda:us-west-2:123456789012:layer:datadog-layer:1");
}
}
}
let d = new Datadog();
let api = new cloud.Api();
api.get("/metrics", inflight () => {
d.fetchMetrics();
});
In the previous example, a Lambda function is implicitly created for handling the "/metrics" endpoint, and the datadog-layer is automatically added to it.
Azure (tf-azure)
The Azure implementation of cloud.Function uses Azure Functions.
🚧 invoke API is not supported yet (tracking issue: #1371)
GCP (tf-gcp)
🚧 Not supported yet (tracking issue: #614)
API Reference
Function
- Implements: IInflightHost
A function.
Initializers
bring cloud;
new cloud.Function(handler: IFunctionHandler, props?: FunctionProps);
| Name | Type | Description |
|---|---|---|
| | No description. |
| | No description. |
handlerRequired
- Type: IFunctionHandler
propsOptional
- Type: FunctionProps
Methods
Preflight Methods
| Name | Description |
|---|---|
| Add an environment variable to the function. |
Inflight Methods
| Name | Description |
|---|---|
| Invokes the function with a payload and waits for the result. |
| Kicks off the execution of the function with a payload and returns immediately while the function is running. |
addEnvironment
addEnvironment(name: str, value: str): void
Add an environment variable to the function.
nameRequired
- Type: str
valueRequired
- Type: str
invoke
inflight invoke(payload?: Json): Json?
Invokes the function with a payload and waits for the result.
payloadOptional
- Type: Json
payload to pass to the function.
If not defined, an empty string will be passed.
invokeAsync
inflight invokeAsync(payload?: Json): void
Kicks off the execution of the function with a payload and returns immediately while the function is running.
payloadOptional
- Type: Json
payload to pass to the function.
If not defined, an empty string will be passed.
Static Functions
| Name | Description |
|---|---|
| A hook called by the Wing compiler once for each inflight host that needs to use this type inflight. |
| Generates an asynchronous JavaScript statement which can be used to create an inflight client for a resource. |
onLiftType
bring cloud;
cloud.Function.onLiftType(host: IInflightHost, ops: MutArray<str>);
A hook called by the Wing compiler once for each inflight host that needs to use this type inflight.
The list of requested inflight methods
needed by the inflight host are given by ops.
This method is commonly used for adding permissions, environment variables, or other capabilities to the inflight host.
hostRequired
- Type: IInflightHost
opsRequired
- Type: MutArray<str>
toInflight
bring cloud;
cloud.Function.toInflight(obj: IResource);
Generates an asynchronous JavaScript statement which can be used to create an inflight client for a resource.
NOTE: This statement must be executed within an async context.
objRequired
- Type: IResource
Properties
| Name | Type | Description |
|---|---|---|
| constructs.Node | The tree node. |
| MutMap<str> | Returns the set of environment variables for this function. |
nodeRequired
node: Node;
- Type: constructs.Node
The tree node.
envRequired
env: MutMap<str>;
- Type: MutMap<str>
Returns the set of environment variables for this function.
Structs
FunctionProps
Options for Function.
Initializer
bring cloud;
let FunctionProps = cloud.FunctionProps{ ... };
Properties
| Name | Type | Description |
|---|---|---|
| num | The maximum concurrent invocations that can run at one time. |
| MutMap<str> | Environment variables to pass to the function. |
| num | Specifies the number of days that function logs will be kept. |
| num | The amount of memory to allocate to the function, in MB. |
| | The maximum amount of time the function can run. |
concurrencyOptional
concurrency: num;
- Type: num
- Default: platform specific limits (100 on the simulator)
The maximum concurrent invocations that can run at one time.
envOptional
env: MutMap<str>;
- Type: MutMap<str>
- Default: No environment variables.
Environment variables to pass to the function.
logRetentionDaysOptional
logRetentionDays: num;
- Type: num
- Default: 30
Specifies the number of days that function logs will be kept.
Setting negative value means logs will not expire.
memoryOptional
memory: num;
- Type: num
- Default: 1024
The amount of memory to allocate to the function, in MB.
timeoutOptional
timeout: duration;
- Type: duration
- Default: 1m
The maximum amount of time the function can run.
Protocols
IFunctionHandler
-
Extends: IInflight
-
Implemented By: IFunctionHandler
Inflight client: @winglang/sdk.cloud.IFunctionHandlerClient
A resource with an inflight "handle" method that can be used to create a cloud.Function.
IFunctionHandlerClient
- Implemented By: IFunctionHandlerClient
Inflight client for IFunctionHandler.
Methods
| Name | Description |
|---|---|
| Entrypoint function that will be called when the cloud function is invoked. |
handle
inflight handle(event?: Json): Json?
Entrypoint function that will be called when the cloud function is invoked.
eventOptional
- Type: Json