<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
  xmlns:content="http://purl.org/rss/1.0/modules/content/"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/"
  xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd">
  <channel>
    <title>Safe from the Losing Fight</title>
    <link>https://losingfight.com/blog/</link>
    <description>mac and ios development</description>
    <language>en</language>
    <lastBuildDate>Tue, 23 Apr 2024 07:58:37 -0400</lastBuildDate>
    <item>
      <title>Reading and writing files in Swift async/await</title>
      <link>https://losingfight.com/blog/2024/04/22/reading-and-writing-files-in-swift-asyncawait/</link>
      <description>&lt;p&gt;Because of habits ingrained in me, by default I tend to reach for synchronous, blocking APIs when reading and writing data to and from disk. This causes problems with Swift&amp;rsquo;s cooperatively scheduled Tasks. In this post, I examine the various async-safe approaches I&amp;rsquo;ve discovered to hitting disk, and end with a general approach that I ended up using.&lt;/p&gt;
&lt;h2&gt;The synchronous way&lt;/h2&gt;
&lt;p&gt;If I&amp;rsquo;m loading up data from disk to decode from JSON or decode into a UIImage, then my go to has been:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
let data = try Data(contentsOf: fileURL)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Similarly, if I&amp;rsquo;m writing said JSON or image data out to disk, I&amp;rsquo;ll use &lt;code&gt;write&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
try data.write(to: fileURL)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These are simple and easy to use. They also create problems with Swift async/await.&lt;/p&gt;
&lt;p&gt;When I look at the Swift Foundation implementation of these methods, I can see by default they do blocking I/O operations. This is a problem because &lt;code&gt;Task&lt;/code&gt;s are cooperatively scheduled over kernel threads. (I know this is probably an over-simplification, but stick with me.) If a &lt;code&gt;Task&lt;/code&gt; traps to the kernel on a blocking call (like the blocking I/O calls), the kernel doesn&amp;rsquo;t know anything about the &lt;code&gt;Task&lt;/code&gt; it only sees the system thread blocking, and therefore suspends it. This robs Swift&amp;rsquo;s async runtime from the opportunity to just suspend the &lt;code&gt;Task&lt;/code&gt; making the I/O call and pick up a different &lt;code&gt;Task&lt;/code&gt; that is available to run. i.e. this takes away one of the system threads Swift async/await can use for the duration of the blocking I/O call.&lt;/p&gt;
&lt;p&gt;So while simple, it would probably be best if I didn&amp;rsquo;t use them in the async/await world.&lt;/p&gt;
&lt;h2&gt;Option 1: side step the issue via memory mapping&lt;/h2&gt;
&lt;p&gt;If all I care about is reading in data, I can consider asking &lt;code&gt;Data&lt;/code&gt; to memory map the file. Depending on the access patterns of the end user, this might actually be the fastest way anyway. The read accesses become implicit whenever someone touches the contents of &lt;code&gt;Data&lt;/code&gt; and the kernel faults in the appropriate pages.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
let data = try Data(contentsOf: fileURL, options: .mappedIfSafe)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A caveat is not all files can be memory mapped. There&amp;rsquo;s also no automatic way to use memory mapping for writes using &lt;code&gt;Data&lt;/code&gt; APIs. While I could roll my own, I&amp;rsquo;m not sure what the benefit of that would be.&lt;/p&gt;
&lt;h2&gt;Option 2: use URLSession&lt;/h2&gt;
&lt;p&gt;The next option I discovered was leveraging &lt;code&gt;URLSession&lt;/code&gt; to do asynchronous reads from file URLs. &lt;/p&gt;
&lt;p&gt;Like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
let (data, _) = try await URLSession.shared.data(from: fileURL)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For reading the entire file in one go, this works well. Unfortunately, I couldn&amp;rsquo;t find a way to &amp;ldquo;upload&amp;rdquo; to a file URL. Probably for good reason. So this is a read-only solution.&lt;/p&gt;
&lt;p&gt;Quick aside about async &lt;code&gt;URLSession&lt;/code&gt;: &lt;a href=&quot;https://falsevictories.com/devdiary/#20241804&quot;&gt;you probably don&amp;rsquo;t want to use the &lt;code&gt;bytes&lt;/code&gt; method&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Option 3: wrap up FileHandle&lt;/h2&gt;
&lt;p&gt;This is the first solution I found that handles both asynchronous reads and writes. The basic principle is simple: create a &lt;code&gt;FileHandle&lt;/code&gt; then use the &lt;code&gt;readabilityHandler&lt;/code&gt; or &lt;code&gt;writeabilityHandler&lt;/code&gt; properties to either read data out or write data into it. For reading, I returned an &lt;code&gt;AsyncStream&amp;lt;Data&amp;gt;&lt;/code&gt; that the &lt;code&gt;readabilityHandler&lt;/code&gt; yields to.&lt;/p&gt;
&lt;p&gt;Side note: I do &lt;strong&gt;not&lt;/strong&gt; recommend using the &lt;code&gt;bytes&lt;/code&gt; property to iterate one byte at a time.&lt;/p&gt;
&lt;p&gt;I got really far with this approach and had it working. However, for files, I found it clunky. Namely:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;When reading, I had to get the size of the file first so I knew when the &lt;code&gt;readabilityHandler&lt;/code&gt; got called the last time. A lot of sample code assumes that the &lt;code&gt;availableData&lt;/code&gt; will be &lt;code&gt;isEmpty&lt;/code&gt; on the last call. However, in my testing, I found that was true for &lt;code&gt;Pipe&lt;/code&gt;s but not for files.
&lt;/li&gt;
&lt;li&gt;When writing, the call to &lt;code&gt;write&lt;/code&gt; was still synchronous. Since I was doing it inside the &lt;code&gt;writeabilityHandler&lt;/code&gt;, presumably it wouldn&amp;rsquo;t actually block but that&amp;rsquo;s not really clear.
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;After getting &lt;code&gt;FileHandle&lt;/code&gt; to work, I decided it was too clunky and went for a different approach. But it &lt;em&gt;is&lt;/em&gt; an option.&lt;/p&gt;
&lt;h2&gt;Option 4: DispatchIO&lt;/h2&gt;
&lt;p&gt;This is the approach I ended up using. DispatchIO is low-level, but its API was consistent and straight forward to wrap up. The basic principle is to use DispatchIO to get non-blocking reads/writes and then wrap those in checked continuations. That way Swift async/await knows when to suspend or resume the calling &lt;code&gt;Task&lt;/code&gt;. Below I go into detail on my implementation. As an added bonus to the async/await, this is my first go at a non-copyable type. &lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ll start with the type declarations:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
/// A phantom type used by AsyncFileStream to restrict methods to read mode
public enum ReadMode {}
/// A phantom type used by AsyncFileStream to restrict methods to write mode
public enum WriteMode {}

