lambda version in ZIP; update readme; improve status code responses

This commit is contained in:
Brandon Liu
2022-07-18 23:01:00 +08:00
parent de687baf61
commit 1570ff0253
3 changed files with 35 additions and 26 deletions

View File

@@ -5,10 +5,12 @@
Upload the resulting `lambda_function.zip` using the Lambda console. Upload the resulting `lambda_function.zip` using the Lambda console.
## Restrictions
1. There is a limit of 1 MB for tiles served through Lambda@Edge. ## Configuration
2. Lambda@Edge does not support layers, environment variables, or ARM functions.
* `BUCKET`: the S3 bucket name.
* `PMTILES_PATH`
* `TILE_PATH`
## AWS Notes ## AWS Notes
@@ -17,28 +19,19 @@ Upload the resulting `lambda_function.zip` using the Lambda console.
## Test Event ## Test Event
CloudFront event:
```json
{
"Records": [
{
"cf": {
"request": {
"uri": "/my-tileset-name/0/0/0.pbf",
"method": "GET",
"headers": {}
}
}
}
]
}
```
API Gateway V2 / Lambda Function URLs: API Gateway V2 / Lambda Function URLs:
```json ```json
{ {
"rawPath": "/my-tileset-name/0/0/0.pbf" "rawPath": "/my-tileset-name/0/0/0.pbf"
} }
``` ```
### Monitoring
### Lambda@Edge
Lambda@Edge's multi-region features have little benefit when fetching data from S3 in a single region, and Lambda@Edge [doesn't support](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/edge-functions-restrictions.html) environment variables or responses over 1 MB. For globally distributed caching, use CloudFront in combination with Lambda Function URLs.

View File

@@ -1,7 +1,11 @@
import zipfile import zipfile
import subprocess
sha = subprocess.check_output(["git", "describe", "--always"]).strip()
with zipfile.ZipFile("lambda_function.zip", "w", zipfile.ZIP_DEFLATED) as z: with zipfile.ZipFile("lambda_function.zip", "w", zipfile.ZIP_DEFLATED) as z:
z.write("lambda_function.py") z.write("lambda_function.py")
z.write("../../python/pmtiles/reader.py", "pmtiles/reader.py") z.write("../../python/pmtiles/reader.py", "pmtiles/reader.py")
z.writestr("version",sha)
print(f"created lambda_function.zip") print(f"created lambda_function.zip")

View File

@@ -8,6 +8,7 @@ import re
# Exists inside all lambda functions # Exists inside all lambda functions
import boto3 import boto3
from botocore.exceptions import ClientError
# create_lambda_function.py will vendor the relevant file # create_lambda_function.py will vendor the relevant file
from pmtiles.reader import Reader from pmtiles.reader import Reader
@@ -16,7 +17,6 @@ Zxy = collections.namedtuple("Zxy", ["z", "x", "y"])
s3 = boto3.client("s3") s3 = boto3.client("s3")
# Given a 512MB lambda function, use half of the memory for the cache, # Given a 512MB lambda function, use half of the memory for the cache,
# assuming the average root/leaf/tile size is 512 KB # assuming the average root/leaf/tile size is 512 KB
@lru_cache(maxsize=500) @lru_cache(maxsize=500)
@@ -64,7 +64,7 @@ def lambda_handler(event, context):
name, tile = parse_tile_path(os.environ.get("TILE_PATH"), uri) name, tile = parse_tile_path(os.environ.get("TILE_PATH"), uri)
if not tile: if not tile:
return {"statusCode": 400, "body": "Invalid Tile URL"} return {"statusCode": 400, "body": "Invalid tile URL"}
def get_bytes(offset, length): def get_bytes(offset, length):
return get_object_bytes( return get_object_bytes(
@@ -72,10 +72,22 @@ def lambda_handler(event, context):
) )
reader = Reader(get_bytes) reader = Reader(get_bytes)
tile_data = reader.get(tile.z, tile.x, tile.y) minzoom = int(reader.header().metadata["minzoom"])
if not tile_data: maxzoom = int(reader.header().metadata["maxzoom"])
if tile.z < minzoom or tile.z > maxzoom:
return {"statusCode": 404, "body": "Tile not found"} return {"statusCode": 404, "body": "Tile not found"}
try:
tile_data = reader.get(tile.z, tile.x, tile.y)
if not tile_data:
return {"statusCode": 204}
except ClientError as e:
error_code = e.response["Error"]["Code"]
if error_code == "AccessDenied":
return {"statusCode": 404, "body": "Archive not found"}
else:
raise e
# CloudFront requires decompressed responses from lambda # CloudFront requires decompressed responses from lambda
# in order to implement the Compressed CacheOptimized policy correctly # in order to implement the Compressed CacheOptimized policy correctly
# as well as Brotli support # as well as Brotli support