Skip to content
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -240,3 +240,4 @@ However, they can be missing some of the features from the `master` branch.
* [Mahla Sharifi](https://github.com/mahlashrifi) - contributed support for Java benchmarks.
* [Alexander Schlieper (ETH Zurich)](https://github.com/xSurus) - improved support for Java benchmarks.
* [Laurin Jahns (ETH Zurich)](https://github.com/userlaurin) - support for language variants.
* [Sharayu Rasal](https://github.com/Sharayu1418) - help with function URLs on AWS.
6 changes: 5 additions & 1 deletion configs/cpp.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,11 @@
"name": "aws",
"aws": {
"region": "us-east-1",
"lambda-role": ""
"lambda-role": "",
"resources": {
"use-function-url": true,
"function-url-auth-type": "NONE"
}
},
"azure": {
"region": "westeurope"
Expand Down
6 changes: 5 additions & 1 deletion configs/example.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,11 @@
"name": "aws",
"aws": {
"region": "us-east-1",
"lambda-role": ""
"lambda-role": "",
"resources": {
"use-function-url": true,
"function-url-auth-type": "NONE"
}
},
"azure": {
"region": "westeurope"
Expand Down
6 changes: 5 additions & 1 deletion configs/java.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,11 @@
"name": "aws",
"aws": {
"region": "us-east-1",
"lambda-role": ""
"lambda-role": "",
"resources": {
"use-function-url": true,
"function-url-auth-type": "NONE"
}
},
"azure": {
"region": "westeurope"
Expand Down
8 changes: 6 additions & 2 deletions configs/nodejs.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,11 @@
"name": "aws",
"aws": {
"region": "us-east-1",
"lambda-role": ""
"lambda-role": "",
"resources": {
"use-function-url": true,
"function-url-auth-type": "NONE"
}
},
"azure": {
"region": "westeurope"
Expand Down Expand Up @@ -99,4 +103,4 @@
}
}
}
}
}
6 changes: 5 additions & 1 deletion configs/python.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,11 @@
"name": "aws",
"aws": {
"region": "us-east-1",
"lambda-role": ""
"lambda-role": "",
"resources": {
"use-function-url": true,
"function-url-auth-type": "NONE"
}
},
"azure": {
"region": "westeurope"
Expand Down
32 changes: 29 additions & 3 deletions docs/platforms.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,33 @@ or in the JSON input configuration:
}
```

### Lambda Function URLs vs API Gateway

SeBS supports two methods for HTTP-based function invocation on AWS Lambda:

1. **Lambda Function URLs** (default) - Direct Lambda invocations.
2. **API Gateway HTTP API** (optional) - Traditional approach using AWS API Gateway.

SeBS used API Gateway to trigger Lambda functions. However, API Gateway has a hard timeout limit of 29 seconds, which can be restrictive for long-running benchmarks. To overcome this limitation and simplify the architecture, we added support for Lambda Function URLs, which allow direct invocation of Lambda functions without the need for API Gateway. Since we do not rely on more complex API management features, function URLs are now the default version.

However, API gateway can still be used to benchmarking. The switch between both options is configured in the deployment settings:

```json
"deployment": {
"name": "aws",
"aws": {
"region": "us-east-1",
"resources": {
"use-function-url": true,
"function-url-auth-type": "NONE"
}
}
}
```

> [!WARNING]
> SeBS implements the "NONE" authentication mode for function URLs, making Lambda functions publicly accessible without any authentication.

## Azure Functions

Azure provides a free tier for 12 months.
Expand Down Expand Up @@ -270,9 +297,8 @@ See the documentation on the
and [OpenWhisk configuration](https://github.com/apache/openwhisk-deploy-kube/blob/master/docs/private-docker-registry.md)
for details.

**Warning**: this feature is experimental and has not been tested extensively.
At the moment, it cannot be used on a `kind` cluster due to issues with
Docker authorization on invoker nodes. [See the OpenWhisk issue for details](https://github.com/apache/openwhisk-deploy-kube/issues/721).
> [!WARNING]
> This feature is experimental and has not been tested extensively. At the moment, it cannot be used on a `kind` cluster due to issues with Docker authorization on invoker nodes. [See the OpenWhisk issue for details](https://github.com/apache/openwhisk-deploy-kube/issues/721).

### Code Deployment

Expand Down
73 changes: 51 additions & 22 deletions sebs/aws/aws.py
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,13 @@ def delete_function(self, func_name: str) -> None:
except Exception:
self.logging.error("Function {} does not exist!".format(func_name))

def delete_function_url(self, func_name: str) -> bool:
Comment thread
Sharayu1418 marked this conversation as resolved.
Outdated
"""
Delete the Function URL associated with a Lambda function.
Returns True if deleted successfully, False if it didn't exist.
"""
return self.config.resources.delete_function_url(func_name, self.session)
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated

@staticmethod
def parse_aws_report(
log: str, requests: Union[ExecutionResult, Dict[str, ExecutionResult]]
Expand Down Expand Up @@ -692,7 +699,7 @@ def parse_aws_report(
def cleanup_resources(self, dry_run: bool = False) -> dict:
"""Delete allocated resources on AWS.
Currently it deletes the following resources:
* Lambda functions and its HTTP API triggers.
* Lambda functions and its HTTP API/Function URL triggers.
* CloudWatch log groups of the functions.
* DynamoDB tables created for the benchmark.
* S3 buckets and their content created for the benchmark.
Expand Down Expand Up @@ -720,6 +727,10 @@ def cleanup_resources(self, dry_run: bool = False) -> dict:
self.session, self.cache_client, dry_run
)

result["Function URLs"] = self.config.resources.cleanup_function_urls(
self.session, self.cache_client, dry_run
)

result["CloudWatch log groups"] = self.config.resources.cleanup_cloudwatch_logs(
list(functions.keys()), self.session, dry_run
)
Expand Down Expand Up @@ -858,7 +869,7 @@ def download_metrics(
f"out of {results_count} invocations"
)

def create_trigger(self, func: Function, trigger_type: Trigger.TriggerType) -> Trigger:
def create_trigger(self, function: Function, trigger_type: Trigger.TriggerType) -> Trigger:
"""Create a trigger for the specified function.

Creates and configures a trigger based on the specified type. Currently
Expand All @@ -874,32 +885,50 @@ def create_trigger(self, func: Function, trigger_type: Trigger.TriggerType) -> T
Raises:
RuntimeError: If trigger type is not supported
"""
from sebs.aws.triggers import HTTPTrigger
from sebs.aws.triggers import HTTPTrigger, HTTPTriggerImplementation

function = cast(LambdaFunction, func)
function = cast(LambdaFunction, function)

trigger: Trigger
if trigger_type == Trigger.TriggerType.HTTP:
api_name = "{}-http-api".format(function.name)
http_api = self.config.resources.http_api(api_name, function, self.session)
# https://aws.amazon.com/blogs/compute/announcing-http-apis-for-amazon-api-gateway/
# but this is wrong - source arn must be {api-arn}/*/*
self.get_lambda_client().add_permission(
FunctionName=function.name,
StatementId=str(uuid.uuid1()),
Action="lambda:InvokeFunction",
Principal="apigateway.amazonaws.com",
SourceArn=f"{http_api.arn}/*/*",
)
trigger = HTTPTrigger(http_api.endpoint, api_name)
self.logging.info(
f"Created HTTP trigger for {func.name} function. "
"Sleep 5 seconds to avoid cloud errors."
)
time.sleep(5)
if self.config.resources.use_function_url:
# Use Lambda Function URL (no 29-second timeout limit)
func_url = self.config.resources.function_url(function, self.session)
trigger = HTTPTrigger(
url=func_url.url,
implementation=HTTPTriggerImplementation.FUNCTION_URL,
function_name=func_url.function_name,
auth_type=func_url.auth_type,
)
self.logging.info(f"Created Function URL trigger for {function.name} function.")
else:
# Use API Gateway (default, for backward compatibility)
api_name = "{}-http-api".format(function.name)
http_api = self.config.resources.http_api(api_name, function, self.session)
# https://aws.amazon.com/blogs/compute/announcing-http-apis-for-amazon-api-gateway/
# but this is wrong - source arn must be {api-arn}/*/*
self.get_lambda_client().add_permission(
FunctionName=function.name,
StatementId=str(uuid.uuid1()),
Action="lambda:InvokeFunction",
Principal="apigateway.amazonaws.com",
SourceArn=f"{http_api.arn}/*/*",
)
trigger = HTTPTrigger(
url=http_api.endpoint,
implementation=HTTPTriggerImplementation.API_GATEWAY,
api_id=api_name,
)
self.logging.info(
f"Created HTTP API Gateway trigger for {function.name} function. "
"Sleep 5 seconds to avoid cloud errors."
)
time.sleep(5)

trigger.logging_handlers = self.logging_handlers
elif trigger_type == Trigger.TriggerType.LIBRARY:
# should already exist
return func.triggers(Trigger.TriggerType.LIBRARY)[0]
return function.triggers(Trigger.TriggerType.LIBRARY)[0]
else:
raise RuntimeError("Not supported!")

Expand Down
Loading