Swiftpack.co - Package - apple/swift-nio

sswg:graduated|104x20

SwiftNIO

SwiftNIO is a cross-platform asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients.

It's like Netty, but written for Swift.

Repository organization

The SwiftNIO project is split across multiple repositories:

Repository | NIO 2 (Swift 5+) | NIO 1 (Swift 4+) --- | --- | --- https://github.com/apple/swift-nio
SwiftNIO core | from: "2.0.0" | from: "1.0.0" https://github.com/apple/swift-nio-ssl
TLS (SSL) support | from: "2.0.0" | from: "1.0.0" https://github.com/apple/swift-nio-http2
HTTP/2 support | from: "1.0.0" | from: "0.1.0" https://github.com/apple/swift-nio-extras
useful additions around SwiftNIO | from: "1.0.0" | from: "0.1.0" https://github.com/apple/swift-nio-transport-services
first-class support for macOS, iOS, and tvOS | from: "1.0.0" | from: "0.1.0"

Protocol Implementations

Below you can find a list of a few protocol implementations that are done with SwiftNIO. This is a non-exhaustive list of protocols that are either part of the SwiftNIO project or are accepted into the SSWG's incubation process. All of the libraries listed below do all of their I/O in a non-blocking fashion using SwiftNIO.

Low-level protocol implementations

Low-level protocol implementations are often a collection of ChannelHandlers that implement a protocol but still require the user to have a good understanding of SwiftNIO. Often, low-level protocol implementations will then be wrapped in high-level libraries with a nicer, more user-friendly API.

Protocol | Client | Server | Repository | Module | Comment --- | --- | --- | --- | --- | --- HTTP/1 | ✅| ✅ | apple/swift-nio | NIOHTTP1 | official NIO project HTTP/2 | ✅| ✅ | apple/swift-nio-http2 | NIOHTTP2 | official NIO project WebSocket | ✅| ✅ | apple/swift-nio | NIOWebSocket | official NIO project TLS | ✅ | ✅ | apple/swift-nio-ssl | NIOSSL | official NIO project

High-level implementations

High-level implementations are usually libraries that come with an API that doesn't expose SwiftNIO's ChannelPipeline and can therefore be used with very little (or no) SwiftNIO-specific knowledge. The implementations listed below do still do all of their I/O in SwiftNIO and integrate really well with the SwiftNIO ecosystem.

Protocol | Client | Server | Repository | Module | Comment --- | --- | --- | --- | --- | --- HTTP | ✅| ❌ | swift-server/async-http-client | AsyncHTTPClient | SSWG community project gRPC | ✅| ✅ | grpc/grpc-swift | GRPC | also offers a low-level API; SSWG community project APNS | ✅ | ❌ | kylebrowning/APNSwift | APNSwift | SSWG community project PostgreSQL | ✅ | ❌ | vapor/postgres-nio | PostgresNIO | SSWG community project Redis | ✅ | ❌ | mordil/swift-redi-stack | RediStack | SSWG community project

Supported Platforms

SwiftNIO aims to support all of the platforms where Swift is supported. Currently, it is developed and tested on macOS and Linux, and is known to support the following operating system versions:

Swift versions

SwiftNIO 1

The latest released SwiftNIO 1 version supports Swift 4.0, 4.1, 4.2, and 5.0.

SwiftNIO 2

The latest released SwiftNIO 2 version supports only Swift 5.0, 5.1, and 5.2. If you have a SwiftNIO 1 application or library that you would like to migrate to SwiftNIO 2, please check out the migration guide we prepared for you.

Compatibility

SwiftNIO follows SemVer 2.0.0 with a separate document declaring SwiftNIO's Public API.

What this means for you is that you should depend on SwiftNIO with a version range that covers everything from the minimum SwiftNIO version you require up to the next major version. In SwiftPM that can be easily done specifying for example from: "2.0.0" meaning that you support SwiftNIO in every version starting from 2.0.0 up to (excluding) 3.0.0. SemVer and SwiftNIO's Public API guarantees should result in a working program without having to worry about testing every single version for compatibility.

Conceptual Overview

SwiftNIO is fundamentally a low-level tool for building high-performance networking applications in Swift. It particularly targets those use-cases where using a "thread-per-connection" model of concurrency is inefficient or untenable. This is a common limitation when building servers that use a large number of relatively low-utilization connections, such as HTTP servers.

To achieve its goals SwiftNIO extensively uses "non-blocking I/O": hence the name! Non-blocking I/O differs from the more common blocking I/O model because the application does not wait for data to be sent to or received from the network: instead, SwiftNIO asks for the kernel to notify it when I/O operations can be performed without waiting.

SwiftNIO does not aim to provide high-level solutions like, for example, web frameworks do. Instead, SwiftNIO is focused on providing the low-level building blocks for these higher-level applications. When it comes to building a web application, most users will not want to use SwiftNIO directly: instead, they'll want to use one of the many great web frameworks available in the Swift ecosystem. Those web frameworks, however, may choose to use SwiftNIO under the covers to provide their networking support.

The following sections will describe the low-level tools that SwiftNIO provides, and provide a quick overview of how to work with them. If you feel comfortable with these concepts, then you can skip right ahead to the other sections of this README.

Basic Architecture

The basic building blocks of SwiftNIO are the following 8 types of objects:

All SwiftNIO applications are ultimately constructed of these various components.

EventLoops and EventLoopGroups

The basic I/O primitive of SwiftNIO is the event loop. The event loop is an object that waits for events (usually I/O related events, such as "data received") to happen and then fires some kind of callback when they do. In almost all SwiftNIO applications there will be relatively few event loops: usually only one or two per CPU core the application wants to use. Generally speaking event loops run for the entire lifetime of your application, spinning in an endless loop dispatching events.

