You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Last December I started using AWS lambda as part of the engine for my blog. Just for fun, because both Lambda and Swift on the server are pretty cool and fun to work with (eg. no need to wait for 2 years to use async/await 😉).
I'm going to be writing this as I go through the code updates, so this article will look more like a notepad than a step-by-step guide.
Let's get started
First step is to update Package.swift to pull the latest from main.
This will ensure I get the unreleased async/await updates.
Async updates
The existing code had a lambda handler with a closure-based method. The lambda uses to agents to process messages from SQS. First, each message is decoded with IssueParser, then processed with IssueProcessor.
structHandler:LambdaHandler{typealiasIn=SQS.EventtypealiasOut=String // Response type
letparser:IssueParserletprocessor:IssueProcessor
/// Business logic is initialized during lambda cold start
/// - Parameter context: Lambda initialization context, provided by AWS
init(context:Lambda.InitializationContext){
parser =IssueParser(logger: context.logger)
processor =IssueProcessor(logger: context.logger)}func handle(context:Lambda.Context, event:In, callback:@escaping(Result<Out,Error>)->Void){do{letgroup=DispatchGroup()formessagein event.records {
group.enter()letgithubContext=try parser.parseContext(json: message.body)try processor.process(githubEvent: githubContext.event){
group.leave()}}
group.wait()callback(.success(""))}catch{callback(.failure(error))}}}
IssueParser is fully synchronous, since it consists mostly in decoding a JSON payload.
IssueProcessor does an HTTP call to trigger a GitHub Action in my eneko.github.com repository. This is a perfect candidate for converting to an async/await call.
So far, I've updated my lambda function to conform to AsyncLambdaHandler, and replaced the closure-based handler method with the new async one.
New code:
@available(macOS 9999, iOS 9999, watchOS 9999, tvOS 9999,*)structHandler:AsyncLambdaHandler{typealiasIn=SQS.EventtypealiasOut=String // Response type
letparser:IssueParserletprocessor:IssueProcessor
/// Business logic is initialized during lambda cold start
/// - Parameter context: Lambda initialization context, provided by AWS
init(context:Lambda.InitializationContext){
parser =IssueParser(logger: context.logger)
processor =IssueProcessor(logger: context.logger)}func handle(event:SQS.Event, context:Lambda.Context)asyncthrows->Out{formessagein event.records {letgithubContext=try parser.parseContext(json: message.body)tryawait processor.process(githubEvent: githubContext.event)}return""}}
The handler method is much cleaner already, but I'm haven't updated IssueProcessor yet, so the above does not yet compile.
Note I'm doing updates from the top to bottom. I think this will be easier for this small lambda.
Updating network calls to async/await
For this network request, I was making a network call and checking for success, discarding any response data received from the server. Completion blocks had no parameters. Logs would be logged, but otherwise ignored.
letdataTask=URLSession.shared.dataTask(with: request){ data, _, error iniflet error = error {self.logger.error("Failed to submit workflow dispatch request to GitHub Actions")self.logger.error("\(error.localizedDescription)")}else{self.logger.debug("Submitted workflow dispatch request to GitHub Actions")}completion()}
dataTask.resume()
Updating this code to async/await makes it easier to handle those errors, and removes those completion blocks, which makes the code very linear.
do{
_ =tryawaitURLSession.shared.data(for: request, delegate:nil)
logger.debug("Submitted workflow dispatch request to GitHub Actions")}catch{
logger.error("Failed to submit workflow dispatch request to GitHub Actions")
logger.error("\(error.localizedDescription)")}
Here, I could re-throw captured errors, but for now I'll leave the logic as it was before.
Building the Lambda for Linux
The latest Swift version released as of today is 5.4.1, which requires compiler flags to enable async/await.
First, we update the docker image to FROM swift:5.4.1-amazonlinux2
Second, we add the compiler flags to Package.swift
Last December I started using AWS lambda as part of the engine for my blog. Just for fun, because both Lambda and Swift on the server are pretty cool and fun to work with (eg. no need to wait for 2 years to use async/await 😉).
I'm going to be writing this as I go through the code updates, so this article will look more like a notepad than a step-by-step guide.
Let's get started
First step is to update
Package.swift
to pull the latest frommain
.This will ensure I get the unreleased async/await updates.
Async updates
The existing code had a lambda handler with a closure-based method. The lambda uses to agents to process messages from SQS. First, each message is decoded with
IssueParser
, then processed withIssueProcessor
.IssueParser
is fully synchronous, since it consists mostly in decoding a JSON payload.IssueProcessor
does an HTTP call to trigger a GitHub Action in my eneko.github.com repository. This is a perfect candidate for converting to an async/await call.So far, I've updated my lambda function to conform to
AsyncLambdaHandler
, and replaced the closure-based handler method with the new async one.New code:
The handler method is much cleaner already, but I'm haven't updated
IssueProcessor
yet, so the above does not yet compile.Note I'm doing updates from the top to bottom. I think this will be easier for this small lambda.
Updating network calls to async/await
For this network request, I was making a network call and checking for success, discarding any response data received from the server. Completion blocks had no parameters. Logs would be logged, but otherwise ignored.
Updating this code to async/await makes it easier to handle those errors, and removes those completion blocks, which makes the code very linear.
Here, I could re-throw captured errors, but for now I'll leave the logic as it was before.
Building the Lambda for Linux
The latest Swift version released as of today is 5.4.1, which requires compiler flags to enable async/await.
First, we update the docker image to
FROM swift:5.4.1-amazonlinux2
Second, we add the compiler flags to
Package.swift
The text was updated successfully, but these errors were encountered: