Creating Swift Binaries for OpenWhisk

Swift sources files are compiled by the platform before processing requests.

This compilation process adds a delay on the invocation time for “cold” runtimes. If the action has not been invoked for a while, the system is under heavy load or multiple invocations are received in parallel, a new runtime will need to be initialised.

Pre-compiled binaries can be deployed to remove this delay. Binaries must be compiled for the correct platform architecture and support execution through the OpenWhisk runtime.

There is now a Swift package to make the process of building pre-compiled binaries much easier.

Let’s have a look at how this works…

Swift Packages

Swift introduced a package manager in Swift 3.0. The package manager integrates with the build system to “automate the process of downloading, compiling, and linking dependencies”.

OpenWhiskAction Package

It bundles the Swift source files used to implement the runtime handler for OpenWhisk as a library. Using this package means developers do not have to manually import those source files into their projects.

usage

This package exposes a public function (OpenWhiskAction ) that should be called with a function reference (([String: Any]) -> [String: Any])) as a named parameter (main). The callback will be executed with the invocation parameters. Returned values will be serialised as the invocation response.

Swift’s build process will produce an executable if the package contains a main.swift file. That file will be compiled as the package binary.

compiling with docker

OpenWhisk Swift actions use a custom Docker image as the runtime environment. Compiling application binaries from this image will ensure it is compatible with the platform runtime.

This command will run the swift build command within a container from this image. The host filesystem is mounted into the container at /swift-package. Binaries and other build artifacts will be available in ./.build/release/ after the command has executed.

deploying to openwhisk

OpenWhisk actions can be created from a zip file containing action artifacts. The zip file will be expanded prior to execution. In the Swift environment, the Swift binary executed by the platform should be at ./.build/release/Action.

If an action is deployed from a zip file which contains this file, the runtime will execute this binary rather than compiling a new binary from source code within the zip file.

This configuration file describes two actions (hello and welcome) using the swift runtime. The handler property for those actions refers to a binary, produced by the build process, rather than source file.

compile during deployment

Before using serverless deploy command to create our application, we need to compile binaries for the OpenWhisk runtime.

Manually running the Swift build command before each deployment is cumbersome and error-prone.

Let’s automate this process…

Using NPM’s scripts feature, the project exports a new command npm run-script compile which triggers the build process using the OpenWhisk Docker runtime for Swift.

The serverless-plugin-scriptsplugin provides a mechanism for running shell commands when framework commands are executed. Using this plugin we can use the package:initialize event to execute the npm run-script compile command.

custom: scripts: hooks: 'package:initialize': npm run-script compile

The package:initialize event is fired when the serverless deploy command executes.

Swift binaries will be compiled prior to deployment without any manual steps from the developer.

Swift binaries for OpenWhisk must be compiled for the correct architecture and support execution through the platform runtime. Previous instruction for producing these binaries involved numerous manual and error-prone steps.

This process has now been improved through a new Swift package which wraps the runtime handler source files. Adding this dependency into the package manifest file means the downloading, compiling and linking of these source files will be handled by the Swift package manager.