Event loops are gathered together into event loop groups. These groups provide a mechanism to distribute work around the event loops. For example, when listening for inbound connections the listening socket will be registered on one event loop. However, we don't want all connections that are accepted on that listening socket to be registered with the same event loop, as that would potentially overload one event loop while leaving the others empty. For that reason, the event loop group provides the ability to spread load across multiple event loops.

In SwiftNIO today there is one EventLoopGroup implementation, and two EventLoop implementations. For production applications there is the MultiThreadedEventLoopGroup, an EventLoopGroup that creates a number of threads (using the POSIX pthreads library) and places one SelectableEventLoop on each one. The SelectableEventLoop is an event loop that uses a selector (either kqueue or epoll depending on the target system) to manage I/O events from file descriptors and to dispatch work. Additionally, there is the EmbeddedEventLoop, which is a dummy event loop that is used primarily for testing purposes.

EventLoops have a number of important properties. Most vitally, they are the way all work gets done in SwiftNIO applications. In order to ensure thread-safety, any work that wants to be done on almost any of the other objects in SwiftNIO must be dispatched via an EventLoop. EventLoop objects own almost all the other objects in a SwiftNIO application, and understanding their execution model is critical for building high-performance SwiftNIO applications.

Channels, Channel Handlers, Channel Pipelines, and Channel Contexts

While EventLoops are critical to the way SwiftNIO works, most users will not interact with them substantially beyond asking them to create EventLoopPromises and to schedule work. The parts of a SwiftNIO application most users will spend the most time interacting with are Channels and ChannelHandlers.

Almost every file descriptor that a user interacts with in a SwiftNIO program is associated with a single Channel. The Channel owns this file descriptor, and is responsible for managing its lifetime. It is also responsible for processing inbound and outbound events on that file descriptor: whenever the event loop has an event that corresponds to a file descriptor, it will notify the Channel that owns that file descriptor.

Channels by themselves, however, are not useful. After all, it is a rare application that doesn't want to do anything with the data it sends or receives on a socket! So the other important part of the Channel is the ChannelPipeline.

A ChannelPipeline is a sequence of objects, called ChannelHandlers, that process events on a Channel. The ChannelHandlers process these events one after another, in order, mutating and transforming events as they go. This can be thought of as a data processing pipeline; hence the name ChannelPipeline.

All ChannelHandlers are either Inbound or Outbound handlers, or both. Inbound handlers process "inbound" events: events like reading data from a socket, reading socket close, or other kinds of events initiated by remote peers. Outbound handlers process "outbound" events, such as writes, connection attempts, and local socket closes.

Each handler processes the events in order. For example, read events are passed from the front of the pipeline to the back, one handler at a time, while write events are passed from the back of the pipeline to the front. Each handler may, at any time, generate either inbound or outbound events that will be sent to the next handler in whichever direction is appropriate. This allows handlers to split up reads, coalesce writes, delay connection attempts, and generally perform arbitrary transformations of events.

In general, ChannelHandlers are designed to be highly re-usable components. This means they tend to be designed to be as small as possible, performing one specific data transformation. This allows handlers to be composed together in novel and flexible ways, which helps with code reuse and encapsulation.

ChannelHandlers are able to keep track of where they are in a ChannelPipeline by using a ChannelHandlerContext. These objects contain references to the previous and next channel handler in the pipeline, ensuring that it is always possible for a ChannelHandler to emit events while it remains in a pipeline.

SwiftNIO ships with many ChannelHandlers built in that provide useful functionality, such as HTTP parsing. In addition, high-performance applications will want to provide as much of their logic as possible in ChannelHandlers, as it helps avoid problems with context switching.

Additionally, SwiftNIO ships with a few Channel implementations. In particular, it ships with ServerSocketChannel, a Channel for sockets that accept inbound connections; SocketChannel, a Channel for TCP connections; DatagramChannel, a Channel for UDP sockets; and EmbeddedChannel, a Channel primarily used for testing.

A Note on Blocking

One of the important notes about ChannelPipelines is that they are thread-safe. This is very important for writing SwiftNIO applications, as it allows you to write much simpler ChannelHandlers in the knowledge that they will not require synchronization.

However, this is achieved by dispatching all code on the ChannelPipeline on the same thread as the EventLoop. This means that, as a general rule, ChannelHandlers must not call blocking code without dispatching it to a background thread. If a ChannelHandler blocks for any reason, all Channels attached to the parent EventLoop will be unable to progress until the blocking call completes.

This is a common concern while writing SwiftNIO applications. If it is useful to write code in a blocking style, it is highly recommended that you dispatch work to a different thread when you're done with it in your pipeline.

Bootstrap

While it is possible to configure and register Channels with EventLoops directly, it is generally more useful to have a higher-level abstraction to handle this work.

For this reason, SwiftNIO ships a number of Bootstrap objects whose purpose is to streamline the creation of channels. Some Bootstrap objects also provide other functionality, such as support for Happy Eyeballs for making TCP connection attempts.

Currently SwiftNIO ships with three Bootstrap objects: ServerBootstrap, for bootstrapping listening channels; ClientBootstrap, for bootstrapping client TCP channels; and DatagramBootstrap for bootstrapping UDP channels.

ByteBuffer

The majority of the work in a SwiftNIO application involves shuffling buffers of bytes around. At the very least, data is sent and received to and from the network in the form of buffers of bytes. For this reason it's very important to have a high-performance data structure that is optimized for the kind of work SwiftNIO applications perform.

For this reason, SwiftNIO provides ByteBuffer, a fast copy-on-write byte buffer that forms a key building block of most SwiftNIO applications.

ByteBuffer provides a number of useful features, and in addition provides a number of hooks to use it in an "unsafe" mode. This turns off bounds checking for improved performance, at the cost of potentially opening your application up to memory correctness problems.

In general, it is highly recommended that you use the ByteBuffer in its safe mode at all times.

For more details on the API of ByteBuffer, please see our API documentation, linked below.

Promises and Futures