public struct AsyncFileStream&amp;lt;Mode&amp;gt;: ~Copyable {
    // ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The actual type of &lt;code&gt;AsyncFileStream&lt;/code&gt; is complicated by the fact that I&amp;rsquo;m trying to make invalid operations impossible for the caller. I achieve this two ways: &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;I use a phantom type called &lt;code&gt;Mode&lt;/code&gt; that can either be &lt;code&gt;ReadMode&lt;/code&gt; or &lt;code&gt;WriteMode&lt;/code&gt;. Read methods are only available when &lt;code&gt;Mode == ReadMode&lt;/code&gt; and write methods only when &lt;code&gt;Mode == WriteMode&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;I mark &lt;code&gt;AsyncFileStream&lt;/code&gt; as non-copyable with &lt;code&gt;~Copyable&lt;/code&gt;. This means there can be only one copy, preventing multiple Tasks/threads/whatever from calling it at the same time. It also means I get a nice &lt;code&gt;deinit&lt;/code&gt; method to clean up in, and I can mark my &lt;code&gt;close()&lt;/code&gt; method as &lt;code&gt;consuming&lt;/code&gt;. This means the instance can&amp;rsquo;t be used after &lt;code&gt;close()&lt;/code&gt; is called, or the &lt;em&gt;compiler&lt;/em&gt; at compile time will emit an error.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;code&gt;AsyncFileStream&lt;/code&gt; has the properties you&amp;rsquo;d probably expect if you&amp;rsquo;ve used DispatchIO before:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
/// The queue to run the operations on
private let queue: DispatchQueue
/// The unix file descriptor for the open file
private let fileDescriptor: Int32
/// The DispatchIO instance used to issue operations
private let io: DispatchIO
/// If the file is open or not; used to prevent double closes()
private var isClosed = false
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you haven&amp;rsquo;t used DispatchIO before, don&amp;rsquo;t worry, these properties will make sense when I use them.&lt;/p&gt;
&lt;p&gt;Creating an instance is actually the most involved part of this whole type, but it&amp;rsquo;s a good place to start:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
fileprivate init(url: URL, mode: Int32) throws {
    guard url.isFileURL else {
        throw AsyncFileStreamError.notFileURL
    }
    // Since we&amp;#x27;re reading/writing as a stream, keep it a serial queue
    let queue = DispatchQueue(label: &amp;quot;AsyncFileStream&amp;quot;)
    let fileDescriptor = open(url.absoluteURL.path, mode, 0o666)
    // Once we start setting properties, we can&amp;#x27;t throw. So check to see if
    //  we need to throw now, then set properties
    if fileDescriptor == -1 {
        throw AsyncFileStreamError.openError(errno)
    }
    self.queue = queue
    self.fileDescriptor = fileDescriptor
    io = DispatchIO(
        type: .stream,
        fileDescriptor: fileDescriptor,
        queue: queue,
        cleanupHandler: { [fileDescriptor] error in
            // Unfortunately, we can&amp;#x27;t seem to do anything with `error`.
            // There are no guarantees when this closure is invoked, so
            //  the safe thing would be to save the error in an actor
            //  that the AsyncFileStream holds. That would allow the caller
            //  to check for it, or the read()/write() methods to check
            //  for it as well. Howevever, having an actor as a property
            //  on a non-copyable type appears to uncover a compiler bug.

            // Since we opened the file, we need to close it
            Darwin.close(fileDescriptor)
        }
    )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;First, notice the &lt;code&gt;init&lt;/code&gt; is &lt;code&gt;fileprivate&lt;/code&gt;. I&amp;rsquo;m going to provide much more ergonomic APIs for creating an instance than knowing how to fill out &lt;code&gt;mode&lt;/code&gt; correctly. But there&amp;rsquo;s a lot of shared code, so this &lt;code&gt;init&lt;/code&gt; takes care of that. Error handling in the init of a non-copyable type is tricky. I can only throw errors up to the point that it starts setting up stored properties. Once that starts the &lt;code&gt;init&lt;/code&gt; must guarantee success (i.e. no throws after) or its a compile time error. So early on I verify I have a file URL and that the open happened successfully.&lt;/p&gt;
&lt;p&gt;Otherwise, I set up DispatchIO. I create my &lt;code&gt;DispatchQueue&lt;/code&gt; to execute the IO operations on. Since I&amp;rsquo;m going to be reading and writing as a stream, I might as well keep a serial queue. I open the file using the POSIX &lt;code&gt;open()&lt;/code&gt; API, using the passed in mode, and set the permissions to &lt;code&gt;0o666&lt;/code&gt;, which should give read/write to all. As mentioned before, I create DispatchIO as a &lt;code&gt;.stream&lt;/code&gt; since I&amp;rsquo;m going to sequentially read through the file or write it out. &lt;/p&gt;
&lt;p&gt;The &lt;code&gt;cleanupHandler&lt;/code&gt; is another tricky bit. It&amp;rsquo;s called once DispatchIO is done with our &lt;code&gt;fileDescriptor&lt;/code&gt;. e.g. after someone&amp;rsquo;s called &lt;code&gt;close()&lt;/code&gt;. Since we opened the file, we take care of closing it. I&amp;rsquo;m also given an error as a parameter to my closure; if it&amp;rsquo;s non-zero something went wrong. Unfortunately, I ran into a compiler bug (according to the compiler itself) in trying to handle it. &lt;/p&gt;
&lt;h3&gt;A slight diversion about said compiler bug&lt;/h3&gt;
&lt;p&gt;What I&amp;rsquo;d like to do to handle the &lt;code&gt;cleanupHandler&lt;/code&gt; error is to have a &lt;code&gt;private&lt;/code&gt; actor like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
final actor AsyncError {
    private(set) var error: AsyncFileStreamError?

    func setError(_ error: AsyncFileStreamError) {
        self.error = error
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I always create an instance in the &lt;code&gt;init&lt;/code&gt; and have it as a property on &lt;code&gt;AsyncFileStream&lt;/code&gt;. Inside of my &lt;code&gt;cleanupHandler&lt;/code&gt; I could set the actual error on it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
cleanupHandler: { [fileDescriptor] error in
    if error != 0 {
        Task {
            await asyncError.setError(error)
        }
    }
    // Since we opened the file, we need to close it
    Darwin.close(fileDescriptor)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Since it&amp;rsquo;s a property, the read and write methods could check it in a &lt;code&gt;guard&lt;/code&gt; statement or the caller could explicitly read it off to check for an error. Unfortunately, when I actually implement this, attempting to touch the actor instance leads to:&lt;/p&gt;
&lt;pre&gt;
Usage of a noncopyable type that compiler can't verify. This is a compiler bug. Please file a bug with a small example of the bug
&lt;/pre&gt;
&lt;p&gt;Welp.&lt;/p&gt;
&lt;p&gt;Moving on&amp;hellip;&lt;/p&gt;
&lt;h3&gt;Creating an instance&lt;/h3&gt;
&lt;p&gt;I wanted to be able to create an instance of an &lt;code&gt;AsyncFileStream&lt;/code&gt; without remembering all the various mode flags for &lt;code&gt;open()&lt;/code&gt;. Also, I added the &lt;code&gt;Mode&lt;/code&gt; phantom type, but I&amp;rsquo;d rather that be invisible to the caller. i.e. they don&amp;rsquo;t have to type out the &lt;code&gt;Mode&lt;/code&gt; explicitly somewhere. If I use a direct &lt;code&gt;init&lt;/code&gt; though, they would, as there&amp;rsquo;s no way to infer it. For those reasons, I added an extension to &lt;code&gt;URL&lt;/code&gt; to create &lt;code&gt;AsyncFileStream&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
public extension URL {
    /// Create an instance from the URL for reading only
    func openForReading() throws -&amp;gt; AsyncFileStream&amp;lt;ReadMode&amp;gt; {
        try AsyncFileStream&amp;lt;ReadMode&amp;gt;(url: self, mode: O_RDONLY)
    }

    /// Create an instance from the URL for writing. It will overwrite if the file
    /// already exists or create it if it does not exist.
    func openForWriting() throws -&amp;gt; AsyncFileStream&amp;lt;WriteMode&amp;gt; {
        try AsyncFileStream&amp;lt;WriteMode&amp;gt;(url: self, mode: O_WRONLY | O_TRUNC | O_CREAT)
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If I have a &lt;code&gt;URL&lt;/code&gt;, I just have to call &lt;code&gt;openForReading()&lt;/code&gt; or &lt;code&gt;openForWriting()&lt;/code&gt;. Does what it says on the tin.&lt;/p&gt;
&lt;h3&gt;Cleaning up safely&lt;/h3&gt;
&lt;p&gt;Next, I&amp;rsquo;ll cover the parts of the type that are available regardless of &lt;code&gt;Mode&lt;/code&gt;, namely closing the file. Because this is a non-copyable type, &lt;code&gt;close()&lt;/code&gt; gets interesting (in a good way):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
/// Close the file. Consuming method
public consuming func close() {
    isClosed = true
    io.close()
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The body is a bit boring &amp;mdash; it marks itself as closed so &lt;code&gt;deinit&lt;/code&gt; doesn&amp;rsquo;t close again, and then closes the DispatchIO object. The fact that this is marked &lt;code&gt;consuming&lt;/code&gt; is interesting though. Specifically, in that position, it means &lt;code&gt;self&lt;/code&gt; is consumed. Which means the caller can&amp;rsquo;t call any methods after it without getting a compiler error. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
let stream: AsyncFileStrea&amp;lt;ReadMode&amp;gt; // ... assume initialized
stream.close() // stream is now consumed

stream.readToEnd() // this is a compiler error!
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That&amp;rsquo;s pretty neat! I&amp;rsquo;ve prevented an illegal operation a &lt;em&gt;compile time&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;To circle back to marking &lt;code&gt;isClosed&lt;/code&gt; to &lt;code&gt;true&lt;/code&gt; so &lt;code&gt;deinit&lt;/code&gt; doesn&amp;rsquo;t try to close it. In a &lt;code&gt;consuming&lt;/code&gt; method, I could &amp;mdash; if the type is right &amp;mdash; call &lt;code&gt;discard self&lt;/code&gt;. That destroys self and means &lt;code&gt;deinit&lt;/code&gt; doesn&amp;rsquo;t get called. Unfortunately, it only works if the type only contains &amp;ldquo;trivial&amp;rdquo; types, and &lt;code&gt;AsyncFileStream&lt;/code&gt; contains non-trivial types, apparently. From what I can discern &amp;ldquo;trivial&amp;rdquo; means you can do a bit-by-bit copy on the type, no reference counting. In any case, since I can&amp;rsquo;t &lt;code&gt;discard self&lt;/code&gt;, we need to mark something so &lt;code&gt;deinit&lt;/code&gt; knows not to try to call &lt;code&gt;ios.close()&lt;/code&gt; a second time.&lt;/p&gt;
&lt;p&gt;Speaking of &lt;code&gt;deinit&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
deinit {
    // Ensure we&amp;#x27;ve closed the file if we&amp;#x27;re going out of scope
    if !isClosed {
        io.close()
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Since I&amp;rsquo;ve got a non-copyable type, I get a &lt;code&gt;deinit&lt;/code&gt;, which is just the bee&amp;rsquo;s knees. If I haven&amp;rsquo;t closed the file already, I do so now so I don&amp;rsquo;t leak anything.&lt;/p&gt;
&lt;h3&gt;Reading&lt;/h3&gt;
&lt;p&gt;If I create the type in &lt;code&gt;ReadMode&lt;/code&gt;, there are a couple of &lt;code&gt;read&lt;/code&gt; methods available.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
public extension AsyncFileStream where Mode == ReadMode {
    /// Read the entire contents of the file in one go
    func readToEnd() async throws -&amp;gt; DispatchData { ... }

    /// Read the next `length` bytes.
    func read(upToCount length: Int) async throws -&amp;gt; DispatchData { ... }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Like marking &lt;code&gt;close()&lt;/code&gt; as &lt;code&gt;consuming&lt;/code&gt;, the goal of putting the methods in a conditional extension is to prevent misuse. Unless I open &lt;code&gt;AsyncFileStream&lt;/code&gt; in &lt;code&gt;ReadMode&lt;/code&gt;, I simply can&amp;rsquo;t call any read methods at compile time because they aren&amp;rsquo;t available.&lt;/p&gt;
&lt;p&gt;As mentioned at the start of this section, the basic idea of &lt;code&gt;read&lt;/code&gt; is to wrap DispatchIO&amp;rsquo;s read in a continuation:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
/// Read the next `length` bytes.
func read(upToCount length: Int) async throws -&amp;gt; DispatchData {
    try await withCheckedThrowingContinuation { continuation in
        var readData = DispatchData.empty
        io.read(offset: 0, length: length, queue: queue) { done, data, error in
            if let data {
                readData.append(data)
            }
            guard done else {
                return // not done yet
            }
            if error != 0 {
                continuation.resume(throwing: AsyncFileStreamError.readError(error))
            } else {
                continuation.resume(returning: readData)
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is straight forward: wrap up &lt;code&gt;io.read()&lt;/code&gt; in checked throwing continuation. For my purposes I built up a single &lt;code&gt;DispatchData&lt;/code&gt; and returned it when finished. That&amp;rsquo;s because I want to use the entire contents as a single &lt;code&gt;Data&lt;/code&gt; instance. However, I could have returned an &lt;code&gt;AsyncStream&amp;lt;DispatchData&amp;gt;&lt;/code&gt; and streamed out the data as I got it in the callback. I&amp;rsquo;m also going to note DispatchIO explicitly marks the read as done with a done flag. Glaring at you, &lt;code&gt;FileHandle&lt;/code&gt;. &lt;/p&gt;
&lt;p&gt;Also note that since I&amp;rsquo;m using the stream mode of DispatchIO, so &lt;code&gt;offset&lt;/code&gt; is ignored, which is why its always &lt;code&gt;0&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Since my goal was to read the entire file at once, I added a helper method to do that:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
/// Read the entire contents of the file in one go
func readToEnd() async throws -&amp;gt; DispatchData {
    try await read(upToCount: .max)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It just calls through to the normal &lt;code&gt;read()&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;Writing&lt;/h3&gt;
&lt;p&gt;Like reading, writing is gated based on the &lt;code&gt;Mode&lt;/code&gt;. Writing also works the same as reading: I wrap up a non-blocking call with a callback in a checked throwing continuation. Ugly, but straight forward and effective (like me!):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
public extension AsyncFileStream where Mode == WriteMode {
    /// Write the data out to file async
    func write(_ data: DispatchData) async throws {
        try await withCheckedThrowingContinuation { continuation in
            io.write(
                offset: 0,
                data: data,
                queue: queue
            ) { done, _, error in
                guard done else {
                    return // not done yet
                }
                if error != 0 {
                    continuation.resume(throwing: AsyncFileStreamError.writeError(error))
                } else {
                    continuation.resume(returning: ())
                }
            }
        } as Void
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The main difference from the structure of the &lt;code&gt;read&lt;/code&gt; is I ignore the second parameter in the callback, which is the data remaining to write out.&lt;/p&gt;
&lt;h3&gt;Some Data convenience&lt;/h3&gt;
&lt;p&gt;Finally, I get back to where I started. Namely, I want convenience methods on &lt;code&gt;Data&lt;/code&gt; that read and write entire files, but asynchronously. All I do is wrap up the methods I just defined:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
public extension Data {
    /// Asynchronously read from the contents of the fileURL. This method
    /// will throw an error if it&amp;#x27;s not a file URL.
    init(asyncContentsOf url: URL) async throws {
        let stream = try url.openForReading()
        self = try await Data(stream.readToEnd())
    }

    /// Asynchronously write the contents of self into the fileURL.
    func asyncWrite(to url: URL) async throws {
        // This line makes me sad because we&amp;#x27;re copying the data. I&amp;#x27;m not
        //  currently aware of a way to not copy these bytes.
        let dispatchData = withUnsafeBytes { DispatchData(bytes: $0) }
        let stream = try url.openForWriting()
        try await stream.write(dispatchData)
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The one thing of note is in the &lt;code&gt;asyncWrite()&lt;/code&gt; method I make a copy of the bytes when I instantiate &lt;code&gt;DispatchData&lt;/code&gt;. I would &lt;em&gt;really&lt;/em&gt; like to not have to do that, but I couldn&amp;rsquo;t find a way. If &lt;em&gt;you&lt;/em&gt; know a way, please tap on the &amp;quot;Contact&amp;quot; button at the top of this page and send me an email or message me on Mastodon.&lt;/p&gt;
&lt;p&gt;And that&amp;rsquo;s it! &lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;In this post, I started with a couple of very convenient methods on &lt;code&gt;Data&lt;/code&gt; that make it easy to read or write entire files. However, I pointed out they&amp;rsquo;re synchronous, which can cause problems in Swift&amp;rsquo;s async/await world. I then walked through various async-safe ways or reading and writing files. Finally, I built out  a general solution for async file I/O by wrapping up DispatchIO in checked continuations.&lt;/p&gt;
</description>
      <category>Swift</category>
      <category>Programming</category>
      <category>Async</category>
      <pubDate>Mon, 22 Apr 2024 19:50:17 -0400</pubDate>
      <guid isPermaLink="false">https://losingfight.com/blog/?p=575</guid>
      <dc:creator>Andy</dc:creator>
      <dc:date>2024-04-22T19:50:17-04:00</dc:date>
    </item>
    <item>
      <title>Swift async/await: do you even need a queue?</title>
      <link>https://losingfight.com/blog/2024/04/14/swift-asyncawait-do-you-even-need-a-queue/</link>
      <description>&lt;p&gt;Alternative title: A concurrency limiter for Swift async/await&lt;/p&gt;
&lt;p&gt;This post is really for me and my future self to help clarify my thinking about modeling asynchronous operations in Swift async/await. But I suppose you can read along as well. &lt;/p&gt;
&lt;p&gt;In the world prior to async/await I used dispatch queues and &lt;code&gt;OperationQueue&lt;/code&gt;s to model asynchronous operations. As a result, my thinking about async naturally reverts to the hammer of execution queues. However, I&amp;rsquo;m starting to realize execution queues are sometimes not a good fit for modeling async operations in Swift async/await. In this post, I&amp;rsquo;m going to walk through an example where I found that an execution queue wasn&amp;rsquo;t what I wanted. Instead I wanted to simply limit the number of &lt;code&gt;Task&lt;/code&gt;s that could concurrently pass through a certain block of code. I&amp;rsquo;ll end with how I solved the limiter problem.&lt;/p&gt;
&lt;h2&gt;An example of my broken thinking&lt;/h2&gt;
&lt;p&gt;To return to &lt;a href=&quot;/blog/2024/04/14/modeling-condition-variables-in-swift-asyncawait/&quot;&gt;my previous post&amp;rsquo;s example&lt;/a&gt;, let&amp;rsquo;s say I&amp;rsquo;m building an image cache. Part of the caching infrastructure is to actually download the image from the network. Since I can overload the network if I try to download too many images at once, I want to limit this part to ensure only so many download operations are happening concurrently.&lt;/p&gt;
&lt;p&gt;The &amp;ldquo;classic&amp;rdquo; way to handle the limiting is to schedule the image download operation in an &lt;code&gt;OperationQueue&lt;/code&gt; and make sure it has its &lt;code&gt;maxConcurrentOperationCount&lt;/code&gt; set appropriately. Therefore, naturally, I turned to execution queues as a way to solve my concurrent downloads problem. I tried to build a Swift async/await &amp;ldquo;native&amp;rdquo; version of a concurrent execution queue. It got something that &amp;ldquo;mostly&amp;rdquo; worked, for some definition of &amp;ldquo;mostly&amp;rdquo;. And &amp;ldquo;work&amp;rdquo;. But what I couldn&amp;rsquo;t make work is a clean way to get the downloaded image back to the caller. &lt;/p&gt;
&lt;p&gt;When I run into difficulties like this, I stop and try to figure out why it&amp;rsquo;s difficult. Usually it&amp;rsquo;s because there&amp;rsquo;s a mismatch between my mental models, and I&amp;rsquo;m trying to force a square peg into a round hole.&lt;/p&gt;
&lt;p&gt;For my image cache, each fetch image operation is modeled as a &lt;code&gt;Task&lt;/code&gt;. In pseudo-code something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
Task.detached {
    if let image = await memoryCache.image(for: url) {
        return image
    }
    if let image = await diskCache.image(for: url) {
        return image
    }

    downloadQueue.run {
        // This block actually runs in Task created by the Queue
        let image = await network.downloadImage(for: url)

        // TODO: how do I get `image` back to the calling Task?
    }

    //...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Things flow well until I need to actually download the image and want to limit how many concurrent ones via the &lt;code&gt;downloadQueue&lt;/code&gt;. How do I get the &lt;code&gt;image&lt;/code&gt; back to the calling &lt;code&gt;Task&lt;/code&gt;? I mean, I guess I might figure out a way to make a callback work? That feels super janky, and possibly not safe.&lt;/p&gt;
&lt;p&gt;However, looking at this code is when I first realized a couple of things. First, I was switching execution contexts to do the download. Why? I have a perfectly good detached &lt;code&gt;Task&lt;/code&gt; already that I would prefer to be executing in. &lt;code&gt;Task&lt;/code&gt;s are supposed to be &amp;ldquo;recipes&amp;rdquo;, i.e. a list of steps to perform, which should include the actual download. So, I didn&amp;rsquo;t need the execution part of an execution queue. Second, what I actually needed it for was limiting the number of concurrent operations; that was its real purpose. &lt;/p&gt;
&lt;p&gt;Therefore, my actual problem is I need a way to limit how many concurrent &lt;code&gt;Task&lt;/code&gt;s are calling &lt;code&gt;await network.downloadImage(for: url)&lt;/code&gt; at the same time. Can I solve that problem instead?&lt;/p&gt;
&lt;h2&gt;A concurrency limiter&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;m going to solve this problem of queues with a queue. &lt;em&gt;Obviously&lt;/em&gt;. The difference is this queue won&amp;rsquo;t provide any execution. The calling &lt;code&gt;Task&lt;/code&gt; will do that.&lt;/p&gt;
&lt;p&gt;I like starting with what I&amp;rsquo;d like to have at the call site:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
Task.detached {
    if let image = await memoryCache.image(for: url) {
        return image
    }
    if let image = await diskCache.image(for: url) {
        return image
    }

    let image = downloadLimiter.run {
        // This runs on the calling task. No extra tasks!
        await network.downloadImage(for: url)
    }

    //...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The key bit is the closure is passed to &lt;code&gt;run&lt;/code&gt; is executed on the calling &lt;code&gt;Task&lt;/code&gt;. That makes returning the image back trivial. A call site like the above example would imply an interface something like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
public final class ConcurrencyLimiter {
    /// Concurrency is the maximum number of concurrent blocks to allow to run
    public init(concurrency: Int) 

    /// Execute the given block on the calling Task. It may wait first if there
    /// are already the maximum blocks running.
    public func run&amp;lt;Value&amp;gt;(_ block: @escaping () async throws -&amp;gt; Value) async throws -&amp;gt; Value
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It has an &lt;code&gt;init&lt;/code&gt; so it can know the maximum number of concurrent blocks, and then just a &lt;code&gt;run&lt;/code&gt; method that executes the passed in closure. There&amp;rsquo;s also a non-throwing variant of &lt;code&gt;run&lt;/code&gt; but it&amp;rsquo;s a simplified version of the throwing one, so it&amp;rsquo;s less interesting.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ll start on the outside and work my way inside to the details of the implementation. Here&amp;rsquo;s how I built &lt;code&gt;run&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
public func run&amp;lt;Value&amp;gt;(_ block: @escaping () async throws -&amp;gt; Value) async throws -&amp;gt; Value {
    let condition = await counter.enterLimiting()
    await condition.wait()

    do {
        let value = try await block()
        await counter.exitLimiting()
        return value
    } catch {
        await counter.exitLimiting()
        throw error
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;First things first: &lt;code&gt;counter&lt;/code&gt; is an actor owned by the &lt;code&gt;ConcurrencyLimiter&lt;/code&gt;. It does all the&amp;hellip; counting&amp;hellip; of how many tasks are running at one time. It&amp;rsquo;ll also decide which task goes next. So maybe I should have called it &lt;code&gt;Scheduler&lt;/code&gt;? This is chaos that happens when you don&amp;rsquo;t have code reviews. &lt;em&gt;smh&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;run&lt;/code&gt; calls into &lt;code&gt;counter&lt;/code&gt; to ask to enter the limited section. The &lt;code&gt;counter&lt;/code&gt; returns a &lt;code&gt;Condition&lt;/code&gt; which the calling &lt;code&gt;Task&lt;/code&gt; immediately waits on. The &lt;code&gt;Condition&lt;/code&gt; is described in &lt;a href=&quot;/blog/2024/04/14/modeling-condition-variables-in-swift-asyncawait/&quot;&gt;my previous post&lt;/a&gt;, and is what allows &lt;code&gt;Counter&lt;/code&gt; to control which &lt;code&gt;Task&lt;/code&gt; goes next. Once the &lt;code&gt;Task&lt;/code&gt; returns from the call to &lt;code&gt;condition.wait()&lt;/code&gt; it executes its code. Before returning or throwing it calls back into &lt;code&gt;counter&lt;/code&gt; on &lt;code&gt;exitLimiting()&lt;/code&gt; to let it know this &lt;code&gt;Task&lt;/code&gt; is done.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s it for &lt;code&gt;run&lt;/code&gt;. Most of the heavy lifting is in &lt;code&gt;Counter&lt;/code&gt; so I&amp;rsquo;ll look at that next.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
final actor Counter {
    /// The maximum amount of currency allowed
    private let concurrency: Int
    /// How many blocks are currently in flight
    private var inflightCount = 0
    /// Pending (blocked) blocks in a FIFO queue.
    private var pending = [Signal]()

    init(concurrency: Int) {
        self.concurrency = concurrency
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There&amp;rsquo;s not much data needed by the scheduler. Um&amp;hellip; I mean &lt;code&gt;Counter&lt;/code&gt;. &lt;em&gt;Counter&lt;/em&gt;. It has the maximum number of concurrent tasks allowed, how many are actually in flight right now, then an array of &lt;code&gt;Tasks&lt;/code&gt; in priority order represented by the &lt;code&gt;Signal&lt;/code&gt; that will unblock them. That&amp;rsquo;s it.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;enterLimiting()&lt;/code&gt; is called by the Task when it wants to enter the limited section:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
func enterLimiting() -&amp;gt; Condition {
    let shouldWait = inflightCount &amp;gt;= concurrency

    let (condition, signal) = Condition.makeCondition()
    if shouldWait {
        pending.append(signal)
    } else {
        // immediately signal and let it run
        inflightCount += 1
        signal.signal()
    }

    return condition
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This method is in an actor, and there are no awaits in here, so this method happens without reentrancy. That&amp;rsquo;s important. It computes if the caller can immediately execute or it should wait. Either way, it creates a &lt;code&gt;Condition/Signal&lt;/code&gt; pair so it can return the &lt;code&gt;Condition&lt;/code&gt;. If the calling &lt;code&gt;Task&lt;/code&gt; can execute immediately, it acts like it has already started by incrementing in the inflight count and pre-signaling (i.e. unblocking) the &lt;code&gt;Condition&lt;/code&gt;. If the calling &lt;code&gt;Task&lt;/code&gt; needs to wait, the &lt;code&gt;Signal&lt;/code&gt; is appended to the end of the waiting queue.&lt;/p&gt;
&lt;p&gt;The other end of the process is when the calling &lt;code&gt;Task&lt;/code&gt; leaves the limited section.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
func exitLimiting() {
    inflightCount -= 1
    let shouldUnblock = inflightCount &amp;lt; concurrency

    guard shouldUnblock, let firstPending = pending.first else {
        return
    }
    pending.removeFirst()
    inflightCount += 1
    firstPending.signal()
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It immediately updates the inflight count and determines if it can unblock any of the pending &lt;code&gt;Task&lt;/code&gt;s. If it can and there are tasks waiting, it counts the &lt;code&gt;Task&lt;/code&gt; as started and unblocks by signaling the &lt;code&gt;Task&lt;/code&gt;&amp;lsquo;s condition.&lt;/p&gt;
&lt;p&gt;You might have noticed this is a simple FIFO queue for prioritization. However, really any prioritization scheme could be substituted in.&lt;/p&gt;
&lt;p&gt;Finally, I put a little bit of &amp;ldquo;what if&amp;rdquo; insurance in the &lt;code&gt;deinit&lt;/code&gt; of the actor. Basically, what happens if the &lt;code&gt;Counter&lt;/code&gt; goes out of scope, but there are still &lt;code&gt;Task&lt;/code&gt;s blocked on it?&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
deinit {
    let localPending = pending
    pending.removeAll()
    for local in localPending {
        local.signal()
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I make a local copy because I&amp;rsquo;m just extra paranoid (probably don&amp;rsquo;t need that), then go through and unblock everything. Presumably no callers care anymore if we&amp;rsquo;re going out of scope, but I don&amp;rsquo;t want to leave any &lt;code&gt;Task&lt;/code&gt;s blocked.&lt;/p&gt;
&lt;p&gt;(As an aside, I remember from my undergrad days this kind of data structure being called a &amp;ldquo;monitor.&amp;rdquo; But Wikipedia says I&amp;rsquo;m wrong.)&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;In this post, I described my learning journey where I realized that I didn&amp;rsquo;t need an execution queue like &lt;code&gt;OperationQueue&lt;/code&gt; for my particular problem. Instead, I wanted to let each &lt;code&gt;Task&lt;/code&gt; bring its own execution, and just needed a queue to limit the number of concurrent executions. Finally, I demonstrated a simple implementation of a &lt;code&gt;ConcurrencyLimiter&lt;/code&gt; using &lt;a href=&quot;/blog/2024/04/14/modeling-condition-variables-in-swift-asyncawait/&quot;&gt;the &lt;code&gt;Condition/Signal&lt;/code&gt; pair I introduced in my previous post&lt;/a&gt;.&lt;/p&gt;
</description>
      <category>Swift</category>
      <category>Programming</category>
      <category>Async</category>
      <pubDate>Sun, 14 Apr 2024 17:35:58 -0400</pubDate>
      <guid isPermaLink="false">https://losingfight.com/blog/?p=574</guid>
      <dc:creator>Andy</dc:creator>
      <dc:date>2024-04-14T17:35:58-04:00</dc:date>
    </item>
    <item>
      <title>Modeling condition variables in Swift async/await</title>
      <link>https://losingfight.com/blog/2024/04/14/modeling-condition-variables-in-swift-asyncawait/</link>
      <description>&lt;p&gt;In the brave new world of Swift async/await, a problem I sometimes encounter is how to communicate between &lt;code&gt;Task&lt;/code&gt;s. More specifically, if I need one &lt;code&gt;Task&lt;/code&gt; to wait on a condition to be true as a result of work that&amp;rsquo;s done by another set of &lt;code&gt;Task&lt;/code&gt;s. In this post I&amp;rsquo;ll cover how I eventually ended up solving this using something like a condition variable.&lt;/p&gt;
&lt;h2&gt;Refining the problem scope&lt;/h2&gt;
&lt;p&gt;There&amp;rsquo;s more than one way to handle &lt;code&gt;Task&lt;/code&gt; synchronization, so I want to start by refining the problem that I&amp;rsquo;m trying to solve. The hope is it&amp;rsquo;ll be clearer why I chose the solution I did.&lt;/p&gt;
&lt;p&gt;One of the easiest ways to have one &lt;code&gt;Task&lt;/code&gt; wait on another&amp;rsquo;s work is to package up that work in it&amp;rsquo;s own &lt;code&gt;Task&lt;/code&gt; then just &lt;code&gt;await&lt;/code&gt; that. Here&amp;rsquo;s a oversimplified example of a pattern that I&amp;rsquo;ve used:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
final actor Thingy {
    private let loadTask: Task&amp;lt;Void, Never&amp;gt;

    /// User might call this at some point, repeatedly
    func processData() async {
        // Waiting on the task to ensure it's done before continuing
        await loadTask.value

        // Ok, now I can do my processing safe that we've loaded
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this example, loading the data can take a while and I want to make sure it&amp;rsquo;s loaded before doing any on-demand processing of it. I also don&amp;rsquo;t want to do the load repeatedly, so I wrap it up in &lt;code&gt;Task&lt;/code&gt; and set it as a property. Any &lt;code&gt;Task&lt;/code&gt; that needs load to be completed just &lt;code&gt;await&lt;/code&gt;s the value. (This is an extremely contrived example to demonstrate a pattern. Don&amp;rsquo;t email how you&amp;rsquo;d refactor it.) The point here is awaiting the result of a &lt;code&gt;Task&lt;/code&gt; is a nice, straight forward mechanism for synchronizing work between two tasks.&lt;/p&gt;
&lt;p&gt;However, there&amp;rsquo;s a variation of this problem that I want to solve in this post. It&amp;rsquo;s not that a specific task has completed, but a condition has become true. That sounds subtle, but there&amp;rsquo;s actually a big difference. Multiple &lt;code&gt;Task&lt;/code&gt;s may be working and any one them might make the condition become true. &lt;/p&gt;
&lt;p&gt;For example, suppose I want to limit the number of concurrent &lt;code&gt;Task&lt;/code&gt;s that are downloading images to be no more than 10. When a &lt;code&gt;Task&lt;/code&gt; starts to download an image it needs to know if there&amp;rsquo;s less than 10. If there are 10 or more, it wants to wait until one of the existing &lt;code&gt;Task&lt;/code&gt; has finished. This is where awaiting on a single &lt;code&gt;Task&lt;/code&gt; as a solution falls apart. The waiting &lt;code&gt;Task&lt;/code&gt; actually wants to know when the concurrency count goes below 10, not when a specific &lt;code&gt;Task&lt;/code&gt; completes (although they are correlated). It can&amp;rsquo;t &lt;code&gt;await&lt;/code&gt; all the executing &lt;code&gt;Task&lt;/code&gt;s because it doesn&amp;rsquo;t need to wait until all &lt;code&gt;Task&lt;/code&gt;s complete. If it awaits a single &lt;code&gt;Task&lt;/code&gt;, it also might wait longer than necessary if a different &lt;code&gt;Task&lt;/code&gt; from the one its &lt;code&gt;await&lt;/code&gt;ing completes first. Of course this is all ignoring that there could be many &lt;code&gt;Task&lt;/code&gt;s waiting for the concurrency count to go below 10, and how do I ensure only &lt;em&gt;one&lt;/em&gt; of them continues when it drops to 9 concurrent?&lt;/p&gt;
&lt;p&gt;(Also, I know the classic way to solve the image download concurrency limiting is to use &lt;code&gt;OperationQueue&lt;/code&gt;. But in a future post, I&amp;rsquo;m going to argue that&amp;rsquo;s not ideal in an async/await world for this problem.)&lt;/p&gt;
&lt;p&gt;To summarize: I want to have a &lt;code&gt;Task&lt;/code&gt; to wait on a &lt;em&gt;condition&lt;/em&gt; to become true, which isn&amp;rsquo;t the same as waiting on a &lt;code&gt;Task&lt;/code&gt; to complete.&lt;/p&gt;
&lt;h2&gt;Classic approach&lt;/h2&gt;
&lt;p&gt;If I was still in the bad old days of pthreads, I&amp;rsquo;d reach for a condition variable. I&amp;rsquo;d have the queued &lt;code&gt;Task&lt;/code&gt; wait on it, and when the concurrent count dropped below 10, the just completed download &lt;code&gt;Task&lt;/code&gt; would signal the condition variable. But I can&amp;rsquo;t actually use pthread condition variables because they&amp;rsquo;d block the underlying system thread, which would hang one of the thread resources used by Swift&amp;rsquo;s cooperative pool. Then everybody would just be sad.&lt;/p&gt;
&lt;p&gt;However, what if I could construct something similar to a condition variable that stays in async/await land? It wouldn&amp;rsquo;t actually need to do everything a traditional pthread condition does, like make sure only one &lt;code&gt;Task&lt;/code&gt; unblocks because I could handle that manually. &lt;/p&gt;
&lt;p&gt;Let me sketch out what that might look like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
struct Condition {
    func wait() async {}

    static func makeCondition() -&amp;gt; (Condition, Signal)
}

final class Signal {
    func signal() {}
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With this approach, the &lt;code&gt;Task&lt;/code&gt; that wants to download an image can call into the queue that knows how many downloads are currently going. The queue constructs a &lt;code&gt;Condition/Signal&lt;/code&gt; pair, keeps the &lt;code&gt;Signal&lt;/code&gt; and returns back the &lt;code&gt;Condition&lt;/code&gt; to the calling &lt;code&gt;Task&lt;/code&gt;. The calling &lt;code&gt;Task&lt;/code&gt; then &lt;code&gt;wait()&lt;/code&gt;s on that &lt;code&gt;Condition&lt;/code&gt;. When the queue decides it&amp;rsquo;s time for that specific &lt;code&gt;Task&lt;/code&gt; to go (it can keep a prioritized array of &lt;code&gt;Signal&lt;/code&gt;s), it calls &lt;code&gt;signal()&lt;/code&gt; on the &lt;code&gt;Signal&lt;/code&gt; and the paired &lt;code&gt;Condition&lt;/code&gt; unblocks.&lt;/p&gt;
&lt;p&gt;This behavior would solve my stated problem: my &lt;code&gt;Task&lt;/code&gt; could wait on a &lt;em&gt;condition&lt;/em&gt; to become true, instead of waiting on a specific &lt;code&gt;Task&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;p&gt;I chose to use an &lt;code&gt;AsyncStream&lt;/code&gt; to build this functionality. Basically, the &lt;code&gt;Condition.wait()&lt;/code&gt; is going to sit in an async/await loop waiting on the &lt;code&gt;AsyncStream&lt;/code&gt; to complete. The &lt;code&gt;Signal.signal()&lt;/code&gt; calls &lt;code&gt;finish()&lt;/code&gt; on the &lt;code&gt;AsyncStream&lt;/code&gt;&amp;lsquo;s continuation to unblock it.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
/// Signal is used in conjunction with Condition. Together they allow
/// one Task to wait on anther Task.
public final class Signal {
    private let stream: AsyncStream&amp;lt;Void&amp;gt;.Continuation

    /// Private init, don't call directly. Instead, use Condition.makeCondition()
    fileprivate init(stream: AsyncStream&amp;lt;Void&amp;gt;.Continuation) {
        self.stream = stream
    }

    /// Signal the waiter (who has the Condition) that they're good to go
    public func signal() {
        stream.finish()
    }
}

/// Condition allows two async Tasks to coordinate. Use `makeCondition()` to
/// create a Condition/Signal pair. The Task that wants to wait on something to
/// happen takes the Condition, the Task that notifies of the condition takes
/// the Signal.
public struct Condition {
    private let waiter: () async -&amp;gt; Void

    /// Private init; create a closure that will can be waited on
    fileprivate init(waiter: @escaping () async -&amp;gt; Void) {
        self.waiter = waiter
    }

    /// Wait on the condition to become true
    public func wait() async {
        await waiter()
    }

    /// Construct a Condition/Signal pair. The Task that wants to wait on something to
    /// happen takes the Condition, the Task that notifies of the condition takes
    /// the Signal.
    public static func makeCondition() -&amp;gt; (Condition, Signal) {
        let (stream, continuation) = AsyncStream&amp;lt;Void&amp;gt;.makeStream()
        let condition = Condition {
            for await _ in stream {}
        }
        let signal = Signal(stream: continuation)
        return (condition, signal)
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;In this post I described a variation of a &lt;code&gt;Task&lt;/code&gt; synchronization problem. In this variation a &lt;code&gt;Task&lt;/code&gt; wants to wait on a condition to become true, as opposed to a &lt;code&gt;Task&lt;/code&gt; being completed. I then introduced simplified version of a traditional synchronization mechanism called a condition variable as a mechanism for solving this problem. Finally, I demonstrated a working async/await solution using &lt;code&gt;AsyncStream&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/blog/2024/04/14/swift-asyncawait-do-you-even-need-a-queue/&quot;&gt;Read the follow up post&lt;/a&gt;.&lt;/p&gt;
</description>
      <category>Swift</category>
      <category>Programming</category>
      <category>Async</category>
      <pubDate>Sun, 14 Apr 2024 15:56:19 -0400</pubDate>
      <guid isPermaLink="false">https://losingfight.com/blog/?p=573</guid>
      <dc:creator>Andy</dc:creator>
      <dc:date>2024-04-14T15:56:19-04:00</dc:date>
    </item>
    <item>
      <title>Updating NativeMarkKit for SwiftUI and iOS 14</title>
      <link>https://losingfight.com/blog/2020/11/14/updating-nativemarkkit-for-swiftui-and-ios-14/</link>
      <description>&lt;p&gt;I&amp;rsquo;ve pushed a small update to &lt;a href=&quot;https://github.com/andyfinnell/NativeMarkKit&quot;&gt;NativeMarkKit&lt;/a&gt;, my native Markdown rendering framework. It adds some SwiftUI wrappers that incorporate workarounds for the &lt;a href=&quot;/blog/2020/08/22/uiviewrepresentable-doesnt-respect-intrinsiccontentsize-invalidation/&quot;&gt;UIKit-SwiftUI interop bugs&lt;/a&gt;. It also fixes a bug introduced by iOS/tvOS 14 that prevented inline backgrounds from being rendered.&lt;/p&gt;
&lt;p&gt;Enjoy!&lt;/p&gt;
</description>
      <category>Programming</category>
      <category>Swift</category>
      <category>Markdown</category>
      <category>Cocoa</category>
      <category>UIKit</category>
      <category>AppKit</category>
      <category>SwiftUI</category>
      <pubDate>Sat, 14 Nov 2020 14:47:15 -0500</pubDate>
      <guid isPermaLink="false">https://losingfight.com/blog/?p=572</guid>
      <dc:creator>Andy</dc:creator>
      <dc:date>2020-11-14T14:47:15-05:00</dc:date>
    </item>
    <item>
      <title>Introducing NativeMarkKit, native Markdown rendering</title>
      <link>https://losingfight.com/blog/2020/08/29/introducing-nativemarkkit-native-markdown-rendering/</link>
      <description>&lt;p&gt;I&amp;rsquo;d like to announce the release of one of my side projects: &lt;a href=&quot;https://github.com/andyfinnell/NativeMarkKit&quot;&gt;NativeMarkKit&lt;/a&gt;. NativeMarkKit is a Swift package implementing the rendering of NativeMark. What&amp;rsquo;s NativeMark? Well, it&amp;rsquo;s a flavor of Markdown designed to be rendered by native iOS, macOS, or tvOS apps. i.e. it compiles down to &lt;code&gt;NSAttributedString&lt;/code&gt; (mostly) instead of HTML and CSS. It&amp;rsquo;s basically &lt;a href=&quot;https://commonmark.org/&quot;&gt;CommonMark&lt;/a&gt;, but without the raw HTML tag support.&lt;/p&gt;
&lt;p&gt;I often get mockups from designers who want to style text like they would on web. So they mix in bold, italics, links and other things within the copy. While that can be done natively, it&amp;rsquo;s a hassle, requiring manually building up &lt;code&gt;NSAttributedString&lt;/code&gt;s and concat-ing them together. NativeMarkKit allows me to have one localized Markdown string, and let the framework figure out how to render that down into a &lt;code&gt;NSAttributedString&lt;/code&gt;. As a bonus, NativeMarkKit supports Dynamic Type and Dark Mode. I can also style the Markdown using whatever app-branded &lt;code&gt;NS/UIColor&lt;/code&gt;s I have in the app.&lt;/p&gt;
</description>
      <category>Programming</category>
      <category>Swift</category>
      <category>Markdown</category>
      <category>Cocoa</category>
      <category>UIKit</category>
      <category>AppKit</category>
      <pubDate>Sat, 29 Aug 2020 10:15:17 -0400</pubDate>
      <guid isPermaLink="false">https://losingfight.com/blog/?p=571</guid>
      <dc:creator>Andy</dc:creator>
      <dc:date>2020-08-29T10:15:17-04:00</dc:date>
    </item>
    <item>
      <title>UIViewRepresentable doesn't respect intrinsicContentSize invalidation</title>
      <link>https://losingfight.com/blog/2020/08/22/uiviewrepresentable-doesnt-respect-intrinsiccontentsize-invalidation/</link>
      <description>&lt;p&gt;This is a quick write-up of an unexpected SwiftUI limitation I encountered recently. In my own searching, I couldn&amp;rsquo;t find it documented anywhere so I&amp;rsquo;m hoping this post will help someone in the future.&lt;/p&gt;
&lt;h3&gt;Problem summary&lt;/h3&gt;
&lt;p&gt;You can&amp;rsquo;t wrap a &lt;code&gt;UIView&lt;/code&gt; in SwiftUI&amp;rsquo;s &lt;code&gt;UIViewRepresentable&lt;/code&gt; if that &lt;code&gt;UIView&lt;/code&gt; changes its &lt;code&gt;intrinsicContentSize&lt;/code&gt; based in its &lt;code&gt;frame&lt;/code&gt; width, because &lt;code&gt;UIViewRepresentable&lt;/code&gt; will ignore &lt;code&gt;invalidateIntrinsicContentSize()&lt;/code&gt;. As a result, the &lt;code&gt;UIView&lt;/code&gt; will have its height clipped.&lt;/p&gt;
&lt;p&gt;To make it a bit more concrete, imagine you have a &lt;code&gt;UIView&lt;/code&gt; that draws multiline text that can line wrap. &lt;code&gt;UILabel&lt;/code&gt; would be an example. If you were to adjust the label&amp;rsquo;s &lt;code&gt;frame&lt;/code&gt; width, it would reflow the text and the intrinsic content height would change to reflect that. &lt;/p&gt;
&lt;p&gt;During SwiftUI layout, what &lt;code&gt;UIViewRepresentable&lt;/code&gt; does is ask the &lt;code&gt;UIView&lt;/code&gt; for its intrinsic content size before it has set the &lt;code&gt;UIView&lt;/code&gt;&amp;lsquo;s frame. It then takes the minimum of the available size from the superview and the &lt;code&gt;UIView&lt;/code&gt;&amp;lsquo;s &lt;code&gt;intrinsicContentSize&lt;/code&gt;, and sets that as the &lt;code&gt;UIView&lt;/code&gt;&amp;lsquo;s &lt;code&gt;frame&lt;/code&gt;. This causes the &lt;code&gt;UIView&lt;/code&gt; to reflow the text and invalidate its intrinsic content size. &lt;code&gt;UIViewRepresentable&lt;/code&gt; ignores this, and as a result the &lt;code&gt;UIView&lt;/code&gt; is clipped too short.&lt;/p&gt;
&lt;p&gt;You can find a &lt;a href=&quot;https://github.com/andyfinnell/SwiftUIBug1&quot;&gt;simplified version of this bug using UILabel on Github&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Investigation&lt;/h3&gt;
&lt;p&gt;I tried many suggestions from Stack Overflow, and override any size or layout related &lt;code&gt;UIView&lt;/code&gt; method that I could. None of the suggestions worked, and almost none of the &lt;code&gt;UIView&lt;/code&gt; methods were ever called during layout. I felt I was probably missing something obvious, so I filed a Developer Tech Support incident with Apple to get an official answer. My submission is summarized in &lt;a href=&quot;https://github.com/andyfinnell/SwiftUIBug1&quot;&gt;the Github repo&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Results&lt;/h3&gt;
&lt;p&gt;Here&amp;rsquo;s the official response from Apple:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;
    Hello Andy,&lt;/p&gt;
&lt;p&gt;    Thank you for contacting Apple Developer Technical Support (DTS). We have reviewed your request and have concluded that there is no supported way to achieve the desired functionality given the currently shipping system configurations.&lt;/p&gt;
&lt;p&gt;    If you would like for Apple to consider adding support for such features in the future, please submit an enhancement request via Feedback Assistant (https://feedbackassistant.apple.com). For more information on Feedback Assistant, please visit https://developer.apple.com/bug-reporting/.&lt;/p&gt;
&lt;p&gt;    While a Technical Support Incident (TSI) was initially debited from your Apple Developer Program account for this request, we have assigned a replacement incident back to your account.&lt;/p&gt;
&lt;p&gt;    Best Regards,&lt;/p&gt;
&lt;p&gt;    Developer Technical Support&lt;br /&gt;
    Worldwide Developer Relations&lt;br /&gt;
    Apple, Inc.
&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;According to the response this is expected behavior, so any change would an enhancement request. I have since filed the enhancement request as feedback &lt;code&gt;FB8499811&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;Moment of Zen&lt;/h3&gt;
&lt;p&gt;I have the exact same view on macOS as an &lt;code&gt;NSView&lt;/code&gt; wrapped up in an &lt;code&gt;NSViewRepresentable&lt;/code&gt;. It works great. When the &lt;code&gt;NSView&lt;/code&gt; invalidates its intrinsic size, &lt;code&gt;NSViewRepresentable&lt;/code&gt; re-queries the intrinsic size and updates the &lt;code&gt;frame&lt;/code&gt; appropriately. &lt;/p&gt;
&lt;p&gt;I guess someone already filed that enhancement request.&lt;/p&gt;
</description>
      <category>Programming</category>
      <category>Swift</category>
      <category>SwiftUI</category>
      <category>Bugs</category>
      <pubDate>Sat, 22 Aug 2020 12:07:32 -0400</pubDate>
      <guid isPermaLink="false">https://losingfight.com/blog/?p=570</guid>
      <dc:creator>Andy</dc:creator>
      <dc:date>2020-08-22T12:07:32-04:00</dc:date>
    </item>
    <item>
      <title>Sharing HTTP API bindings between Swift Vapor and iOS/macOS apps</title>
      <link>https://losingfight.com/blog/2019/01/21/sharing-http-api-bindings-between-swift-vapor-and-iosmacos-apps/</link>
      <description>&lt;p&gt;I&amp;rsquo;ve been building a macOS/iOS front for my &lt;a href=&quot;https://vapor.codes/&quot;&gt;Swift Vapor&lt;/a&gt; side project. When I first started I simply duplicated the API HTTP request and response information between the client and server. But, as the project has grown, this has become more tedious. Since both client and server are in Swift, it seems like I should be able to come up with a more scalable solution. Ideally, I&amp;rsquo;d like to define an API in one place and have both the client and server code use it. So in this post, I will: figure out what&amp;rsquo;s shareable, wrestle with package managers to share it, and finally integrate the API component into both the server and client.&lt;/p&gt;
&lt;h2&gt;What can be shared&lt;/h2&gt;
&lt;p&gt;I first had to determine what parts of the API made sense to share between the client and server. Both would need the same information, but they encode that information in different ways, and those ways might not be compatible. In my thinking there are five pieces of API information: the URL path, HTTP method, query parameters, request body, and response body.&lt;/p&gt;
&lt;p&gt;While it would be nice to share the URL path, the client and server encoded them in very different ways. The client used a raw string for the entire path, while the server implicitly encoded the path, one component at a time, in a &lt;a href=&quot;/blog/2019/01/06/building-a-declarative-router-for-swift-vapor/&quot;&gt;declarative router&lt;/a&gt;. The HTTP method was treated similarly. The client had an enum for the method, while the server encoded the method implicitly in the routing table. So I couldn&amp;rsquo;t easily share paths and methods. Or, perhaps more accurately, I didn&amp;rsquo;t feel I could share them without making the client and server code worse.&lt;/p&gt;
&lt;p&gt;Query parameters are special in that they are not declared on either side. The server checks for their existence down in the controller code, but there&amp;rsquo;s no standard declaration or deserialization of them. So currently, I can&amp;rsquo;t share them. However, I feel like this could be improved somehow using &lt;code&gt;Codable&lt;/code&gt; to define all the possible query parameters. I will likely revisit this in the future.&lt;/p&gt;
&lt;p&gt;I found that only the request body and the response bodies were used similarly enough on both sides to be sharable. Both declared them as &lt;code&gt;Codable&lt;/code&gt; structs, albeit with slightly different names. But I felt like I could consolidate on a naming scheme that would make sense for both sides.&lt;/p&gt;
&lt;p&gt;I also briefly thought about putting the sending and receiving of responses into the shareable library. But that didn&amp;rsquo;t work easily because it would require importing the Vapor framework for the server support, which I didn&amp;rsquo;t want to do for a Cocoa app. Perhaps more importantly, that part of the code wouldn&amp;rsquo;t actually be shared; only one side would be using it. So my decision was to only share data structures and not code.&lt;/p&gt;
&lt;h2&gt;Structure and naming in the shared component&lt;/h2&gt;
&lt;p&gt;Now that I had decided that I only wanted to share the request and response data structures, I needed to figure out a way to build that. I had a few requirements. First, I needed to minimize name collisions; the library was to be imported into both the client and server apps, which increased the odds of a collision. Second, I needed to name the data structures in a way that wasn&amp;rsquo;t client or server centric, which was their current state. The names needed to make sense on both the client and server. Thirdly, I needed to name things consistently so they were discoverable. Finally, there were some functional requirements, such as the requests and responses needed to be &lt;code&gt;Codable&lt;/code&gt; and &lt;code&gt;Equatable&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;First, to solve global name collisions, I nested everything in a namespace. Since Swift doesn&amp;rsquo;t have real namespaces, I used an enum:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
import Foundation

public enum MyAppAPI {

}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I put the app name in the namespace name because my client app already had a type named &lt;code&gt;API&lt;/code&gt;. It also would allow the client to import multiple API bindings in the future without collisions.&lt;/p&gt;
&lt;p&gt;As far as structuring the API bindings consistently, I decided to group things by REST resource. As an example, here&amp;rsquo;s the bindings for the user resource:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
import Foundation

public extension MyAppAPI {
    public enum User {
        public struct Envelope&amp;lt;T&amp;gt;: Codable, Equatable where T: Codable, T: Equatable {
            public let user: T

            public init(user: T) {
                self.user = user
            }
        }

        public struct ShowResponse: Codable, Equatable {
            public let id: UUID
            public let email: String

            public init(id: UUID, email: String) {
                self.id = id
                self.email = email
            }
        }

        public struct UpdateRequest: Codable, Equatable {
            public let resetTokens: Bool

            public init(resetTokens: Bool) {
                self.resetTokens = resetTokens
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There&amp;rsquo;s a lot to unpack. First, I put each resource into its own file. Second, I created a &amp;ldquo;namespace&amp;rdquo; (i.e. a Swift &lt;code&gt;enum&lt;/code&gt;) for each resource inside the main API namespace. Inside the resource namespace, I created the individual requests and resource bodies. My naming convention was REST verb + &lt;code&gt;Request&lt;/code&gt; or &lt;code&gt;Response&lt;/code&gt;. My hope was this would make them easily discoverable. I also used envelopes in my APIs for clarity, so I declared my envelope for each resource as well.&lt;/p&gt;
&lt;p&gt;In doing this work, I ran into a few practical considerations, aka things I had to do to appease Swift. The first thing was making &lt;em&gt;everything&lt;/em&gt; &lt;code&gt;public&lt;/code&gt;, which was a bit tedious. This had a knock-on effect in that the &lt;code&gt;struct&lt;/code&gt; default &lt;code&gt;init&lt;/code&gt;s didn&amp;rsquo;t work because they&amp;rsquo;re implicitly &lt;code&gt;internal&lt;/code&gt;. I had to go through and manually implement the &lt;code&gt;init&lt;/code&gt;s so that I could declare them &lt;code&gt;public&lt;/code&gt;. This was enough overhead that I briefly reconsidered if having a sharable API component was worth doing. In the end I decided it was worth it, but I really wish there was a way to specify the access level of the implicit &lt;code&gt;init&lt;/code&gt; on a &lt;code&gt;struct&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;One thing I didn&amp;rsquo;t attempt to deal with was API versioning. That&amp;rsquo;s only because I haven&amp;rsquo;t had to deal with it yet. I suspect I&amp;rsquo;ll add a namespace under the resource namespace for each non-v1 version, and add the updated request and response bodies there.&lt;/p&gt;
&lt;h2&gt;How to share&lt;/h2&gt;
&lt;p&gt;I had a plan of what to share, but I needed to figure out the mechanics of how to share. In most languages, this is done by a package manager, and Swift is no different. In fact, for Swift, there&amp;rsquo;s at least three package managers that can be chosen: &lt;a href=&quot;https://swift.org/package-manager/&quot;&gt;Swift Package Manager (SwiftPM)&lt;/a&gt;, &lt;a href=&quot;https://github.com/Carthage/Carthage&quot;&gt;Carthage&lt;/a&gt;, and &lt;a href=&quot;https://cocoapods.org/&quot;&gt;Cocoapods&lt;/a&gt;.  Ideally, I would like to use only one for both client and server. Unfortunately, each package manager has its own limitations, which made using only one undesirable.&lt;/p&gt;
&lt;p&gt;SwiftPM has Linux support, but Carthage and Cocoapods don&amp;rsquo;t, meaning SwiftPM is the only viable option for my Swift Vapor app. However, SwiftPM doesn&amp;rsquo;t currently have the ability to generate Cocoa frameworks or apps, only Swift static libraries or command line apps. Since my API component doesn&amp;rsquo;t have any resources that require a framework, and Xcode can link against static Swift libraries for Cocoa apps, SwiftPM is a technical possibility. However, there is a decent amount of inconvenience involved with this approach (Googling can turn up tutorials on how). One is that my client apps would need two package managers (SwiftPM and either Carthage or Cocoapods). That&amp;rsquo;s because outside of my shared API component, all of the other packages my client app needs are only available as Carthage or Cocoapods packages. SwiftPM is supposedly going to get the ability to build Cocoa apps and frameworks sometime in the future, but not today. &lt;/p&gt;
&lt;p&gt;In the end, I decided to make my API component both a SwiftPM package and a Carthage package. My Swift Vapor app would use the SwiftPM package, and my Cocoa apps would use the Carthage package. Although this meant a higher up front cost of setting up both, my thinking is it shouldn&amp;rsquo;t noticeably increase the maintenance burden afterwards. The benefit is each app can use the package manager best suited for its platform, which should make updating the API component easier when changes are made.&lt;/p&gt;
&lt;p&gt;Between the two package managers, SwiftPM is stricter, requiring a specific directory hierarchy. Since Carthage uses an Xcode project, it could adapt to any hierarchy. For that reason, I tackled setting the SwiftPM package up first.&lt;/p&gt;
&lt;h2&gt;Refactoring the Swift Vapor app&lt;/h2&gt;
&lt;p&gt;In my apps, the server app was the source of truth for API information. It had the full definitions of the request and response bodies, and was the most up-to-date. So my plan was to pull the definitions out of the Vapor app into the API component, publish the component, then have the Vapor app import that component. Later, I could figure out how to refactor the Cocoa client apps.&lt;/p&gt;
&lt;p&gt;First I created a SwiftPM package for the API component from the command line, and committed it to a git repo.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
&amp;gt; mkdir MyAppAPI
&amp;gt; cd MyAppAPI
&amp;gt; swift package init
&amp;gt; git init
&amp;gt; git commit -am &quot;Initial commit&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, I moved over the API request and response definitions from the Vapor app, and modified them to fit the structure and naming conventions I defined earlier. I&amp;rsquo;d use &lt;code&gt;swift build&lt;/code&gt; periodically to make sure everything was valid Swift code from SwiftPM&amp;rsquo;s perspective. Since I prefer Xcode&amp;rsquo;s editor to a command line editor, I used &lt;code&gt;swift package generate-xcodeproj&lt;/code&gt; to create a project, and then made my changes in Xcode. When I was done, I committed my changes in git.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
&amp;gt; git commit -am &quot;Adding API definitions&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To share the package, I needed a remote git repo that both client and server could pull from, plus a version number. Since &lt;a href=&quot;https://bitbucket.org&quot;&gt;Bitbucket&lt;/a&gt; offers free private repos, I created one there, and added it as the remote origin. (&lt;a href=&quot;https://github.com&quot;&gt;Github&lt;/a&gt; recently announced free private repos, too.) Then I tagged my repo with a version, and pushed it to the remote:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
&amp;gt; git remote add origin &amp;lt;MyAppAPI bitbucket git URL&amp;gt;
&amp;gt; git tag 0.0.1
&amp;gt; git push origin master --tags
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that SwiftPM version tags are just the version number, sans any prefix or suffix.&lt;/p&gt;
&lt;p&gt;I was now ready to refactor my Vapor app to pull in this shared package and use it instead. First, I modified the &lt;code&gt;Package.swift&lt;/code&gt; file to include it as a dependency:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
    dependencies: [
        ...
        .package(url: &quot;&amp;lt;MyAppAPI bitbucket git URL&amp;gt;&quot;, from: &quot;0.0.1&quot;),
        ...
    ],
    ...
    targets: [
        ...
        .target(name: &quot;App&quot;, dependencies: [
            ...
            &quot;MyAppAPI&quot;,
            ...
            ]),
        ...
    ]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Running &lt;code&gt;vapor update&lt;/code&gt; from the command line pulled down the package and updated all my dependencies. &lt;/p&gt;
&lt;p&gt;Swift Vapor needs one more thing on the API request and responses before they are useable. Namely, it needs the top-level type of the request and response to conform to the &lt;code&gt;Content&lt;/code&gt; protocol that Vapor defines. Fortunately, it&amp;rsquo;s just an subprotocol of &lt;code&gt;Codable&lt;/code&gt; that provides some extra methods, so the requests and responses only need to be declared as conforming. Further, since it&amp;rsquo;s only the top level types, and I used envelopes to wrap my request and response, for me I only needed to conform the envelopes. I decided to do this all in one file, with the hopes it would be easier to keep up-to-date.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
import Foundation
import Vapor
import MyAppAPI

extension MyAppAPI.Session.Envelope: Content {}
extension MyAppAPI.User.Envelope: Content {}
...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is a bit tedious, but I didn&amp;rsquo;t find it overly so. In hindsight, using envelopes saved me a bit of work. If I hadn&amp;rsquo;t used envelopes each individual request and response would have been the top-level type, and I would have had to conform each to &lt;code&gt;Content&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The last piece was to go through all my controllers and have them import &lt;code&gt;MyAppAPI&lt;/code&gt; and use the &lt;code&gt;struct&lt;/code&gt;s defined there.&lt;/p&gt;
&lt;p&gt;In doing this part of the work, I learned a couple of things. First, all the namespacing does make using the shared package a bit verbose. Second, separating out the request and response models from the server helped clarify what was a server model and what was a response payload. I felt this work improved the server codebase.&lt;/p&gt;
&lt;h2&gt;Refactoring the Cocoa/CocoaTouch app&lt;/h2&gt;
&lt;p&gt;To get my API package working the Cocoa clients, I needed to make the API package a proper Carthage package, then import that into the Cocoa app. Since Carthage works by building an Xcode project, my first job was to create an Xcode project that built both iOS and macOS targets. This was straight forward, although tedious, since the default Xcode templates create a different folder layout than SwiftPM requires. &lt;/p&gt;
&lt;p&gt;First, in order to create a Carthage Xcode project, I deleted the existing Xcode project that the SwiftPM had built. It builds a static Swift library, but Carthage needs an iOS/macOS framework. Second, I needed to commit the Xcode project to git for Carthage, but SwiftPM generates a &lt;code&gt;.gitignore&lt;/code&gt; file that excludes Xcode projects. So I removed the &lt;code&gt;*.xcodeproject&lt;/code&gt; line from &lt;code&gt;.gitignore&lt;/code&gt;. Finally, I created an iOS framework project in Xcode with the same name as my package (e.g. MyAppAPI).&lt;/p&gt;
&lt;p&gt;While I now had an Xcode project, it was using the Xcode generated files and not the actual files I wanted. Fixing this took several manual steps. First I closed Xcode, then moved the project file itself to the root folder of the package. I moved the framework header (e.g. &lt;code&gt;MyAppAPI.h&lt;/code&gt;) and the &lt;code&gt;Info.plist&lt;/code&gt; file into the source folder (e.g. &lt;code&gt;Sources/MyAppAPI&lt;/code&gt;). Then I deleted all of the other Xcode generated files. Next I opened the project in Xcode. I removed all of the existing file references that were now broken, and then added all of Swift files, the framework header, and the Info.plist to the project. I had to mark the framework header as public, and then go into the Build Settings to update the path to the Info.plist to be correct. At this point I could build an iOS framework.&lt;/p&gt;
&lt;p&gt;The second step was to create a macOS framework. It was similarly messy. First, in Xcode, I created a new target for a macOS framework named &lt;code&gt;MyAppAPI-macOS&lt;/code&gt;. I went through and deleted all the files Xcode created in performing that, then pointed the macOS target to all the same files that the iOS target had. The &lt;code&gt;Info.plist&lt;/code&gt; and framework header were sharable between iOS and macOS. I did have to update the framework header to import &lt;code&gt;Foundation/Foundation.h&lt;/code&gt; instead of &lt;code&gt;UIKit/UIKit.h&lt;/code&gt;. In the Build Settings, I had to update the path to the &lt;code&gt;Info.plist&lt;/code&gt;. Additionally, I needed the iOS and macOS frameworks to have the same name and bundle identifier so the client code could import using the same name. To do that, I modified the Product Name and the Product Bundle Identifier to manually be the same as the iOS target. Building the macOS target now worked for me.&lt;/p&gt;
&lt;p&gt;Xcode also defines a test target and files, but since I was only defining types, I didn&amp;rsquo;t feel I needed unit tests, so I deleted it.&lt;/p&gt;
&lt;p&gt;To verify that Carthage would be able to build my project file, from the root of the package I ran:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
&amp;gt; carthage build --no-skip-current
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When everything successfully built, I was ready to publish my Carthage package.&lt;/p&gt;
&lt;p&gt;Carthage is decentralized like SwiftPM, so to publish my package I just needed to tag a version and the push that to the remote git repository. Unfortunately, Carthage and SwiftPM use two different formats for version tags. Carthage prefixes it&amp;rsquo;s version tags with &amp;ldquo;v&amp;rdquo;, while SwiftPM has no prefix. So I committed all my Carthage changes, tagged both Carthage and SwiftPM, then pushed.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
&amp;gt; git commit -am &quot;Adding Carthage support&quot;
&amp;gt; git tag 0.0.2
&amp;gt; git tag &quot;v0.0.2&quot;
&amp;gt; git push origin master --tags
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, I could pull the shared API package into my Cocoa apps. That involved adding it as a dependency in Carthage and updating. I added the repo to my &lt;code&gt;Cartfile&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
git &quot;&amp;lt;MyAppAPI bitbucket git URL&amp;gt;&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then updated Carthage from the command line.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
&amp;gt; carthage update
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Carthage doesn&amp;rsquo;t modify project files (which I consider a feature), so I went and added the &lt;code&gt;MyAppAPI.framework&lt;/code&gt; to both my iOS and macOS client app targets.&lt;/p&gt;
&lt;p&gt;Using the shared API package was straight forward in the client apps. It was simply importing the &lt;code&gt;MyAppAPI&lt;/code&gt; framework, then using the types. I did end up using some &lt;code&gt;typealias&lt;/code&gt;es to rename some of the API responses. This was because the client app&amp;rsquo;s model was the same as the response model. To me this makes sense, because the server is publishing a REST-ful interface, meaning the response model should be the resource model.&lt;/p&gt;
&lt;p&gt;And, with that, I was done!&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;My side project has both server and client apps, all written in Swift. Because they share a common language, I wanted to leverage that to share HTTP API information between the two. My hope was to reduce redundant definitions that could get out of sync. To accomplish this, I created an API repo that contained the API request and response bodies. The repo was both a valid SwiftPM package and a valid Carthage package at the same time. This allowed both the Swift Vapor server and the Cocoa iOS/macOS apps to include the same shared API package.&lt;/p&gt;
</description>
      <category>Programming</category>
      <category>Swift</category>
      <category>Vapor</category>
      <category>Server-side</category>
      <category>Cocoa</category>
      <pubDate>Mon, 21 Jan 2019 11:23:51 -0500</pubDate>
      <guid isPermaLink="false">https://losingfight.com/blog/?p=569</guid>
      <dc:creator>Andy</dc:creator>
      <dc:date>2019-01-21T11:23:51-05:00</dc:date>
    </item>
    <item>
      <title>Handling periodic tasks in Swift Vapor</title>
      <link>https://losingfight.com/blog/2019/01/13/handling-periodic-tasks-in-swift-vapor/</link>
      <description>&lt;p&gt;In my &lt;a href=&quot;https://vapor.codes/&quot;&gt;Swift Vapor&lt;/a&gt; side project, there have been a couple of instances where I wanted to run some periodic tasks. My needs were pretty simple: every X amount of time, I wanted to run a closure that would perform some database operations. On top of that, it would be nice to have a tiny bit of infrastructure to make periodic jobs require less boilerplate, have visibility in production (i.e. logging if the job was successful or not), and the ability to verify the jobs in integration tests.&lt;/p&gt;
&lt;p&gt;In this post, I&amp;rsquo;m going to flesh out a periodic job interface, lay out some implementation approaches, talk through what I actually did, and finally how I tested it. &lt;/p&gt;
&lt;h2&gt;A periodic example&lt;/h2&gt;
&lt;p&gt;First, I&amp;rsquo;ll define how I&amp;rsquo;d like to be able to schedule a periodic task in client code. Here&amp;rsquo;s an except from my app: &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
func boot(_ app: Application) throws {
    let jobQueue = try app.make(JobQueue.self)
    jobQueue.schedule(initialDelay: .hours(1),
                      delay: .hours(24),
                      withName: &quot;Accounts.cleanup&quot;) { container, connection -&amp;gt; Future&amp;lt;Void&amp;gt; in
        return self.cleanup(with: container, on: connection)
    }
}

private func cleanup(with container: Container, on connection: DatabaseConnectable) -&amp;gt; Future&amp;lt;Void&amp;gt; {
    return // task that performs clean up
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I didn&amp;rsquo;t need a complicated interface to schedule a periodic job. The initial delay and repeated delay are givens for any periodic task. The name is a bit extra, but it turned out to be quite helpful when testing and logging. Finally, the &amp;ldquo;job&amp;rdquo; itself is a closure that&amp;rsquo;s passed a dependency injection container and a database connection. Those two things are needed for just about any meaningful work in Vapor. Finally, the closure will return a &lt;code&gt;Void&lt;/code&gt; promise, which is used by the job infrastructure to know when it is complete, and if it was successful or not.&lt;/p&gt;
&lt;p&gt;Although the &lt;code&gt;JobQueue&lt;/code&gt; interface is inferable from the example above, here&amp;rsquo;s exactly how I&amp;rsquo;ve defined it for my app:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
import Foundation
import Vapor

typealias Job = (Container, DatabaseConnectable) -&amp;gt; Future&amp;lt;Void&amp;gt;

protocol JobQueue: Service {
    func schedule(initialDelay: TimeAmount, delay: TimeAmount, withName name: String, _ job: @escaping Job)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I&amp;rsquo;ve defined it as a protocol because I&amp;rsquo;ll inject a fake implementation in my integration tests. Since I&amp;rsquo;m taking advantage of the dependency injection system in Vapor, I conform the protocol to &lt;code&gt;Service&lt;/code&gt;. But all I needed was one method on the protocol to actually schedule the periodic job. The &lt;code&gt;TimeAmount&lt;/code&gt; is a datatype defined down in the &lt;code&gt;NIO&lt;/code&gt; framework.&lt;/p&gt;
&lt;h2&gt;JobQueue Decisions&lt;/h2&gt;
&lt;p&gt;Now that I&amp;rsquo;ve defined the &lt;code&gt;JobQueue&lt;/code&gt; interface, I need to figure out how to implement it. I thought of a few options. &lt;/p&gt;
&lt;p&gt;One option was to register a timer in my app at the given interval, and run the periodic job closure then and there. The benefit of this is it simple to understand and implement. The downside is it doesn&amp;rsquo;t scale up or down very well. If my host spins up more than one instance of my app, both instances will try to run this periodic task. Or, if I&amp;rsquo;m on a hobbyist plan, and my host spins down all my instances because of lack of requests, then my periodic task won&amp;rsquo;t run at all.&lt;/p&gt;
&lt;p&gt;Another option was to find or build something like &lt;a href=&quot;https://github.com/resque/resque&quot;&gt;Ruby&amp;rsquo;s Resque&lt;/a&gt; but for Swift, and use a timer to schedule a background job on Resque-but-for-Swift to perform the periodic job. The benefit would be the job would only be run once no matter how many instances of my app were spun up, plus job persistence. The downside is, as far as my Google searches show, such a thing does not exist, and building it myself would be a significant undertaking.&lt;/p&gt;
&lt;p&gt;There were also some options that didn&amp;rsquo;t fit the interface I gave above, but could be legitimate solutions. First up, I could &lt;a href=&quot;https://docs.vapor.codes/3.0/command/overview/&quot;&gt;define a Vapor command&lt;/a&gt; that&amp;rsquo;s invokable from my app&amp;rsquo;s command line that performs the periodic job. Then, using my host&amp;rsquo;s infrastructure, manually invoke the command when I think it needs to be run. The downside is it relies on me remembering to run the command. However, it wouldn&amp;rsquo;t need any internal job infrastructure, and would only run on the instance I wanted. A second option would be to do nothing. If my periodic job didn&amp;rsquo;t run nothing bad would happen for a very long time. The upside to this is it cost nothing to implement. The downside is there is a timebomb in my app that will one day go off. But that might be fine because the app might not last that long, or be completely redesigned so the periodic job is unnecessary.&lt;/p&gt;
&lt;p&gt;In the end, I went with the first solution of registering a timer in my app, and running the closure when it triggered. I decided this for a few reasons. First, I&amp;rsquo;m lazy and forgetful and won&amp;rsquo;t remember to run some manual command. Second, my side project probably won&amp;rsquo;t ever scale beyond one instance. Third, even if it did scale up, the periodic tasks running concurrently wouldn&amp;rsquo;t hurt anything. Finally, this solution did something (so no timebomb), but was the least investment that did something.&lt;/p&gt;
&lt;p&gt;As far as using a timer in my Vapor app, my first attempt was to use a 3rd party Swift library that implemented periodic jobs on top of &lt;code&gt;DispatchQueue&lt;/code&gt;. That did seem to work, but it happened outside of Vapor&amp;rsquo;s &lt;code&gt;EventLoop&lt;/code&gt;s, which always seemed a little janky to me. Later, I discovered that the &lt;code&gt;NIO&lt;/code&gt; framework offered &lt;code&gt;RepeatedTask&lt;/code&gt;s on their &lt;code&gt;EventLoop&lt;/code&gt;s, so I used those instead.&lt;/p&gt;
&lt;h2&gt;Implementing JobQueue&lt;/h2&gt;
&lt;p&gt;I had an approach now, I just needed to implement it. First up, building the production implementation of &lt;code&gt;JobQueue&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
import Foundation
import Vapor

final class ProductionJobQueue: JobQueue {
    private let eventLoop: EventLoop
    private let container: Container
    private let logger: Logger

    init(eventLoop: EventLoop, container: Container, logger: Logger) {
        self.eventLoop = eventLoop
        self.container = container
        self.logger = logger
    }
    ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;ProductionJobQueue&lt;/code&gt; needed a few things in order to function. First, it needs an &lt;code&gt;EventLoop&lt;/code&gt; so it can schedule &lt;code&gt;RepeatedTask&lt;/code&gt;s. Second, it needs a dependency injection &lt;code&gt;Container&lt;/code&gt; so it can get a database connection later to hand to a periodic job. Finally, it takes a &lt;code&gt;Logger&lt;/code&gt; because the app logs any periodic job invocation to provide some insight into what&amp;rsquo;s going on in the deployed app.&lt;/p&gt;
&lt;p&gt;The only required method of the &lt;code&gt;JobQueue&lt;/code&gt; protocol is the &lt;code&gt;schedule()&lt;/code&gt; method: &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
final class ProductionJobQueue: JobQueue {
    ...
    func schedule(initialDelay: TimeAmount, delay: TimeAmount, withName name: String, _ job: @escaping Job) {
        eventLoop.scheduleRepeatedTask(initialDelay: initialDelay, delay: delay) { repeatedTask -&amp;gt; EventLoopFuture&amp;lt;Void&amp;gt; in
            return self.execute(job, withName: name, on: repeatedTask)
        }
    }
    ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is a thin wrapper around &lt;code&gt;EventLoop.scheduleRepeatedTask()&lt;/code&gt;. All the interesting bits of the implementation are in the &lt;code&gt;execute()&lt;/code&gt; method which actually calls the job closure.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
final class ProductionJobQueue: JobQueue {
    ...
    private func execute(_ job: @escaping Job, withName name: String, on repeatedTask: RepeatedTask) -&amp;gt; Future&amp;lt;Void&amp;gt; {
        let startTime = Date()
        return container.withPooledConnection(to: .psql) { connection -&amp;gt; Future&amp;lt;Void&amp;gt; in
            return job(self.container, connection)
        }.map {
            self.logSuccess(for: name, whichStartedAt: startTime)
        }.catch { error in
            self.logFailure(error, for: name, whichStartedAt: startTime)
        }
    }
    ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;execute()&lt;/code&gt; method provides most of the value add functionality of the &lt;code&gt;JobQueue&lt;/code&gt;. First off, it grabs a database connection for the job, so the job doesn&amp;rsquo;t have to itself. Once it has a connection, it invokes the job closure with the container and database connection. It waits on the job to complete, then logs the success or failure of the job.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
final class ProductionJobQueue: JobQueue {
    ...
    private func logSuccess(for name: String, whichStartedAt startTime: Date) {
        let time = Date().timeIntervalSince(startTime).asFormattedMilliseconds
        logger.info(&quot;JOB \(name) -&amp;gt; SUCCESS [\(time)]&quot;)
    }

    private func logFailure(_ error: Error, for name: String, whichStartedAt startTime: Date) {
        let time = Date().timeIntervalSince(startTime).asFormattedMilliseconds
        logger.info(&quot;JOB \(name) -&amp;gt; FAILURE [\(time)]&quot;)
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The logging of jobs is simple, but provides some necessary transparency. It just logs the name of the job, whether it was a success or failure, and the  time it took to complete. Even though I capture the error in the failure case, I don&amp;rsquo;t log it for now. That&amp;rsquo;s because it might possibly have sensitive info in it (like database connection info) that I don&amp;rsquo;t want being saved out to a log. In the future, I might log out the name of the error type, if I discovered I needed more information when debugging production issues.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;asFormattedMilliseconds&lt;/code&gt; property above is an extraction of code from my earlier &lt;a href=&quot;/blog/2018/12/21/basic-vapor-logging-with-papertrail/&quot;&gt;Swift Vapor logging&lt;/a&gt; post:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
extension TimeInterval {
    private static let intervalFormatter: NumberFormatter = {
        let formatter = NumberFormatter()
        formatter.numberStyle = .decimal
        formatter.maximumFractionDigits = 2
        formatter.multiplier = 1000
        return formatter
    }()

    var asFormattedMilliseconds: String {
        return TimeInterval.intervalFormatter.string(for: self).map { $0 + &quot;ms&quot; } ?? &quot;???ms&quot;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, I needed to implement the &lt;code&gt;Service&lt;/code&gt; protocol so the class could be used in the dependency injection system.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
extension ProductionJobQueue: ServiceType {
    static var serviceSupports: [Any.Type] {
        return [JobQueue.self]
    }

    static func makeService(for worker: Container) throws -&amp;gt; ProductionJobQueue {
        return try ProductionJobQueue(eventLoop: worker.eventLoop, container: worker, logger: worker.make())
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As usual, I used &lt;code&gt;ServiceType&lt;/code&gt; to conform to the &lt;code&gt;Service&lt;/code&gt; protocol. This allowed me to register with only the type, plus have a dependency injection container available when the instance was created. This implementation was a bit different than usual, in that I needed to override the static &lt;code&gt;serviceSupports&lt;/code&gt; property to include the &lt;code&gt;JobQueue&lt;/code&gt; protocol. This is needed because by default &lt;code&gt;ServiceType&lt;/code&gt; only registers the concrete type. By listing &lt;code&gt;JobQueue&lt;/code&gt; as supported, client code can ask the container for &lt;code&gt;JobQueue&lt;/code&gt; and they&amp;rsquo;ll get a &lt;code&gt;ProductionJobQueue&lt;/code&gt; in the production app. The  &lt;code&gt;makeService()&lt;/code&gt; method takes full advantage of being given a &lt;code&gt;Container&lt;/code&gt;: it passes in the event loop from it, the container itself, and creates a logger from the container.&lt;/p&gt;
&lt;p&gt;Finally, &lt;code&gt;ProductionJobQueue&lt;/code&gt; is registered as a service from the &lt;a href=&quot;/blog/2018/12/09/environment-configuration-in-vapor/&quot;&gt;&lt;code&gt;ProductionConfiguration&lt;/code&gt;&lt;/a&gt;. At this point, periodic jobs should work in production. But it would be nice to test them.&lt;/p&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;I spent some time thinking about what and how to test periodic jobs. I knew I wanted integration level testing, and that I&amp;rsquo;d facilitate that by building a fake implementation of &lt;code&gt;JobQueue&lt;/code&gt;. I needed a fake because waiting on timers to fire in a test isn&amp;rsquo;t a viable option, especially if they&amp;rsquo;re only firing once a day. Also, for me, integration testing meant I should be able to verify that the periodic job was both registered and it performed what it was supposed to. I considered two possible solutions.&lt;/p&gt;
&lt;p&gt;The first idea was to have a fake job queue that individual tests could manipulate the clock on. That is, a test could say &amp;ldquo;pretend two hours have elapsed&amp;rdquo; to the fake job queue, and the job queue would go look through the registered jobs and fire the ones that should have fired by then. The upside to this approach is it could be used to validate the initial and repeating delays given at registration were working. The downside is this would require a sophisticated fake that could do time calculations reliably. This would give me less confidence that I was testing production code, as opposed to testing my fake job queue.&lt;/p&gt;
&lt;p&gt;The second idea was to require each periodic job to provide a unique name. Then individual tests could ask the fake job queue to invoke a periodic job by that name. The upside is the fake is simple and predictable. The downside is jobs have to have globally unique names, which is a bit of overhead.&lt;/p&gt;
&lt;p&gt;I decided on the second option to invoke jobs by name. Because of the logging done in production, the requirement that jobs have globally unique names was already there, so the downside was moot. Additionally, the &amp;ldquo;upside&amp;rdquo; of the first option was validating the delay values. But in my case, they were always constants, so there seemed to be little value in validating them. Finally, the ease of implementing the second option was hard to ignore.&lt;/p&gt;
&lt;p&gt;This approach turned out to be easy to use in my tests. As an example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
func testRemoveExpiredChallenges() throws {
    // setup

    try app.jobQueue.execute(&quot;Accounts.cleanup&quot;, container: app.container, connection: connection)

    // validate here
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I ended up redacting all the setup and validation code for this test for succinctness, and because all of it was specific to the app and not that interesting. The only part left is invoking the periodic job on the fake job queue, which is done by passing the job name, a &lt;code&gt;Container&lt;/code&gt; and a connection to the database. The &lt;code&gt;app&lt;/code&gt; seen here is a &lt;code&gt;TestApplication&lt;/code&gt;, which I covered in a post about &lt;a href=&quot;/blog/2018/12/16/how-to-do-integration-testing-on-a-vapor-server/&quot;&gt;integration testing Swift Vapor&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Because of my selected testing approach, &lt;code&gt;TestJobQueue&lt;/code&gt; was easy to implement. Here&amp;rsquo;s how I conformed it to the &lt;code&gt;JobQueue&lt;/code&gt; protocol:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
import Foundation
import Vapor

final class TestJobQueue: JobQueue {
    struct Entry {
        let initialDelay: TimeAmount
        let delay: TimeAmount
        let name: String
        let job: Job
    }

    var schedule_wasCalled = false
    var schedule_wasCalled_withEntries = [Entry]()
    func schedule(initialDelay: TimeAmount, delay: TimeAmount, withName name: String, _ job: @escaping Job) {
        schedule_wasCalled = true
        let entry = Entry(initialDelay: initialDelay, delay: delay, name: name, job: job)
        schedule_wasCalled_withEntries.append(entry)
    }
    ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;schedule()&lt;/code&gt; method is just a recorder. It creates an entry for each scheduled job and stores it in an array. The important bits that are used later are the &lt;code&gt;name&lt;/code&gt; and &lt;code&gt;job&lt;/code&gt;. I ended up storing the &lt;code&gt;initialDelay&lt;/code&gt; and &lt;code&gt;delay&lt;/code&gt; so if a test actually wanted to validate them, they could.&lt;/p&gt;
&lt;p&gt;The other interesting piece to the &lt;code&gt;TestJobQueue&lt;/code&gt; class is the &lt;code&gt;execute()&lt;/code&gt; method that tests call when they want to fake a periodic job being triggered.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
final class TestJobQueue: JobQueue {
    ...
    func execute(_ name: String, container: Container, connection: DatabaseConnectable) throws {
        guard let entry = schedule_wasCalled_withEntries.first(where: { $0.name == name }) else {
            return
        }

        try entry.job(container, connection).wait()
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;My implementation is as simple as I could make it. It searches the array of entries looking for the first job with the matching name. If it can&amp;rsquo;t find a matching job, it silently fails. This is intentional: it mimics what would happen in production if a periodic job wasn&amp;rsquo;t properly registered. Namely, nothing would happen. It is up to the individual test cases to verify that a job&amp;rsquo;s side effects are happening. However, &lt;code&gt;execute()&lt;/code&gt; does wait on the job to complete before returning, just to make the tests simpler.&lt;/p&gt;
&lt;p&gt;The last bit needed for &lt;code&gt;TestJobQueue&lt;/code&gt; is registering it with the dependency injection system. I did it differently from the production job queue, however. &lt;code&gt;ProductionJobQueue&lt;/code&gt; conformed to &lt;code&gt;ServiceType&lt;/code&gt; because it needed access to a dependency injection container to initialize. &lt;code&gt;TestJobQueue&lt;/code&gt; doesn&amp;rsquo;t have the same requirement to instantiate. Further, it would be useful to the tests if the &lt;code&gt;TestJobQueue&lt;/code&gt; were exposed to them as that type &amp;mdash; so they can access the &lt;code&gt;execute()&lt;/code&gt; method. Otherwise they&amp;rsquo;d have to force cast a &lt;code&gt;JobQueue&lt;/code&gt; to a &lt;code&gt;TestJobQueue&lt;/code&gt;, and I find that more than a little gross.&lt;/p&gt;
&lt;p&gt;For that reason, I modified &lt;code&gt;TestingConfiguration&lt;/code&gt; to hold an exact instance:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
struct TestingConfiguration: ConfigurationType {
    ...
    let jobQueue = TestJobQueue()

    func configure(_ services: inout Services) throws {
        ...
        services.register(jobQueue, as: JobQueue.self)
        ...
    }
    ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is the &lt;code&gt;TestingConfiguration&lt;/code&gt; that I described in how I do &lt;a href=&quot;/blog/2018/12/09/environment-configuration-in-vapor/&quot;&gt;environment configuration for Swift Vapor&lt;/a&gt;. Here, it registered a member variable of type &lt;code&gt;TestJobQueue&lt;/code&gt; as a &lt;code&gt;JobQueue&lt;/code&gt;. By making it publicly available on &lt;code&gt;TestingConfiguration&lt;/code&gt;, the &lt;code&gt;TestApplication&lt;/code&gt; has easy access to it.&lt;/p&gt;
&lt;p&gt;The final piece is exposing the &lt;code&gt;TestJobQueue&lt;/code&gt; on &lt;code&gt;TestApplication&lt;/code&gt; so it&amp;rsquo;s convenient for tests to use.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
class TestApplication {
    ...
    var jobQueue: TestJobQueue {
        return configuration.jobQueue
    }
    ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Since the &lt;code&gt;TestApplication&lt;/code&gt; already has a reference to &lt;code&gt;TestingConfiguration&lt;/code&gt;, it can return that instance. The test code now works.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;My Swift Vapor app had a need to run some clean up jobs periodically. The requirements were simple: it was ok if the job ran on multiple instances or not at all, but it should make a good faith effort to run at least once. I wanted a class that reduced the necessary boilerplate for scheduling a job, while adding logging to the jobs, and being testable. I settled on &lt;code&gt;NIO&lt;/code&gt;&amp;lsquo;s &lt;code&gt;RepeatedTasks&lt;/code&gt; to implement timers to run the periodic tasks in each app instance. For testing, I kept the testing fake simple: the tests could invoke jobs by name, and then validate the side effects.&lt;/p&gt;
</description>
      <category>Programming</category>
      <category>Swift</category>
      <category>Vapor</category>
      <category>Server-side</category>
      <pubDate>Sun, 13 Jan 2019 10:13:37 -0500</pubDate>
      <guid isPermaLink="false">https://losingfight.com/blog/?p=568</guid>
      <dc:creator>Andy</dc:creator>
      <dc:date>2019-01-13T10:13:37-05:00</dc:date>
    </item>
    <item>
      <title>Building a declarative router for Swift Vapor</title>
      <link>https://losingfight.com/blog/2019/01/06/building-a-declarative-router-for-swift-vapor/</link>
      <description>&lt;p&gt;As I&amp;rsquo;ve been using &lt;a href=&quot;https://vapor.codes/&quot;&gt;Swift Vapor 3&lt;/a&gt;, one of the things that I felt could be better was the way routes were declared. So I built &lt;a href=&quot;https://github.com/andyfinnell/VaporRoutingTable&quot;&gt;a framework to meet my Vapor routing needs&lt;/a&gt;. If you&amp;rsquo;d like to try it out, &lt;a href=&quot;https://github.com/andyfinnell/VaporRoutingTable&quot;&gt;go to the Github page and checkout the README&lt;/a&gt;. For the rest of this post, I&amp;rsquo;m going to talk about what my goals were, and highlight parts of the implementation that were interesting to me.&lt;/p&gt;
&lt;p&gt;But first, to whet your appetite, here&amp;rsquo;s a tiny example of declaring routes using my framework:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
import Vapor
import RoutingTable

public func routes(_ router: Router) throws {
    let table = RoutingTable(
        .scope(&quot;api&quot;, middleware: [ApiKeyMiddleware()], children: [
            .resource(&quot;users&quot;, parameter: User.self, using: UserController.self, children: [
                .resource(&quot;sprockets&quot;, parameter: Sprocket.self, using: SprocketController.self),
                .resource(&quot;widgets&quot;, using: WidgetController.self)
            ]),
            .resource(&quot;sessions&quot;, using: SessionController.self),
            .post(&quot;do_stuff&quot;, using: StuffController.doStuff)
        ])
    )
    table.register(routes: router)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Goals&lt;/h2&gt;
&lt;p&gt;I had four goals when creating my routing framework:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;h4&gt;All routes in one file&lt;/h4&gt;
&lt;p&gt;One of the challenges I ran into was determining what all the routes in the app were and how they fit together. It is possible to print out all the routes by running a command line tool, but that didn&amp;rsquo;t help me with finding where the associated code was.&lt;/p&gt;&lt;/p&gt;
&lt;p&gt;I also attempted to take advantage of &lt;code&gt;RouteCollection&lt;/code&gt;s at one point in order to make my &lt;code&gt;routes()&lt;/code&gt; method less verbose. It did improve the verbosity, but at the expense of all the routes in one place. Ideally, I&amp;rsquo;d like to have my cake and eat it, too: all routes in one file, but expressed concisely.&lt;/p&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;h4&gt;Hierarchical declaration&lt;/h4&gt;
&lt;p&gt;Routes are hierarchical by nature, and I&amp;rsquo;d like to declare them that way. By that, I mean building a tree data type that is hierarchical in Swift syntax when declared, as opposed to calling a series of methods that build up a tree at runtime.&lt;/p&gt;&lt;/p&gt;
&lt;p&gt;I see a couple of benefits from making the route declaration hierarchical. First, it&amp;rsquo;s easier for me to see how the endpoints fit together or relate to one another. I can see the hierarchy in the code syntax itself, instead of parsing method calls to build up the hierarchy in my head. Second, it can reduce boilerplate code by inheriting configuration from the parent to the child.&lt;/p&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;h4&gt;Re-usability of controllers&lt;/h4&gt;
&lt;p&gt;By re-usability of controllers, I mean a controller can be used in more than one place in the routing hierarchy. For example, maybe a controller implements managing sprockets. It could be exposed in one place in the routing hierarchy for normal users, but also in a different place for admin users. Part of making this useful would be allowing the routing declaration to specify which controller endpoints are available at each place in the hierarchy. e.g. the admin sub-hierarchy should allow the &lt;code&gt;DELETE&lt;/code&gt;ing of sprockets, but the normal user&amp;rsquo;s sub-hierarchy shouldn&amp;rsquo;t.&lt;/p&gt;
&lt;p&gt;Being re-usable implies controllers don&amp;rsquo;t know where they are in the route hierarchy. To me, this makes sense because of my iOS/macOS background. In that context, view controllers don&amp;rsquo;t know where they appear in the app. Instead, app architecture relies on &lt;a href=&quot;http://khanlou.com/2015/10/coordinators-redux/&quot;&gt;Coordinators&lt;/a&gt; (or a similar pattern) to know when and where to display the view controllers. Because of the separation of concerns, view controllers can be re-used in multiple places of the app. I think of API/web controllers in the same way.&lt;/p&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;h4&gt;Use higher level concepts&lt;/h4&gt;
&lt;p&gt;In my experience, few things reduce boilerplate code and increase readability like the introduction of higher level concepts. In the case of routing, I&amp;rsquo;m thinking about scopes and resources.&lt;/p&gt;&lt;/p&gt;
&lt;p&gt;Scopes add the ability to group routes logically, so that the code maintainer knows they fit together to accomplish a common goal. It also means routes in a scope can inherit the same path prefix and/or middleware. Some examples of scopes could be an API scope or an admin user scope.&lt;/p&gt;&lt;/p&gt;
&lt;p&gt;Resources allow me to describe REST-like resources in a succinct way. Although resource declaration can be succinct, the code maintainer can infer a lot about it. That&amp;rsquo;s because REST-like resources are known to support certain subpaths and HTTP methods that behave in specific ways. So although fewer things are declared about a resource, more is known about it than if I had declared each route individually.&lt;/p&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;The Results&lt;/h2&gt;
&lt;p&gt;Based on these goals, I came up with an idealized version of what I wanted route declaration to look like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
scope &quot;api&quot;, [ApiMiddleware.self] {
    resource &quot;users&quot;, parameter: User.self, using: UserController.self {
        resource &quot;sprockets&quot;, using: SprocketsController.self
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What I like about the above is it has just enough punctuation and keywords to make it readable, but no more than that is unnecessary. It also makes use of curly braces to denote hierarchy. When I&amp;rsquo;m reading Swift code, curly braces make my brain think parent/child relationship in a way other punctuation doesn&amp;rsquo;t. It also seems to help make Xcode do sane things with indentation.&lt;/p&gt;
&lt;p&gt;Here I&amp;rsquo;m going to admit that much of my inspiration for what routing could be came from &lt;a href=&quot;https://phoenixframework.org/&quot;&gt;Elixir&amp;rsquo;s Phoenix framework&lt;/a&gt;, and its &lt;a href=&quot;https://hexdocs.pm/phoenix/routing.html&quot;&gt;routing library&lt;/a&gt;. I feel like its route declaration is very close to my ideal. In addition, it supports more features, including the ability to generate full URLs from a named resource.&lt;/p&gt;
&lt;p&gt;Unfortunately, I couldn&amp;rsquo;t achieve my ideal in Swift. The example I gave above isn&amp;rsquo;t valid Swift, nor was there a way to extend Swift to support it. A lot of Phoenix&amp;rsquo;s elegance and power comes from Elixir&amp;rsquo;s &lt;a href=&quot;https://en.wikipedia.org/wiki/Hygienic_macro&quot;&gt;hygienic macros&lt;/a&gt;, which Swift doesn&amp;rsquo;t have.&lt;/p&gt;
&lt;p&gt;Instead, here&amp;rsquo;s the closest I could come in Swift:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
.scope(&quot;api&quot;, middleware: [ApiKeyMiddleware()], children: [
    .resource(&quot;users&quot;, parameter: User.self, using: UserController.self, children: [
        .resource(&quot;sprockets&quot;, parameter: Sprocket.self, using: SprocketController.self)
    ]),
])
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It has a lot more punctuation and keywords than is really necessary to convey what I want. It also uses square brackets for arrays to denote hierarchy, which are a bit clumsy especially when used in Xcode. But given Swift&amp;rsquo;s limitations, I feel like it comes pretty close.&lt;/p&gt;
&lt;h2&gt;Interesting Implementation Bits&lt;/h2&gt;
&lt;p&gt;When implementing my declarative router I ran into some implementation hurdles that I thought were interesting enough to write down.&lt;/p&gt;
&lt;h3&gt;Verbosity reduction&lt;/h3&gt;
&lt;p&gt;One of my stated goals was to reduce the verbosity needed to declare all my routes. Some of the reduction came for free just by using higher level concepts like scopes and resources, and making the declarations hierarchical so common configuration could be shared. But all that space savings could be undone if I messed up the declaration API. I paid particular attention to leveraging Swift&amp;rsquo;s type inference and default parameters.&lt;/p&gt;
&lt;p&gt;I realized early on that I needed a tree that was homogenous in type, but polymorphic in behavior. There are three types that could appear in a routing declaration: a scope, a resource, and a raw endpoint (i.e. a GET, PUT, PATCH, POST, or DELETE). Each of those has its own properties, and handles registering routes differently. Of those, both scopes and resources could have children, which could themselves be scopes, resources, or raw endpoints. That left me with a couple of options.&lt;/p&gt;
&lt;p&gt;The first option that I considered was using an enum to represent the three types (scope, resource, and raw endpoint). Since Swift enums can have associated data, each value could contain all their necessary properties. However, enums had a couple of problems. First, they don&amp;rsquo;t allow default values on construction. Which means each declaration would have to specify all values even if they weren&amp;rsquo;t used. Second, eventually each enum value would have to register all the routes it represented, and since each enum type had to do that differently, there would be a giant switch statement somewhere. That didn&amp;rsquo;t seem elegant to me, so I abandoned that approach.&lt;/p&gt;
&lt;p&gt;The second option was to declare a common protocol (e.g. &lt;code&gt;Routable&lt;/code&gt;) and have scope, resource, and raw endpoint types conform to that protocol. Then I had scopes and resources declare their children to be of type &lt;code&gt;Routable&lt;/code&gt; so type homogenous trees could be built. That turned out to mostly work. The problem I ran into was the raw endpoints were more verbose than I wanted. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
Scope(&quot;api&quot;, middleware: [ApiMiddleware()], children: [
    RawEndpoint(.post, &quot;do_stuff&quot;, using: StuffController.doStuff)
])
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I felt having the typename &lt;code&gt;RawEndpoint&lt;/code&gt; in the declaration was unnecessary and uninteresting. The important bit was the HTTP method, but that was obscured by the typename. My next thought was use the HTTP method name as the typename (e.g. &lt;code&gt;Post&lt;/code&gt;, &lt;code&gt;Get&lt;/code&gt;, etc). This worked, but at a cost. First, it meant I had five different types that all did the same thing, except for one parameter. Second, the HTTP method names are common words and had to exist at the top level scope. This made me worried about typename collisions.&lt;/p&gt;
&lt;p&gt;I tried to fix those problems by adding static methods to my protocol as a shorthand way to create the raw endpoint type like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
extension Routable {
    static func get&amp;lt;T&amp;gt;(_ path: String..., using controller: T) -&amp;gt; Routable {
        return RawEndpoint(.get, path, using: controller)
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;However, when I tried to use the static methods in a declaration:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
Scope(&quot;api&quot;, middleware: [ApiMiddleware()], children: [
    .post(&quot;do_stuff&quot;, using: StuffController.doStuff) // ERROR
])
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Swift complained, seemingly because it couldn&amp;rsquo;t infer the type because the static methods were on a protocol. I could have specified the full type name to the method, but I felt that would have made the declaration too verbose. But I thought I was close to something that would work. I just needed the type inference to work on the static methods.&lt;/p&gt;
&lt;p&gt;That lead me to the final option that I actually used. My hunch was I needed use a concrete type rather than a protocol in my declaration API. That would allow me to use static methods in the declaration and Swift&amp;rsquo;s type inference would work. To put it another way, I could make this work:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
Scope(&quot;api&quot;, middleware: [ApiMiddleware()], children: [
    .post(&quot;do_stuff&quot;, using: StuffController.doStuff)
])
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If &lt;code&gt;children&lt;/code&gt; was declared to be an array of a concrete (i.e. non-protocol) type, and if &lt;code&gt;post()&lt;/code&gt; were a static method on that concrete type.&lt;/p&gt;
&lt;p&gt;The challenge now was I needed two seemingly opposed concepts. I needed each declaration item (i.e. scope, resource, raw endpoint) to be polymorphic since they each should act differently based on their type. I had achieved that via making them conform to a common protocol. However, in order to make Swift type inference happy, I needed a concrete type.&lt;/p&gt;
&lt;p&gt;So I used type erasure, kind of. I wrapped the protocol &lt;code&gt;Routable&lt;/code&gt; in a &lt;code&gt;struct&lt;/code&gt; called &lt;code&gt;AnyRoutable&lt;/code&gt;. It works like a type erasure datatype in that it implements the &lt;code&gt;Routable&lt;/code&gt; protocol by calling the methods on the &lt;code&gt;Routable&lt;/code&gt; instance it contains. This gave me a single concrete type while still allowing polymorphism.&lt;/p&gt;
&lt;p&gt;To make this work, I essentially made &lt;code&gt;AnyRoutable&lt;/code&gt; a facade to the rest of the framework. Every node in the routing tree would be declared as an &lt;code&gt;AnyRoutable&lt;/code&gt;, which could, internal to the framework, wrap the correct declaration item type. To make building an entire tree from one type possible, I added static methods on &lt;code&gt;AnyRoutable&lt;/code&gt; that created each declaration type: scope, resource, and each of the HTTP methods. For example, something like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
struct AnyRoutable {
    static func get&amp;lt;T&amp;gt;(_ path: String..., using controller: T) -&amp;gt; AnyRoutable {
        return AnyRoutable(RawEndpoint(.get, path, using: controller))
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The trick was I had the static methods deal only in &lt;code&gt;AnyRoutable&lt;/code&gt;; children were declared as them, and the return types were &lt;code&gt;AnyRoutable&lt;/code&gt;. Since all parameters and return types were a concrete type, Swift could easily infer the type, and the static methods could be called without them. Implementation wise, the static methods simply created the appropriate &lt;code&gt;Routable&lt;/code&gt; subtype, then wrapped it in &lt;code&gt;AnyRoutable&lt;/code&gt;. This had the added bonus of only needing to make &lt;code&gt;AnyRoutable&lt;/code&gt; &lt;code&gt;public&lt;/code&gt; in the framework. The &lt;code&gt;Routable&lt;/code&gt; implementations for resource, scopes, and endpoints stayed hidden.&lt;/p&gt;
&lt;p&gt;Although it took me a while to reach the final implementation, the pattern seems generally useful. It allows polymorphism in the implementation, while only exposing one concrete type to client code, which means type inference can be used. I suspect there might be other options for solving this problem. For example, I never tried a class hierarchy and I wonder if that could be made to work. However, I&amp;rsquo;m pretty happy with &lt;code&gt;AnyRoutable&lt;/code&gt; since I got a facade pattern out of it as well.&lt;/p&gt;
&lt;h3&gt;Resource reflection&lt;/h3&gt;
&lt;p&gt;After designing the API interface, the next most difficult thing was figuring out how to implement controllers that managed REST-like resources. In a nutshell, if a router declares a resource, my framework should be able to look at the implementing controller and determine what verbs (i.e. index, show, update, create, delete, new, or edit) it supports, and automatically declare those routes. I wanted this to require as little boilerplate as possible. As a bonus, I wanted to determine the verb support at compile time.&lt;/p&gt;
&lt;p&gt;I quickly realized that there would have to be some overhead no matter what, just because of the limitations of Swift. Swift has no way of asking &amp;ldquo;does this type implement this method&amp;rdquo; outside of having that type declare conformance to a protocol that requires the method. It doesn&amp;rsquo;t have a fully dynamic and reflective runtime like Objective-C, nor a &lt;a href=&quot;https://en.wikipedia.org/wiki/Structural_type_system&quot;&gt;structural type system&lt;/a&gt;. So I accepted that resource controllers would have to declare conformance to a protocol for each of the verbs it supported.&lt;/p&gt;
&lt;p&gt;But even accepting that limitation, I still wanted to determine which verbs were available at compile time. Since the controller declared conformance to a protocol, and a generic method could require parameter conformance to a protocol, for a long time I held out hope this this was possible. For example, I could do this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
func indexRoutes&amp;lt;ControllerType: ResourceIndexable&amp;gt;(_ controller: ControllerType) -&amp;gt; [Route] {
    // generate route for index verb
} 

func indexRoutes&amp;lt;ControllerType&amp;gt;(_ controller: ControllerType) -&amp;gt; [Route] {
    return []
} 

class MyController: ResourceIndexable {
}

let controller = MyController()
let routes = indexRoutes(controller) // calls the correct method
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The issue I ran into was trying to put all the verb routes together. The method that put all the routes together would have to know about all the resource verb protocols it conformed too. That&amp;rsquo;s because if the method didn&amp;rsquo;t require conformance to a verb protocol, Swift would act like it didn&amp;rsquo;t conform to that protocol regardless of it actually did or not. So for this to work, I would have to implement a generic method for every combination of the seven verb protocols that could occur. That seemed excessive to me. In the end, I simply had the code query at runtime which protocols the controller implemented.&lt;/p&gt;
&lt;p&gt;This part was interesting to me because it seems like it should be solvable problem. However, in its current state, Swift doesn&amp;rsquo;t appear able to overcome it. I do wonder if a &lt;a href=&quot;https://en.wikipedia.org/wiki/Hygienic_macro&quot;&gt;hygienic macro system&lt;/a&gt; would make it feasible.&lt;/p&gt;
&lt;h3&gt;Dependency injection woes&lt;/h3&gt;
&lt;p&gt;The next two implementation struggles relate to the implementation details of Vapor itself, and not something inherent to the issue of building a declarative router. But they still contained valuable learnings.&lt;/p&gt;
&lt;p&gt;At a base level, the router connects routes with a controller that will handle requests to that route. To make the route declaration as concise as possible, I only required the type of the controller, as opposed to a live instance that might have be constructed and/or configured. I decided I would instantiate the controller later, when registering the route, using Vapor&amp;rsquo;s dependency injection system. The problem was when it came to register the route, Vapor&amp;rsquo;s dependency injection system was in the wrong state.&lt;/p&gt;
&lt;p&gt;Vapor&amp;rsquo;s dependency injection effectively has two phases. The first phase is the setup phase, where it registers types it calls &amp;ldquo;services&amp;rdquo; which can be instantiated later, in the second phase. In the second phase, a &amp;ldquo;container&amp;rdquo; exists, and can be used to instantiate any of the service types registered in the first phase. When the router is being initialized, the system is in the setup phase, and can&amp;rsquo;t instantiate any of the controller types because there&amp;rsquo;s no container.&lt;/p&gt;
&lt;p&gt;I considered using my own custom protocol on controllers that allowed them to be constructed without a dependency injection container. However, after trying that out, it seemed surprising in that everything else uses Vapor&amp;rsquo;s DI system. Plus my custom protocol would be more restrictive; it wouldn&amp;rsquo;t be able to allow custom &lt;code&gt;init&lt;/code&gt; parameters to the controller (unless all controllers needed them), nor would it offer access to the DI system to allow construction of said parameters.&lt;/p&gt;
&lt;p&gt;In the end, I was able to defer controller allocation until the first route was actually executed. By then, containers were available. Further, Vapor&amp;rsquo;s DI system took care of caching the controller for me.&lt;/p&gt;
&lt;p&gt;This problem was interesting because I&amp;rsquo;ve run into it a few times in Vapor. I need to be on the lookout for different patterns to work around not having a DI container available when I need it. &lt;/p&gt;
&lt;h3&gt;Testing difficulties&lt;/h3&gt;
&lt;p&gt;The final issue I ran into was trying to unit test my framework. Since it&amp;rsquo;s implemented in Swift, my go to method is to define all dependencies as protocols, then for my tests to create fakes I can manipulate and observe.&lt;/p&gt;
&lt;p&gt;Unfortunately, most of the Vapor types I had to interact with weren&amp;rsquo;t easily fakeable. The big one I needed to fake was Vapor&amp;rsquo;s &lt;code&gt;Router&lt;/code&gt; protocol. Being a protocol, I thought it would be a slam dunk. Unfortunately, all the interesting methods on &lt;code&gt;Router&lt;/code&gt; were in protocol extensions, meaning my testing fakes could not override those methods.&lt;/p&gt;
&lt;p&gt;What I ended up doing was defining my own protocol for the methods on &lt;code&gt;Router&lt;/code&gt; that I used, then using that everywhere in my code. Since the methods were declared in the protocol, they were overridable by my testing fakes. This allowed me to do the unit testing I wanted. That only left the issue of how to use Vapor&amp;rsquo;s &lt;code&gt;Router&lt;/code&gt; in the non-testing version of the framework.&lt;/p&gt;
&lt;p&gt;Indirection solves a lot of problems, this being another example. I declared a concrete type that conformed to my router protocol that my framework could use. I then had it wrap a Vapor &lt;code&gt;Router&lt;/code&gt;, and implement the protocol by calling the corresponding methods on &lt;code&gt;Router&lt;/code&gt;. Then, at the top level object, I hid the wrapping of &lt;code&gt;Router&lt;/code&gt; behind a helper method, so it looked like my framework dealt with &lt;code&gt;Router&lt;/code&gt;s natively.&lt;/p&gt;
&lt;p&gt;The lesson I take from this is testing when relying on 3rd party frameworks is hard. Unit testing with UIKit and AppKit types is no different. Also, defining my own protocol and wrapping a 3rd party protocol in a concrete type to conform to it seems like a repeatable strategy.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;When using Swift Vapor&amp;rsquo;s routing API, I discovered I wanted a few more things than it offered. Namely, I wanted all routes declared in one file, a hierarchal declaration, re-usability of controllers, and higher level concepts like scopes and resources. In building a framework to support these concepts, I ran into a few implementation concerns. The first was learning to design an API in such a way to reduce verbosity. The others were trying to determining protocol conformance at compile time, working around two-stage dependency injection limitations, and trying to test my code while not having fakeable protocols from 3rd party frameworks.&lt;/p&gt;
</description>
      <category>Programming</category>
      <category>Swift</category>
      <category>Vapor</category>
      <category>Server-side</category>
      <pubDate>Sun, 06 Jan 2019 10:59:23 -0500</pubDate>
      <guid isPermaLink="false">https://losingfight.com/blog/?p=567</guid>
      <dc:creator>Andy</dc:creator>
      <dc:date>2019-01-06T10:59:23-05:00</dc:date>
    </item>
    <item>
      <title>Sending email from Swift Vapor</title>
      <link>https://losingfight.com/blog/2018/12/30/sending-email-from-swift-vapor/</link>
      <description>&lt;p&gt;Like most services these days, my &lt;a href=&quot;https://vapor.codes/&quot;&gt;Vapor&lt;/a&gt; side project needs to send welcome emails when a user signs up for the service. While I could write my own SMTP client, it would still require &lt;a href=&quot;https://blog.codinghorror.com/so-youd-like-to-send-some-email-through-code/&quot;&gt;a lot of DNS setup to make sure those emails made it through various spam countermeasures&lt;/a&gt;. Given this is a side project, and sending email is a minor component of it, that didn&amp;rsquo;t seem worthwhile to me. So I decided to use a 3rd party service who would take care of all of that.&lt;/p&gt;
&lt;p&gt;I chose &lt;a href=&quot;https://www.mailgun.com/&quot;&gt;Mailgun&lt;/a&gt; for a couple of reasons:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;I&amp;rsquo;m hosting my side project on &lt;a href=&quot;https://www.heroku.com/&quot;&gt;Heroku&lt;/a&gt;, and they provide a convenient Mailgun add on that I can provision.&lt;/li&gt;
&lt;li&gt;Mailgun offers a free tier, appropriate for my side project&lt;/li&gt;
&lt;li&gt;There&amp;rsquo;s already a &lt;a href=&quot;https://github.com/twof/VaporMailgunService&quot;&gt;Swift package for Mailgun&amp;rsquo;s API&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The Swift package for Mailgun got me most of the way there. However, I still needed a bit of infrastructure to render the emails, and then to validate the emails were correctly sent in my integration tests.&lt;/p&gt;
&lt;p&gt;In this post I&amp;rsquo;m going to cover how I went about generating the email content, sending the email to Mailgun, and finally how I ensured I could test it all. I&amp;rsquo;m not going to cover how to set up Mailgun and all the DNS stuff because that&amp;rsquo;s very app specific, and is documented in Mailgun&amp;rsquo;s docs already.&lt;/p&gt;
&lt;h2&gt;Example use&lt;/h2&gt;
&lt;p&gt;I find it helpful when building a subsystem to sketch out what the use site will look like. It helps me determine if I&amp;rsquo;m building something that will meet my needs, and gives me a concrete target to build toward. With that in mind, I thought the ideal for my project was to define an email template for each kind of email I wanted to send, have a method that could render that down to a final email to send, then send it via an abstract email delivery service. The email body allows both text and html, and the body template was defined in &lt;a href=&quot;https://github.com/vapor/leaf&quot;&gt;Leaf&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s how that looked in code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
struct WelcomeData: Encodable {
    let verifyLink: String

    init(user: User) {
        self.verifyLink = &quot;myapp://verify/\(user.verifyToken)&quot;
    }
}
...
let template = EmailTemplate(from: &quot;donotreply@myapp.com&quot;,
                             to: email,
                             subject: &quot;Welcome to MyApp!&quot;,
                             bodyTemplate: &quot;WelcomeEmail&quot;)
let welcomeData = WelcomeData(user: user)
return template.render(welcomeData, on: container).flatMap { message -&amp;gt; Future&amp;lt;Void&amp;gt; in
    let deliveryService = try container.make(EmailDeliveryService.self)
    return deliveryService.send(message, on: container)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The first step is to create the &lt;code&gt;EmailTemplate&lt;/code&gt; for the email I want to send and render it. The &lt;code&gt;from&lt;/code&gt;, &lt;code&gt;to&lt;/code&gt;, and &lt;code&gt;subject&lt;/code&gt; properties are &lt;code&gt;String&lt;/code&gt;s that will be passed through unchanged to the final email. The &lt;code&gt;bodyTemplate&lt;/code&gt; is the base name for the Leaf templates that will be rendered in the &lt;code&gt;render()&lt;/code&gt; method. &lt;code&gt;WelcomeData&lt;/code&gt; is the Leaf context for the templates; it defines anything that the the Leaf template will need. I like to think of it as a &lt;a href=&quot;https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93viewmodel&quot;&gt;view model&lt;/a&gt;. It takes a model object and transforms it into values that the view (i.e. the Leaf template) needs. In this example, the WelcomeEmail template needs an email verification link, so &lt;code&gt;WelcomeData&lt;/code&gt; constructs that based on a token assumed to be on the &lt;code&gt;User&lt;/code&gt; model. To render the &lt;code&gt;EmailTemplate&lt;/code&gt; into something that can be sent, &lt;code&gt;render()&lt;/code&gt; is called, passing in &lt;code&gt;WelcomeData&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The second step is to send the resulting &lt;code&gt;EmailMessage&lt;/code&gt;. The dependency injection framework is asked to produce a &lt;code&gt;EmailDeliveryService&lt;/code&gt; object, which can send an &lt;code&gt;EmailMessage&lt;/code&gt;. &lt;code&gt;EmailDeliveryService&lt;/code&gt; is a protocol, meaning it can be swapped out later, without the client code knowing or caring. This enables testing fakes to be injected during tests, as well as making it possible to move to a new email service should I ever decide to do that.&lt;/p&gt;
&lt;p&gt;That covers the Swift code for creating and sending the email. I still need to define the Leaf templates though. I want to send both plain text and HTML MIME parts in my email, so regardless of the user&amp;rsquo;s email app they&amp;rsquo;ll see something reasonable. Since the email body template parts are Leaf templates, I put them in the standard location: &lt;code&gt;Resources/Views&lt;/code&gt;. I also follow a naming convention so &lt;code&gt;EmailTemplate.render()&lt;/code&gt; can find them at runtime.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s the contents of &lt;code&gt;WelcomeEmail.html.leaf&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;p&amp;gt;Hello!&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Welcome to MyApp!&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;&amp;lt;a href=&quot;#(verifyLink)&quot;&amp;gt;Verify your email address&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;The MyApp Team.&amp;lt;/p&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the contents of &lt;code&gt;WelcomeEmail.text.leaf&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
Hello!

Welcome to MyApp!

Verify your email address by clicking on this link: #(verifyLink)

The MyApp Team.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Both templates represent the same email, but the content changes based on the format they&amp;rsquo;re being rendered into. The &lt;code&gt;#(verifyLink)&lt;/code&gt; placeholder is filled in with value in &lt;code&gt;WelcomeData.verifyLink&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Now that I&amp;rsquo;ve defined my target API, I can start building the implementation.&lt;/p&gt;
&lt;h2&gt;Rendering email with Leaf&lt;/h2&gt;
&lt;p&gt;First I need to define what an email message is, because it is the type everything else is dependent on. The &lt;code&gt;EmailTemplate&lt;/code&gt; needs to render to it, and &lt;code&gt;EmailDeliveryService&lt;/code&gt; needs to send it. I decided to define my own types for this because it reduces coupling on a specific service, plus it more accurately represents what my app thinks an email is. Also, the necessary types are pretty simple, so I did&amp;rsquo;t think they&amp;rsquo;d increase my maintenance burden any.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s my definition:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
struct EmailBody {
    let text: String
    let html: String
}

struct EmailMessage {
    let from: String
    let to: String
    let subject: String
    let body: EmailBody
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;My app&amp;rsquo;s idea of an email is simple. It has a &lt;code&gt;from&lt;/code&gt;, &lt;code&gt;to&lt;/code&gt;, &lt;code&gt;subject&lt;/code&gt;, and &lt;code&gt;body&lt;/code&gt; fields. The only thing that might look out of the ordinary is the the &lt;code&gt;body&lt;/code&gt; has two parts: HTML and plain text. My app doesn&amp;rsquo;t care about attachments or other features, so they don&amp;rsquo;t show up here.&lt;/p&gt;
&lt;p&gt;With email defined, I could create the &lt;code&gt;EmailTemplate&lt;/code&gt; which takes care of rendering Leaf templates down to a &lt;code&gt;EmailMessage&lt;/code&gt;. I started by defining the properties of the &lt;code&gt;EmailTemplate&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
import Vapor
import Leaf
import TemplateKit

struct EmailTemplate {
    private let from: String
    private let to: String
    private let subject: String
    private let bodyTemplate: String

    init(from: String, to: String, subject: String, bodyTemplate: String) {
        self.from = from
        self.to = to
        self.subject = subject
        self.bodyTemplate = bodyTemplate
    }
    ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The template is the same as the &lt;code&gt;EmailMessage&lt;/code&gt; with the exception of &lt;code&gt;bodyTemplate&lt;/code&gt;, which is the base name of the Leaf templates for the email body. Most of the work of &lt;code&gt;EmailTemplate&lt;/code&gt; is to convert the &lt;code&gt;bodyTemplate&lt;/code&gt; into a &lt;code&gt;EmailBody&lt;/code&gt;. The top level render method looks like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
struct EmailTemplate {
    ...
    private static let htmlExtension = &quot;.html&quot;
    private static let textExtension = &quot;.text&quot;

    func render&amp;lt;E&amp;gt;(_ context: E, on container: Container) -&amp;gt; Future&amp;lt;EmailMessage&amp;gt; where E: Encodable {
        let htmlRender = render(bodyTemplate + EmailTemplate.htmlExtension, context, on: container)
        let textRender = render(bodyTemplate + EmailTemplate.textExtension, context, on: container)
        return htmlRender.and(textRender)
            .map { EmailBody(text: $1, html: $0) }
            .map { EmailMessage(from: self.from, to: self.to, subject: self.subject, body: $0) }
    }
    ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;render()&lt;/code&gt; method takes the Leaf template context and a dependency injection container, and returns the promise of an &lt;code&gt;EmailMessage&lt;/code&gt;. The implementation relies on a helper &lt;code&gt;render()&lt;/code&gt; method that renders one Leaf template at a time. This top level &lt;code&gt;render()&lt;/code&gt; calls it twice: once for the plain text template, and once for the html template. It uses the &lt;code&gt;and&lt;/code&gt; operator to let the template renders run concurrently if possible, then combines the results into an &lt;code&gt;EmailBody&lt;/code&gt;, before a final &lt;code&gt;map&lt;/code&gt; that mixes in the &lt;code&gt;from&lt;/code&gt;, &lt;code&gt;to&lt;/code&gt;, and &lt;code&gt;subject&lt;/code&gt; fields.&lt;/p&gt;
&lt;p&gt;The helper &lt;code&gt;render()&lt;/code&gt; method is similarly straight forward:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
enum EmailError: Error {
    case invalidStringEncoding
    case emailProviderNotConfigured
}
...
struct EmailTemplate {
    ...
    private func render&amp;lt;E&amp;gt;(_ name: String, _ context: E, on container: Container) -&gt; Future&amp;lt;String&amp;gt; where E: Encodable {
        do {
            let leaf = try container.make(LeafRenderer.self)
            return leaf.render(name, context).map { view in
                guard let str = String(data: view.data, encoding: .utf8) else {
                    throw EmailError.invalidStringEncoding
                }
                return str
            }
        } catch let error {
            return container.future(error: error)
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The helper method here takes the full Leaf template name, its context, a dependency injection container and returns a promise of &lt;code&gt;String&lt;/code&gt;, which is the fully rendered body. To achieve this, it creates a &lt;code&gt;LeafRenderer&lt;/code&gt; and asks it to render the template. This results in view data, which it decodes into a &lt;code&gt;String&lt;/code&gt; and returns. If any error is thrown, it&amp;rsquo;ll convert it into a rejected promise for convenience.&lt;/p&gt;
&lt;p&gt;The email template rendering is fairly simple, but creating the &lt;code&gt;EmailTemplate&lt;/code&gt; type reduces the boilerplate code needed for sending an email.&lt;/p&gt;
&lt;h2&gt;Sending email&lt;/h2&gt;
&lt;p&gt;I now have a fully rendered email message, and I need to send it. As I mentioned up top, I&amp;rsquo;m used a 3rd party Swift package to actually talk to Mailgun&amp;rsquo;s API. However, I wanted an easy way to inject testing fakes, and the ability to swap out email services later if necessary. So I&amp;rsquo;m first going to show how I integrated the Swift Mailgun package, then how I abstracted it with a generic interface that can be faked.&lt;/p&gt;
&lt;p&gt;Since it&amp;rsquo;s a Swift package, I added it to my &lt;code&gt;Package.swift&lt;/code&gt; file:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
    dependencies: [
        ...
        .package(url: &quot;https://github.com/twof/VaporMailgunService.git&quot;, from: &quot;1.1.0&quot;),
        ...
    ],
    ...
    targets: [
        ...
        .target(name: &quot;App&quot;, dependencies: [
            ...
            &quot;Mailgun&quot;,
            ...
            ]),
        ...
    ]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Running &lt;code&gt;vapor update&lt;/code&gt; from the command line pulled down the package and updated all my dependencies. I decided to use a &lt;code&gt;Provider&lt;/code&gt; to set up the Mailgun package in my app:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
import Vapor
import Mailgun

struct MailgunProvider: Provider {
    private let config: MailgunConfigurationType

    init(mailgunConfig: MailgunConfigurationType) {
        self.config = mailgunConfig
    }

    func register(_ services: inout Services) throws {
        services.register(Mailgun(apiKey: config.apiKey, domain: config.domain), as: EmailDeliveryService.self)
    }

    func didBoot(_ container: Container) throws -&gt; EventLoopFuture&amp;lt;Void&amp;gt; {
        return .done(on: container)
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There&amp;rsquo;s not much to this. The only interesting bit is the &lt;code&gt;register()&lt;/code&gt; implementation. It registers the &lt;code&gt;Mailgun&lt;/code&gt; service from the &lt;code&gt;Mailgun&lt;/code&gt; framework as the implementation for the &lt;code&gt;EmailDeliveryService&lt;/code&gt; protocol. It uses &lt;code&gt;apiKey&lt;/code&gt; and &lt;code&gt;domain&lt;/code&gt; fields from the configuration passed in, which will come from the appropriate &lt;a href=&quot;/blog/2018/12/09/environment-configuration-in-vapor/&quot;&gt;environment configuration&lt;/a&gt;. In my case, since I&amp;rsquo;m using Heroku, the production environment configuration will pull from the &lt;code&gt;MAILGUN_API_KEY&lt;/code&gt; and &lt;code&gt;MAILGUN_DOMAIN&lt;/code&gt; environment variables. Additionally, the production configuration will take care of registering this provider.&lt;/p&gt;
&lt;p&gt;I decided to use a provider pattern for the sake of the testing configuration. The production provider here doesn&amp;rsquo;t really need to be a provider; it only registers one service. But since the testing configuration does make full use of the &lt;code&gt;Provider&lt;/code&gt; protocol, I decided to make the production configuration follow suite.&lt;/p&gt;
&lt;p&gt;Now that I had Mailgun in my app, I needed to put it behind a generic protocol so all the client code could be agnostic about the email service being used. I started by defining a simple protocol:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
import Vapor

protocol EmailDeliveryService: Service {
    func send(_ message: EmailMessage, on container: Container) -&amp;gt; Future&amp;lt;Void&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;An &lt;code&gt;EmailDeliveryService&lt;/code&gt; is a &lt;code&gt;Service&lt;/code&gt; (in the dependency injection sense) that implements a &lt;code&gt;send()&lt;/code&gt; method. The &lt;code&gt;send()&lt;/code&gt; method takes an &lt;code&gt;EmailMessage&lt;/code&gt; and returns a &lt;code&gt;Void&lt;/code&gt; promise, which can be used to know if the send succeeded or failed.&lt;/p&gt;
&lt;p&gt;For the final bit of sending an email, I need to conform the &lt;code&gt;Mailgun&lt;/code&gt; service to my generic &lt;code&gt;EmailDeliveryService&lt;/code&gt; protocol:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
import Vapor
import Mailgun

extension Mailgun: EmailDeliveryService {
    func send(_ message: EmailMessage, on container: Container) -&amp;gt; Future&amp;lt;Void&amp;gt; {
        do {
            let mailgunMessage = Mailgun.Message(
                from: message.from,
                to: message.to,
                subject: message.subject,
                text: message.body.text,
                html: message.body.html
            )

            return try self.send(mailgunMessage, on: container).transform(to: ())
        } catch let error {
            return container.future(error: error)
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The implementation is intentionally as thin as possible. This is partly because it&amp;rsquo;s hard to test protocol extensions. If I had needed anything more complicated, I would have opted to wrap &lt;code&gt;Mailgun&lt;/code&gt; in another type that conformed to &lt;code&gt;EmailDeliveryService&lt;/code&gt;. In any case, this simply converts my &lt;code&gt;EmailMessage&lt;/code&gt; type into Mailgun&amp;rsquo;s version and sends it. It also wraps any thrown errors into a rejected promise for the convenience of any calling code.&lt;/p&gt;
&lt;p&gt;And, with that, my app is now sending email via Mailgun! But is it sending the correct emails? Well&amp;hellip;&lt;/p&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;The goal of a couple of design decisions was to make the testing of emails possible, or at least easier. The choice of abstracting out the email service into a generic protocol means I can inject a testing fake. Making the email template rendering separate from the email sending means I can still test the template rendering, even if I swap out the email service with a fake. &lt;/p&gt;
&lt;p&gt;For my integration testing, I didn&amp;rsquo;t actually want to send any emails to Mailgun. That means my tests aren&amp;rsquo;t full integration tests, and won&amp;rsquo;t catch a misconfigured Mailgun setup. But I didn&amp;rsquo;t want my integration tests dependent on an external, non-local service to run; that would make them too flaky. Plus I&amp;rsquo;d likely run into an Mailgun API quota pretty quick. However, even with this limitation, I was able to verify that the correct emails got sent at the correct time.&lt;/p&gt;
&lt;p&gt;Like with building the initial email types, I prefer to start out with what a final test might look like. Here&amp;rsquo;s a simplified test from my app that validates a welcome email was sent:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
func testCreate_emailShouldSend() throws {
    app.emailDeliveryService.send_stubbed?.succeed()
    ...
    // Do something that should send an email
    ...
    XCTAssertTrue(app.emailDeliveryService.send_wasCalled)
    XCTAssertEqual(app.emailDeliveryService.send_wasCalled_withMessage!.to, &quot;bob.jimbob@example.com&quot;)
    XCTAssertEqual(app.emailDeliveryService.send_wasCalled_withMessage!.from, &quot;donotreply@myapp.com&quot;)
    XCTAssertEqual(app.emailDeliveryService.send_wasCalled_withMessage!.subject, &quot;Welcome to MyApp!&quot;)

    let link = &quot;myapp://verify/\(user!.verifyToken)&quot;
    XCTAssertTrue(app.emailDeliveryService.send_wasCalled_withMessage!.body.html.contains(link))
    XCTAssertTrue(app.emailDeliveryService.send_wasCalled_withMessage!.body.text.contains(link))
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The first line tells the email service testing fake that the next call to &lt;code&gt;send()&lt;/code&gt; should return success. Next the test calls into the app in a way that should send a welcome email (as represented by the comment). The final lines assert that send was called, and with the correct parameters. The test also validates that the most important piece of information &amp;mdash; the verify link &amp;mdash; appears in both the plain text and HTML parts of the email message. I didn&amp;rsquo;t do a full text comparison because most of the body is static content, and comparing all of it makes the test more fragile than it needs to be.&lt;/p&gt;
&lt;p&gt;With this test written, I can work backwards and define what my email service testing fake should implement.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
import Vapor
import Mailgun

final class FakeEmailDeliveryService: EmailDeliveryService {
    var send_wasCalled = false
    var send_wasCalled_withMessage: EmailMessage?
    var send_stubbed: Promise&amp;lt;Void&amp;gt;?
    func send(_ message: EmailMessage, on container: Container) -&amp;gt; Future&amp;lt;Void&amp;gt; {
        send_wasCalled = true
        send_wasCalled_withMessage = message
        return send_stubbed!.futureResult
    }
    ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The testing fake, &lt;code&gt;FakeEmailDeliveryService&lt;/code&gt;, records if &lt;code&gt;send()&lt;/code&gt; was called along with the &lt;code&gt;EmailMessage&lt;/code&gt; it was called with. It only keeps track of the last message because my tests only send one at a time. The fake also has the ability to return a stubbed value from &lt;code&gt;send()&lt;/code&gt;. This is useful for validating what happens if there&amp;rsquo;s a failure on the email service&amp;rsquo;s end. The fake &lt;code&gt;send()&lt;/code&gt; assumes that the stubbed promise has been allocated elsewhere before it&amp;rsquo;s invoked.&lt;/p&gt;
&lt;p&gt;Speaking of allocating the stubbed promise, there&amp;rsquo;s a bit of cleanup that&amp;rsquo;s required because of the way Vapor&amp;rsquo;s promises work:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
final class FakeEmailDeliveryService: EmailDeliveryService {
    ...
    deinit {
        // Vapor does not like a promise created but not resolved before it is destroyed. It calls them &quot;leaked&quot; and crashes the tests. So make sure nothing is &quot;leaked&quot; in our tests.
        send_stubbed?.succeed()
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As the comment states, Vapor will crash a test if there are any promises left unresolved. This happens in any of my tests that don&amp;rsquo;t exercise the email functionality of the app. I could go through all of those tests and add code to resolve the &lt;code&gt;send_stubbed&lt;/code&gt; promise, but that&amp;rsquo;d be verbose and tedious. Instead, I opted to have &lt;code&gt;deinit&lt;/code&gt; forcefully resolve the promise if it hasn&amp;rsquo;t already been.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;FakeEmailDeliveryService&lt;/code&gt; needs to be registered with the dependency injection system so that code asking for a &lt;code&gt;EmailDeliveryService&lt;/code&gt; will get an instance of it. As with the production version of &lt;code&gt;EmailDeliveryService&lt;/code&gt;, I used a &lt;code&gt;Provider&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
struct TestMailProvider: Provider {
    var emailDeliveryService = FakeEmailDeliveryService()

    func register(_ services: inout Services) throws {
        services.register(emailDeliveryService, as: EmailDeliveryService.self)
    }

    func didBoot(_ container: Container) throws -&gt; EventLoopFuture&amp;lt;Void&amp;gt; {
        emailDeliveryService.send_stubbed = container.eventLoop.newPromise()
        return .done(on: container)
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The first thing the provider does is create the &lt;code&gt;FakeEmailDeliveryService&lt;/code&gt; and stash in a public member variable. It does this so tests can get ahold of it and validate the &lt;code&gt;send()&lt;/code&gt; parameters, or resolve its return value. The &lt;code&gt;register()&lt;/code&gt; method then registers the fake as the implementation of &lt;code&gt;EmailDeliveryService&lt;/code&gt;. The &lt;code&gt;didBoot()&lt;/code&gt; method takes care of creating the unresolved promise for &lt;code&gt;send()&lt;/code&gt;&amp;lsquo;s stubbed return value. Creating promises require an event loop, and &lt;code&gt;didBoot()&lt;/code&gt; is the earliest place in the test code that I had access to one. I chose to allocate the stubbed promise this early because it allowed tests to assume its existence during set up without worrying about race conditions.&lt;/p&gt;
&lt;p&gt;With the registering of &lt;code&gt;TestMailProvider&lt;/code&gt; all of testing fakes are set up and ready to be used. However, &lt;code&gt;FakeEmailDeliveryService&lt;/code&gt; wasn&amp;rsquo;t yet accessible to the test cases, which were expecting it as a property on &lt;a href=&quot;/blog/2018/12/16/how-to-do-integration-testing-on-a-vapor-server/&quot;&gt;&lt;code&gt;TestApplication&lt;/code&gt;&lt;/a&gt; called &lt;code&gt;emailDeliveryService&lt;/code&gt;. The rest of this section is showing the plumbing of &lt;code&gt;TestMailProvider.emailDeliveryService&lt;/code&gt; property up through to &lt;code&gt;TestApplication&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I started at the &lt;a href=&quot;/blog/2018/12/09/environment-configuration-in-vapor/&quot;&gt;&lt;code&gt;TestingConfiguration&lt;/code&gt;&lt;/a&gt; level, which is where the &lt;code&gt;TestMailProvider&lt;/code&gt; is created and registered:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
struct TestingConfiguration: ConfigurationType {
    ...
    let mailProvider = TestMailProvider()

    func configure(_ services: inout Services) throws {
        try services.register(mailProvider)
    }
    ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This exposes &lt;code&gt;TestMailProvider&lt;/code&gt; on the &lt;code&gt;TestConfiguration&lt;/code&gt;, which &lt;code&gt;TestApplication&lt;/code&gt; can then use:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
class TestApplication {
    ...
    private let configuration: TestingConfiguration
    ...
    var emailDeliveryService: FakeEmailDeliveryService {
        return configuration.mailProvider.emailDeliveryService
    }
    ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And now my tests could validate emails by using the &lt;code&gt;FakeEmailDeliveryService&lt;/code&gt; exposed on &lt;code&gt;TestApplication&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;My Vapor side project needed to send emails on user registration, which could potentially be a complicated setup. Since email isn&amp;rsquo;t a major feature of my app, it made sense to delegate sending emails out to a third party service like Mailgun. Although there&amp;rsquo;s a convenient Mailgun Swift package, I still needed to build out infrastructure for rendering emails from Leaf templates and abstracting out the emailing sending so I can test my app&amp;rsquo;s email handling. &lt;/p&gt;
</description>
      <category>Programming</category>
      <category>Swift</category>
      <category>Vapor</category>
      <category>Server-side</category>
      <pubDate>Sun, 30 Dec 2018 09:37:11 -0500</pubDate>
      <guid isPermaLink="false">https://losingfight.com/blog/?p=566</guid>
      <dc:creator>Andy</dc:creator>
      <dc:date>2018-12-30T09:37:11-05:00</dc:date>
    </item>
    <generator>Postword 1.0</generator>
  </channel>
</rss>