One major difference between writing concurrent code and writing synchronous code is that not all actions will complete immediately. For example, when you write data on a channel, it is possible that the event loop will not be able to immediately flush that write out to the network. For this reason, SwiftNIO provides EventLoopPromise<T> and EventLoopFuture<T> to manage operations that complete asynchronously.

An EventLoopFuture<T> is essentially a container for the return value of a function that will be populated at some time in the future. Each EventLoopFuture<T> has a corresponding EventLoopPromise<T>, which is the object that the result will be put into. When the promise is succeeded, the future will be fulfilled.

If you had to poll the future to detect when it completed that would be quite inefficient, so EventLoopFuture<T> is designed to have managed callbacks. Essentially, you can hang callbacks off the future that will be executed when a result is available. The EventLoopFuture<T> will even carefully arrange the scheduling to ensure that these callbacks always execute on the event loop that initially created the promise, which helps ensure that you don't need too much synchronization around EventLoopFuture<T> callbacks.

Another important topic for consideration is the difference between how the promise passed to close works as opposed to closeFuture on a Channel. For example, the promise passed into close will succeed after the Channel is closed down but before the ChannelPipeline is completely cleared out. This will allow you to take action on the ChannelPipeline before it is completely cleared out, if needed. If it is desired to wait for the Channel to close down and the ChannelPipeline to be cleared out without any further action, then the better option would be to wait for the closeFuture to succeed.

There are several functions for applying callbacks to EventLoopFuture<T>, depending on how and when you want them to execute. Details of these functions is left to the API documentation.

Design Philosophy

SwiftNIO is designed to be a powerful tool for building networked applications and frameworks, but it is not intended to be the perfect solution for all levels of abstraction. SwiftNIO is tightly focused on providing the basic I/O primitives and protocol implementations at low levels of abstraction, leaving more expressive but slower abstractions to the wider community to build. The intention is that SwiftNIO will be a building block for server-side applications, not necessarily the framework those applications will use directly.

Applications that need extremely high performance from their networking stack may choose to use SwiftNIO directly in order to reduce the overhead of their abstractions. These applications should be able to maintain extremely high performance with relatively little maintenance cost. SwiftNIO also focuses on providing useful abstractions for this use-case, such that extremely high performance network servers can be built directly.

The core SwiftNIO repository will contain a few extremely important protocol implementations, such as HTTP, directly in tree. However, we believe that most protocol implementations should be decoupled from the release cycle of the underlying networking stack, as the release cadence is likely to be very different (either much faster or much slower). For this reason, we actively encourage the community to develop and maintain their protocol implementations out-of-tree. Indeed, some first-party SwiftNIO protocol implementations, including our TLS and HTTP/2 bindings, are developed out-of-tree!

Documentation

Example Usage

There are currently several example projects that demonstrate how to use SwiftNIO.

  • chat client https://github.com/apple/swift-nio/tree/master/Sources/NIOChatClient
  • chat server https://github.com/apple/swift-nio/tree/master/Sources/NIOChatServer
  • echo client https://github.com/apple/swift-nio/tree/master/Sources/NIOEchoClient
  • echo server https://github.com/apple/swift-nio/tree/master/Sources/NIOEchoServer
  • UDP echo client https://github.com/apple/swift-nio/tree/master/Sources/NIOUDPEchoClient
  • UDP echo server https://github.com/apple/swift-nio/tree/master/Sources/NIOUDPEchoServer
  • HTTP client https://github.com/apple/swift-nio/tree/master/Sources/NIOHTTP1Client
  • HTTP server https://github.com/apple/swift-nio/tree/master/Sources/NIOHTTP1Server
  • WebSocket client https://github.com/apple/swift-nio/tree/master/Sources/NIOWebSocketClient
  • WebSocket server https://github.com/apple/swift-nio/tree/master/Sources/NIOWebSocketServer

To build & run them, run following command, replace TARGET_NAME with the folder name under ./Sources

swift run TARGET_NAME

For example, to run NIOHTTP1Server, run following command:

swift run NIOHTTP1Server

Getting Started

SwiftNIO primarily uses SwiftPM as its build tool, so we recommend using that as well. If you want to depend on SwiftNIO in your own project, it's as simple as adding a dependencies clause to your Package.swift:

dependencies: [
    .package(url: "https://github.com/apple/swift-nio.git", from: "2.0.0")
]

and then adding the appropriate SwiftNIO module(s) to your target dependencies. The syntax for adding target dependencies differs slightly between Swift versions. For example, if you want to depend on the NIO and NIOHTTP1 modules, specify the following dependencies:

Swift 5.0 and 5.1 (swift-tools-version:5.[01])

dependencies: ["NIO", "NIOHTTP1"]

Swift 5.2 (swift-tools-version:5.2)

dependencies: [.product(name: "NIO", package: "swift-nio"),
               .product(name: "NIOHTTP1", package: "swift-nio")]

Using Xcode Package support

If your project is set up as an Xcode project and you're using Xcode 11+, you can add SwiftNIO as a dependency to your Xcode project by clicking File -> Swift Packages -> Add Package Dependency. In the upcoming dialog, please enter https://github.com/apple/swift-nio.git and click Next twice. Finally, select the targets you are planning to use (for example NIO, NIOHTTP1, and NIOFoundationCompat) and click finish. Now will be able to import NIO (as well as all the other targets you have selected) in your project.

To work on SwiftNIO itself, or to investigate some of the demonstration applications, you can clone the repository directly and use SwiftPM to help build it. For example, you can run the following commands to compile and run the example echo server:

swift build
swift test
swift run NIOEchoServer

To verify that it is working, you can use another shell to attempt to connect to it:

echo "Hello SwiftNIO" | nc localhost 9999

If all goes well, you'll see the message echoed back to you.

To work on SwiftNIO in Xcode 11+, you can just open the Package.swift file in Xcode and use Xcode's support for SwiftPM Packages.

If you want to develop SwiftNIO with Xcode 10, you have to generate an Xcode project:

swift package generate-xcodeproj

An alternative: using docker-compose

Alternatively, you may want to develop or test with docker-compose.

First make sure you have Docker installed, next run the following commands:

  • docker-compose -f docker/docker-compose.yaml run test

    Will create a base image with Swift runtime and other build and test dependencies, compile SwiftNIO and run the unit and integration tests

  • docker-compose -f docker/docker-compose.yaml up echo

    Will create a base image, compile SwiftNIO, and run a sample NIOEchoServer on localhost:9999. Test it by echo Hello SwiftNIO | nc localhost 9999.

  • docker-compose -f docker/docker-compose.yaml up http

    Will create a base image, compile SwiftNIO, and run a sample NIOHTTP1Server on localhost:8888. Test it by curl http://localhost:8888

  • docker-compose -f docker/docker-compose.yaml -f docker/docker-compose.1604.53.yaml run test

    Will create a base image using ubuntu 16.04 and swift 5.3, compile SwiftNIO and run the unit and integration tests. Files exist for other ubuntu and swift versions in the docker directory.

Developing SwiftNIO

Note: This section is only relevant if you would like to develop SwiftNIO yourself. You can ignore the information here if you just want to use SwiftNIO as a SwiftPM package.

For the most part, SwiftNIO development is as straightforward as any other SwiftPM project. With that said, we do have a few processes that are worth understanding before you contribute. For details, please see CONTRIBUTING.md in this repository.

Prerequisites

SwiftNIO's master branch is the development branch for the next releases of SwiftNIO 2, it's Swift 5-only.

To be able to compile and run SwiftNIO and the integration tests, you need to have a few prerequisites installed on your system.

macOS

  • Xcode 10.2 or newer, Xcode 11 recommended.

Linux

  • Swift 5.0, 5.1, or 5.2 from swift.org/download. We always recommend to use the latest released version.
  • netcat (for integration tests only)
  • lsof (for integration tests only)
  • shasum (for integration tests only)

Ubuntu 18.04

# install swift tarball from https://swift.org/downloads
apt-get install -y git curl libatomic1 libxml2 netcat-openbsd lsof perl

Fedora 28+

dnf install swift-lang /usr/bin/nc /usr/bin/lsof /usr/bin/shasum

Github

link
Stars: 5869

Dependencies

Used By

Total: 0

Releases

SwiftNIO 2.17.0 - 2020-05-12 13:54:51

Semver Minor

  • Added a new BSDSocket namespace, containing BSDSocket.OptionLevel and BSDSocket.Option for use when configuring socket options. (#1461, #1467, #1470, #1510) (Patch credit to @compnerd)
  • Added BSDSocket.ProtocolFamily and BSDSocket.AddressFamily to replace the libc spelling for socket address families. (#1468, #1469) (Patch credit to @compnerd)
  • Added ECN metadata to AddressedEnvelope. This functionality is currently unused, but will be enabled in a future release. (#1502)
  • Added ByteBuffer.writeRepeatingByte method to provide a fast memset-like operation. (#1500)
  • Added EventLoop.preconditionNotInEventLoop and EventLoop.assertNotInEventLoop to match existing EventLoop.preconditionInEventLoop and EventLoop.assertInEventLoop. (#1508) (Patch credit to @gwynne)
  • Added MultithreadedEventLoopGroup.withCurrentThreadAsEventLoop to support taking over an existing thread and turning it into a NIO event loop. This allows NIO programs to now be single-threaded. (#1499)
  • Added EventLoop.flatScheduleTask to provide a cleaner way to support a scheduled task that returns a future. (#1497) (Patch credit to @gwynne)

Semver Patch

  • Fixed an error in the UDP echo client example where the socket would not be closed after receiving the response. (#1501)
  • Cleaned up uniqueness checking in NIOHTTP1. (#1507) (Patch credit to @shekhar-rajak)
  • New UDP allocation tests. (#1496)
  • Improved allocation counter tests. (#1476)
  • Improved allocation diffing script. (#1513)
  • Removed warnings. (#1481, #1493)
  • Documentation improvements. (#1474, #1482, #1483, #1505)
  • Added Swift 5.3 CI. (#1498)

SwiftNIO 2.16.1 - 2020-05-05 10:58:50

SwiftNIO 2.16.1

  • make compiles with Swift 5.3 compilers warning free (#1493 / #1498)

SwiftNIO 2.16.0 - 2020-04-02 17:19:37

SemVer Minor

  • Offer event loop group validation for bootstraps (#1464)
  • Convenient initialisers from ByteBuffer (#1457)

SemVer Patch

  • Selector: further default to Linux behaviour (#1447, patch credit to @compnerd)
  • IO: extend IOError for Windows (#1460, patch credit to @compnerd)
  • CNIOWindows: add paranoid preprocessing (NFC) (#1459, patch credit to @compnerd)
  • NIO: add module constructor for Windows (#1450, patch credit to @compnerd)
  • shorten NIOThreadPool's thread names (#1466)

SwiftNIO 2.15.0 - 2020-03-19 18:01:25

SemVer Minor

  • universal bootstrapping mechanism (#1323)
  • warn on execution of tasks on an already shutdown EL (#1395, patch credit to @realdoug)
  • ByteToMessageDecoder: Default implementation for decodeLast should be provided (#1426, patch credit to @shekhar-rajak)
  • Add offset writes and file size support to NonBlockingFileIO (#1408, patch credit to @sveamarcus)
  • Add custom index methods to ByteBufferView (#1394, patch credit to @PeterAdams76)
  • Provides a means to control the underlying header storage capacity. (#1451, patch credit to @ldewailly)

SemVer Patch

  • the beginnings of Windows support for SwiftNIO, a fantastic effort by @compnerd
    • NIOConcurrencyHelpers: make LLP64 friendly (#1402, patch credit to @compnerd)
    • CNIOAtomics: define types for uintptr_t and intptr_t (#1401, patch credit to @compnerd)
    • NIOConcurrencyHelpers: port to Windows (#1403, patch credit to @compnerd)
    • NIO: undo exclusion of UDS on Windows (#1437, patch credit to @compnerd)
    • CNIOSHA1: make the code more portable (#1399, patch credit to @compnerd)
    • CNIOAtomics: declare atomic operations using a macro (#1400, patch credit to @compnerd)
    • NIO: excise UDS support for Windows (#1404, patch credit to @compnerd)
    • SelectableEventLoop: make Darwin the special case (#1449, patch credit to @compnerd)
    • NIO: unify the syscall wrapper (#1423, patch credit to @compnerd)
    • NIO: swap selector implementations (NFC) (#1443, patch credit to @compnerd)
    • NIO: use Posix "namespace" more aggressively (#1439, patch credit to @compnerd)
    • NIO: split out FileDescriptor and Selectable (#1444, patch credit to @compnerd)
    • NIO: move comment to right location (NFC) (#1452, patch credit to @compnerd)
    • NIO: implement core counting on Windows (#1448, patch credit to @compnerd)
    • Thread: port to Windows (#1424, patch credit to @compnerd)
  • docs: BlockingIOThreadPool -> NIOThreadPool (#1438, patch credit to @kmahar)
  • use Posix.read instead of Glibc.read for timerfd (#1432, patch credit to @shekhar-rajak)
  • tests: improve tests that are supposed to throw (#1430)
  • fix more warnings from master Swift compilers (#1396)
  • list_topsorted_deps: multiple fixes (#1420)
  • update docs generation script to work better with selinux (#1419)
  • Add SSWG badge to README (#1421)
  • Allow discardable results on NIOAtomic for mutating functions (#1417, patch credit to @kylebrowning)
  • Stop copying Strings into Arrays for SHA1 (#1413, patch credit to @trungducc)
  • undo @convention(c) hacks in System.swift (#1412, patch credit to @shekhar-rajak)
  • Use UInt instead of ObjectIdentifier in promiseCreationStore (#1411, patch credit to @shekhar-rajak)
  • test that massive chunked encoding chunks behave sensibly (#1407)
  • other minor improvements (#1455, #1454, #1446, #1434, #1433, #1419, #1398)

SwiftNIO 2.14.0 - 2020-02-13 19:53:43

SemVer Minor

  • apply ChannelOptions before channel initializer runs (#1372)
  • Reserve capacity in terms of writable bytes (#1378)

SemVer Patch

  • add AcceptHandler after serverChannelInitializer runs (#1393)
  • improve pod updater script (#1391)
  • Include stackdiff-ing in the debugging-allocations doc (#1384)
  • add Swift 5.2 to the readme (#1386)
  • ByteBuffer: make getInteger for UInt8 faster (#1380)
  • update vendored code & attribute it correctly (#1382)
  • Provide descriptions for EventLoopError (#1381)
  • get IOError down to git in an existential container (#1355) (#1376, patch credit to @dfriedm3)
  • dev/stackdiff-dtrace: stack aggregation diffing script (#1373)
  • SR-12094 is fixed, no need to skip tests (#1371)
  • improve docker security (#1375)
  • Avoid curried thunks (workaround SR-12115) (#1374)
  • switch swift-tools-version to 5.0 for integration tests (#1369)
  • include clang modularised headers last (#1368)
  • fix 5.2 builds (#1366)
  • fix #1363: fix race between EL exit and wakeup call (#1364)
  • add SAL (Syscall Abstraction Layer) and new SALChannelTests
  • Recursive file reading not building up EventLoopFuture chain (#1353, patch credit to @fabianfett)
  • adding an extra test for reading many chunks (#1356)
  • fix docker setup for development snapshots (#1357)
  • update contributors (#1350)
  • make tests faster (#1367, #1365)

SwiftNIO 1.14.2 - 2020-02-10 15:32:47

This version contains security related content: please apply the update as soon as possible.

Semver Minor

  • Updated http-parser to bring in the fix for Node.JS CVE-2019-15605, which also affected SwiftNIO. This allowed remote peers to launch request smuggling attacks on SwiftNIO. A SwiftNIO-specific CVE is forthcoming, but as this vulnerability is already public knowledge we judged it to be important to ship a patch before the CVE is ready. Reported by ZeddYu Lu. (#1388)

SwiftNIO 2.13.1 - 2020-02-10 15:11:37

This version contains security related content: please apply the update as soon as possible.

Semver Minor

  • Updated http-parser to bring in the fix for Node.JS CVE-2019-15605, which also affected SwiftNIO. This allowed remote peers to launch request smuggling attacks on SwiftNIO. A SwiftNIO-specific CVE is forthcoming, but as this vulnerability is already public knowledge we judged it to be important to ship a patch before the CVE is ready. Reported by ZeddYu Lu. (df9390006bce7da1b6273f804d3acbbfdfcc6154)

SwiftNIO 2.13.0 - 2020-01-22 16:24:52

SemVer Minor

  • Add setSubstring/writeSubstring to ByteBuffer. (#1346, patch credit to @cpriebe)
  • Add bindTimeout function to ServerBootstrap (#1349, patch credit to @cpriebe)
  • support pread (#1324)
  • Correct NIOHTTPWebClientSocketUpgrader to NIOHTTPWebSocketClientUpgrader (#1336, patch credit to @tigerpixel)
  • ByteBuffer is now Hashable (#1326, patch credit to @fabianfett)

SemVer Patch

  • Rename misnamed closure parameter argument in ServerBootstrap.bind0 (#1347, patch credit to @cpriebe)
  • improve flushNow re-entrancy protection (#1348)
  • improve flushNow behaviour tests & description (#1345)
  • flushes from channelWritabilityChanged callbacks get lost (#1344)
  • Fix documentation for HTTPRequestDecoder. (#1342, patch credit to @vsapsai)
  • Read exactly UInt64's size from timerfd (#1340, patch credit to @Bouke)
  • Change the byte to message decoder verifier example to be correct. (#1338, patch credit to @tigerpixel)
  • Initializing HTTPMethod with String picks explicit value over catch all RAW(value) (#1329, patch credit to @fabianfett)
  • Faster Base64 Encoding for NIOWebsocket connections (#1328, patch credit to @fabianfett)
  • docker: support Swift 5.2 dev snapshots (#1343)
  • Fix documenation in HTTPHeaders. (#1335)
  • fix bogus warnings in newer Swift versions (#1325)

SwiftNIO 2.12.0 - 2019-12-20 17:41:13

SemVer Minor

  • add descriptions to EventLoop and NIOThread (#1317)
  • fix EVFILT_EXCEPT loop if autoRead is off on Darwin (#1305)
  • Remove example binaries from products (#1303, patch credit to @johnlinvc)

SemVer Patch

  • Drain scheduled tasks on EmbeddedChannel finish() (#1319)
  • make SelectableEventLoop.description not take a lock (#1318)
  • HEAD and DELETE may have bodies. (#1314, bug report credit to @prafsoni)
  • Use actual element count of PriorityQueue for its description (#1296, patch credit to @adtrevor)
  • close kqueue/epoll fds in Selector.close (#1308)
  • SelectableEventLoop: Call wakeup less frequently (#1301)
  • Create a ClientBootstrap protocol (#1253, patch credit to @Yasumoto)
  • add an allocation counter test for scheduling tasks (#1315)
  • fix race in testConnect (#1310)
  • accept: don't do unnecessary dodgy pointer things (#1306, bug report credit to @milseman)
  • remove phantom publics from EventLoop and Heap (#1298)
  • don't assume realloc never happens (#1300)
  • Other small improvements (#1312, #1311, #1304)

SwiftNIO 2.11.1 - 2019-12-13 11:10:24

SemVer Patch

  • workaround failed associated type inference (#1299)
  • EventLoopFuture: more tests for andAll/whenAllComplete (#1297)

SwiftNIO 2.11.0 - 2019-12-09 14:37:07

SemVer Minor

  • fix AtomicBox by deprecating it and implementing it with a CAS loop (#1287)
  • Add first(name:) to HTTPHeaders (#1282)
  • Out of pipeline byte stream decoding (#1268, patch credit to @richardalow)
  • Fast atomics (#1263, patch credit to @2bjake)
  • Make ByteBufferView mutable (#1208)
  • join the threads of a MultiThreadedEventLoopGroup on shutdown (#1261)
  • fix a number of memory leaks in the test suite (#1157)

SemVer Patch

  • save allocations on connect (#1290)
  • optimise future callback collection (#1293)
  • Remove weak var from testThreadSpecificDoesNotLeakIfThreadExitsWhilstSetOnMultipleThreads (#1295)
  • Replaced CircularBuffer's uses of checked arithmetic (+, -) (#1284, patch credit to @3a4oT)
  • stop using AtomicBox (#1289)
  • make sure ByteToMessageHandler is happy never being in a pipeline (#1288)
  • implemented Equatable for _UInt24 and _UInt56 and marked as @inlinable (#1285, patch credit to @3a4oT)
  • Webhooks upgrade complete fix (#1280, patch credit to @MrLotU)
  • document debugging with allocation tests (#1277)
  • heap: make checkHeapProperty a tests thing (#1276)
  • use Optional instead of T? to workaround SR-11777 (#1252)
  • Also collect total bytes allocated in alloc tests (#1116, patch credit to @ktoso)
  • allow deprecated tests to test deprecated functionality (#1083)
  • Fix typo in Endianness docs (#1269, patch credit to @ktoso)
  • Fix Dash docset generation. (#1256)
  • remove internal ExpressibleBy(Integer|Array)Literal conformances (#1258)
  • Added parentheses in TimeAmount constructors to generate optimal code. As Per issue #1249 (#1250, patch credit to @przala)
  • Support writing WS header to user buffer. (#1168)
  • Various other small improvements (#1273, #1251, #1278, #1272, #1259)

SwiftNIO 2.10.1 - 2019-11-14 11:11:12

SemVer Patch

  • Fix running run-nio-alloc-counter-tests.sh for a single test (#1245)
  • HTTP1TestServer: close accepted channel on stop (#1246)
  • fix new warnings about empty OptionSets (#1238)
  • perf tests: switch printed metric to mean (#1244)
  • fix two potential hangs in the test suite (#1240)
  • add script to easily create multi-module SwiftPM packages from one file (#1236)
  • Add withContiguousStorageIfAvailable implementation to WebSocketMaskingKey (#1237, patch credit to @richardalow)
  • performance: don't use variable initialisation outside of init (#1235)
  • Disallow zero EventLoop threads (#1230, patch credit to @richardalow)
  • Add extra WebSocket decoder benchmarks (#1219, patch credit to @emarashliev)
  • Speed up ByteBuffer setBytes slow path (#1231, patch credit to @richardalow)
  • Update ByteBuffer docs to advance write index on set operations (#1233, patch credit to @richardalow)
  • cleanup some unnecessary #if os (#1199)
  • NIOPerformanceTester: more precision and resiliency (#1229)
  • EventLoopFuture: save one allocation per future (#1224)
  • ByteBuffer: readJSONDecodable: use specified decoder (#1228)
  • update contributors (#1225)
  • Cow-box WebSocketFrame. (#1211, patch credit to @marlimox)

SwiftNIO 2.10.0 - 2019-11-07 19:12:46

SemVer Minor

  • Add ApplicationProtocolNegotiationHandler init that takes a closure that receives the Channel (#1196, patch credit to @2bjake)
  • added a public var to extract the IP address of the SocketAddress (#1194, patch credit to @Lupurus)
  • Make SocketAddress.port mutable (#1200, patch credit to @siemensikkema)
  • Add function preconditionIsNotBlacklistedErrno (#1201, patch credit to @heidipuk)
  • Add an option to ByteBuffer.clear() to specify minimumCapacity (#1204, patch credit to @cweinberger and @Keno42)

SemVer Patch

  • Allow single test to be specified as an argument to run-nio-alloc-counter-tests.sh. (#1214, patch credit to @marlimox)
  • Use self as the decoder when decoding a ByteBuffer (#1221, patch credit to @gwynne)
  • Add inlinability to ByteBuffer getters. (#1220)
  • ByteBuffer.clear should reset the ByteBuffer._slice. (#1212, patch credit to @kam800)
  • Added an allocation benchmark for WebSocketFrameDecoder. (#1210, patch credit to @marlimox)
  • Add an benchmark for WebSocket frame decoder (#1203, patch credit to @emarashliev)
  • add socketpair to the POSIX wrappers (#1198)
  • Make future builders and scheduled tasks inlinable (#1193)
  • improve docs (#1191, #1206, patch credit to @Davidde94)
  • make use of EventLoop.flatSubmit (#1179)

SwiftNIO 2.9.0 - 2019-10-23 18:18:31

SemVer Minor

  • Add option to reserve writable capacity to writeWithUnsafeMutableBytes (#1175, patch credit to @2bjake)
  • Add flatSubmit method to EventLoop (#1174, patch credit to @2bjake)
  • namespace ChannelOptions types (#1176, patch credit to @2bjake)
  • Add API for modifying ByteBuffer without CoW (#1173)
  • ByteBuffer: add direct Codable support (#1153)
  • add PipeChannel (#1138)
  • NIOHTTP1TestServer (#1152, patch credit to @mariosangiorgio)
  • assert EventLoopGroup::syncShutdownGracefully is not called on the event loop (#1151, patch credit to @tomerd)

SemVer Patch

  • fix tests in iOS Simulator (#1171)
  • Reduce allocations in WebSocketFrameEncoder. (#1161)
  • Add some websocket encode benchmarks. (#1159)
  • Prefer handlerAdded/handlerRemoved in websocket example (#1158, patch credit to @ktoso)
  • swift 5.1 docker setup (#1146, patch credit to @tomerd)
  • fix thread-safety of BaseSocketChannel's description (#1142, bug report credit to @drexin)
  • fix one EventLoopGroup leak in tests (#1143)
  • Fix creating HTTPResponseStatus from 418 (#1140)
  • various small readme, benchmarks, code, and docs improvements (#1137, #1172, #1170, #1178, #1164, #1163, #1162, #1145)

SwiftNIO 2.8.0 - 2019-09-10 15:06:12

SemVer Minor

  • Allow promises to be completed with a Result<Value, Error> (#1124, patch credit to @glbrntt)
  • ChannelPipeline: fail double removal of handler (#1133, reported by @vlm)

SemVer Patch

  • fix NIODeadline/TimeAmount maths (#1136, reported by @mariosangiorgio)
  • HTTPServerUpgradeHandler: Tolerate futures from other ELs (#1134, reported by @vlm)
  • Lock: guarantee crash instead of undefined behaviour (#1131, reported by @kevints)
  • Avoid having cascade be title of all methods in jazzy docs (#1129, patch credit to @ktoso)
  • Fix doc typo: before possible -> are possible (#1122, patch credit to @tamc)

SwiftNIO 2.7.1 - 2019-08-27 13:32:38

SemVer Patch

  • BaseSocketChannel: accept immediately closed socket (#1121)
  • codestyle: apply suggestions from #1117 (#1118)
  • Fix dead link to process_test_files.rb in NOTICE.txt (#1119)
  • update conduct email group (#1120)

SwiftNIO 2.7.0 - 2019-08-15 15:07:14

SemVer Minor

  • Add conditional conformances of CircularBuffer to Equatable and Hashable (#1101)
  • Conform CircularBuffer to ExpressibleByArrayLiteral (#1102)

SemVer Patch

  • NIOThreadPool: backed by NIOThreads (pthreads) instead of DispatchQueues (#1100)
  • docs: EmbeddedChannel isn't as broken as it claims (#1103)
  • Remove unused wrapper functions for atomic_flag (#1106)
  • Rename BOOL to BOOLIFY (#1107)
  • bootstraps: tolerate random EventLoops (#1108)
  • MTELG: Add EventLoopGroup identifier (#1109)
  • more compatibility with other platforms (#1110)
  • Remove cpp_magic.h import and ancient Clang compatibility hack from CNIOAtomics.h (#1111)

SwiftNIO 2.6.1 - 2019-08-09 11:07:26

SemVer Patch

  • Deliver HTTPServerUpgradeHandler data on removal. (#1092)
  • HTTPDecoder: don't deliver unsolicited responses (#1093)
  • really no double handlerRemoved calls (#1094)
  • Fail promise in MessageToByteHandler write error cases (#1096)

SwiftNIO 2.6.0 - 2019-08-02 07:56:49

Semver Minor

  • Fixed a crash when a client received an unsolicited HTTP response: now errors instead. (#1084)

Semver Patch

  • Fixed an issue where handlerRemoved could be called multiple times, leading to crashes in ByteToMessageDecoders. (#1091)
  • Enhanced MultiThreadedEventLoopGroup to support being shut down multiple times. (#1085, #1089)
  • Prevented ByteBuffer.viewBytes from crashing when passing it a negative length. (#1082)
  • Testing improvements. (#1086, #1090)
  • New WebSocket client example. (#1064, #1087)

SwiftNIO 2.5.1 - 2019-07-24 18:58:44

SemVer Patch

  • Make pipeline handler behave better when removed (#1080)

SwiftNIO 2.5.0 - 2019-07-22 16:43:21

Semver Minor

  • Deprecated and replaced ByteBuffer.set(buffer:at:) with ByteBuffer.setBuffer(_:at:). (#1078)

Semver Patch

  • Enforced that shutting down EventLoopGroups not directly created by you is illegal. (#1055)
  • Improved performance of EventLoopFuture.reduce. (#1069, #1070)
  • Fixed an issue when subtracting two NIODeadline structures could lead to a crash. (#1074)
  • Miscellaneous testing improvements. (#1062, #1067, #1068, #1076, #1077, #1079)

SwiftNIO 2.4.0 - 2019-07-11 19:53:06

SemVer Minor

  • Add a WebSocket client upgrader. (#1038)
  • EventLoopPromise.completeWith(Future), mirroring ELF.cascade(to:) (#1053)

SemVer Patch

  • HTTPDecoder: Don't invoke left overs strategy on EOF (#1061)
  • check breakages: fail loudly when unable to checkout tag (#1060)
  • Check jq is available before checking API breakages (#1058)
  • various patches (#1063, #1051, #1050)

SwiftNIO 2.3.0 - 2019-06-19 17:16:14

Semver Minor

  • Enable TCP_NODELAY by default on all TCP channels. (#1020)
  • Enabled heuristic to control whether NIO will copy data from ByteBuffer to Data or whether it will share the buffer, as well as APIs to explicitly control that choice. (#1046)
  • Fixed issue where fcntl failing to set an accepted socket into non-blocking mode would cause the closure of the entire listening socket. (#1041)
  • Add a HTTP client upgrade handler. (#1001)
  • Made EmbeddedChannel.isWritable mutable. (#1023)
  • Added CircularBuffer.modify. (#1009)

Semver Patch

  • Returned a NIOFileHandle(path:) constructor that was accidentally removed. (#1045)
  • Fixed an issue where setting a socket to non-blocking mode could clobber any other flags on that socket. (#1040)
  • Fixed an issue where IPv6 tests would incorrectly run on a system without appropriate IPv6 support. (#1028)
  • Improved AcceptHandler to prevent it swallowing errors when attempting to quiesce channels. (#1015)
  • Added optimisation tips document. (#1024)
  • Extra EmbeddedChannel testing. (#1033)
  • Added continuous performance reporting. (#1044)
  • Miscellaneous testing & documentation cleanups and improvements. (#1043, #1034, #1032, #1026, #1025, #1022, #1021, #1019, #1016, #1013)

SwiftNIO 2.2.0 - 2019-05-22 17:21:08

Semver Minor

  • Added EventLoopFuture.always. (#981)
  • Added HTTPHeaders.add(contentsOf:). (#1004)
  • Added new ByteToMessageDecoder verifier test utility. (#939)
  • Added EventCounterHandler test utility. (#1005)

Semver Patch

  • Removed some hardcoded features of the allocation counter script. (#999)
  • Improved the temporary directory management of the allocation counter script. (#1000)
  • Cleaned up misleading code comment. (#1012)
  • Cleaned up docker files. (#1007, #1010)

SwiftNIO 2.1.1 - 2019-05-17 16:18:26

SemVer Patch (repair accidental SemVer Major)

  • undo tiny public API breakage #1008

SwiftNIO 2.1.0 - 2019-05-09 14:30:57

Semver Minor

  • Added an API to construct a ByteBuffer from a ByteBufferView. (#958)
  • Added an API to limit the maximum buffer size of a ByteToMessageDecoder. (#957, #998)
  • Extended NonBlockingFileIO to allow opening a file for writing. (#975, #990)
  • Added NIOCloseOnErrorHandler. (#967)
  • Conformed HTTPMethod to RawRepresentable with a raw type of String. (#976)
  • Added an API to get a ChannelHandler from the pipeline. (#974)
  • Made ChannelOptions.Storage initializer public. (#988)
  • Renamed WebSocketUpgrader to NIOWebSocketServerUpgrader and deprecated the old name. (#983)

Semver Patch

  • Improved performance by rewriting internal Heap implementation. (#960)
  • Fixed example HTTP server to avoid crashing when serving an empty file. (#962)
  • Removed invalid assert in CircularBuffer that caused crashes on 32 bit architectures. (#978)
  • Fixed a bug where HTTPDecoder would incorrectly retain too many bytes, and replay them on handler removal in some cases. (#984)
  • Made MarkedCircularBuffer implementation @inlineable. (#993)
  • Improved the performance of constructing HTTPHeaders from an array of tuples. (#994)
  • Fixed an issue where HTTPDecoder would crash if it received a response without headers. (#997)
  • Added a link to GitHub implementation in documentation. (#977)
  • Started testing on Swift 5.1. (#991, #995)
  • Various documentation cleanups. (#979, #989)
  • Removed some warnings in the tests. (#982)
  • Started using new allocation test framework. (#996)

SwiftNIO 2.0.2 - 2019-04-30 10:33:06

SemVer Patch

  • Add 'Show on GitHub' link to API docs (#977)
  • CircularBuffer.Index: remove bogus assert (#978)
  • Remove unnecessary warnings in HeapTests (#982)
  • Avoid keeping hold of partial bytes forever. (#984)

SwiftNIO 2.0.1 - 2019-04-12 15:45:52

Semver Patch

  • Simplified our internal Heap implementation, improving performance. (#960)
  • Prevent internal ByteToMessageDecoder errors by entering the final state twice on error. (#948)
  • Significantly improved performance of EventLoopFuture.andAllSucceed and EventLoopFuture.whenAllSucceed. (#943)
  • Cleanups in examples. (#941, #953)
  • Improved testing. (#956)
  • Documentation improvements. (#932, #940, #949, #959)

SwiftNIO 1.14.1 - 2019-04-11 08:17:03

Semver Patch

  • Fixed an issue introduced in 1.14.0 that led to EventLoopFuture.hopTo(_:) accidentally being made internal. (#963)

SwiftNIO 1.14.0 - 2019-04-10 17:18:10

SemVer Minor

  • Backport whenAll[Succeed] to NIO 1 (#947)

SemVer Patch

  • Simplify Heap implementation. patch-version-bump-only (#961)
  • alloc tests: hook posix_memalign & reallocf (#954)