Swiftpack.co - Package - Mordil/swift-redi-stack

RediStack logo

Build Status SSWG Maturity Apache 2 License Swift 5.0+ Redis 5.0+

The GitHub repository is a read-only mirror of the GitLab repository. For issues and merge requests, please visit GitLab.


RediStack (pronounced like "ready stack") is a non-blocking Swift client for Redis built on top of SwiftNIO.

It communicates over the network using Redis' Redis Seralization Protocol (RESP2).

The table below lists the major releases alongside their compatible language, dependency, and Redis versions.

| SPM Version | Swift | Redis | SwiftNIO | SwiftLog | SwiftMetrics | |:---:|:---:|:---:|:---:|:---:|:---:| | from: "1.0.0-alpha.5" | 5.0+ | 5.0+ | 2.x | 1.x | 1.x |

Supported Operating Systems

RediStack runs anywhere that is officially supported by the Swift project.

See the test matrix below for more details.


To install RediStack, just add the package as a dependency in your Package.swift.

dependencies: [
    .package(url: "https://gitlab.com/mordil/swift-redi-stack.git", from: "1.0.0-alpha.5")

Getting Started

RediStack is quick to use - all you need is an EventLoop from SwiftNIO.

import NIO
import RediStack

let eventLoop: EventLoop = ...
let connection = RedisConnection.connect(
    to: try .init(ipAddress: "", port: RedisConnection.defaultPort),
    on: eventLoop

let result = try connection.set("my_key", to: "some value")
    .flatMap { return connection.get("my_key") }

print(result) // Optional("some value")

Note: Use of wait() was used here for simplicity. Never call this method on an eventLoop!


The docs for the latest tagged release are always available at docs.redistack.info.


For bugs or feature requests, file a new issue.

For all other support requests, please email support@redistack.info.


SemVer changes are documented for each release on the releases page.


Check out CONTRIBUTING.md for more information on how to help with RediStack.


Check out CONTRIBUTORS.txt to see the full list. This list is updated for each release.

Swift on Server Ecosystem

RediStack is part of the Swift on Server Working Group ecosystem - currently recommended as Sandbox Maturity.

| Proposal | Pitch | Discussion | Review | Vote | |:---:|:---:|:---:|:---:|:---:| | SSWG-0004 | 2019-01-07 | 2019-04-01 | 2019-06-09 | 2019-06-27 |

Language and Platform Test Matrix

The following table shows the combination of Swift language versions and operating systems that receive regular unit testing (either in development, or with CI).

| Swift Version | macOS Mojave | Ubuntu 16.04 (Xenial) | Ubuntu 18.04 (Bionic) | |---|:---:|:---:|:---:| | 5.0 | X | X | X | | 5.1 | X | X | X | | Trunk | X | X | |


Apache 2.0

Copyright (c) 2019-present, Nathan Harris (@mordil)

This project contains code written by others not affliated with this project. All copyright claims are reserved by them. For a full list, with their claimed rights, see NOTICE.txt

Redis is a registered trademark of Redis Labs. Any use of their trademark is under the established trademark guidelines and does not imply any affiliation with or endorsement by them, and all rights are reserved by them.

Swift is a registered trademark of Apple, Inc. Any use of their trademark does not imply any affiliation with or endorsement by them, and all rights are reserved by them.


Stars: 14
Help us keep the lights on


1.0.0-alpha.6 - Sep 24, 2019

API Docs are always available at docs.redistack.info


  • RedisIntegrationTestCase now has properties that can be overridden in subclasses for specializing how to connect to Redis !74
  • RESPTranslator.ParsingError has two new cases: invalidBulkStringSize and bulkStringSizeMismatch !82
  • RedisMetrics.activeConnectionCount is no longer an Int and instead is a new specialized wrapper class called ActiveConnectionGauge !84
    • This is to address the data race found by the thread sanitizer that now runs on test passes
    • It maintains an internal Atomic<Int> count that can be modified with the public increment(by:)/decrement(by:) methods


  • RESPValue now conforms to Equatable !76
  • RedisError now conforms to Equatable !77
  • RESPValue.init(bulk:) now accepts a wider range of values !81
    • The String overload is now String?
    • The Int overload is now generic with a constraint of FixedWidthInteger


  • Fixed a data race with RedisMetrics.activeConnectionCount that was caught with the new thread sanitizer test passes !84
    • The job that caught the error: https://gitlab.com/Mordil/swift-redi-stack/-/jobs/302079265

1.0.0-alpha.5.0.2 - Jul 13, 2019

API Docs are always available at docs.redistack.info


  • RedisConnection.sendCommandsImmediately is now correctly public (fae8eada)

1.0.0-alpha.5.0.1 - Jul 11, 2019

API Docs are always available at docs.redistack.info


  • RediStackTestUtils is now correctly an importable module (aeae1f6c)

1.0.0-alpha.5 - Jul 11, 2019

API Docs are always available at docs.redistack.info


  • The library module was renamed from RedisNIO to RediStack !73
  • RedisNIOError was renamed to RedisClientError !72
    • .responseConversion(to:) was renamed to .failedRESPConversion(to:)
    • .unsupportedOperation(method:message:) was removed
  • RedisCommandHandler is no longer open (now public final) !55
  • RedisCommandContext was renamed to RedisCommand !66
  • RedisCommand.command was renamed to message and the initializer signature updated to match its properties (2605763)
  • RedisCommandHandler.init(logger:) is now .init(initialQueueCapacity:logger:) !66
  • The names for the ChannelPipeline handlers are now explicitly named !66
    • RediStack.OutgoingHandler
    • RediStack.IncomingHandler
    • RediStack.CommandHandler
  • The Redis namespace enum was removed !71
    • The makeConnection factory method was moved to RedisConnection.connect
      • This method now requires a NIO.EventLoop instance, no longer creating a MultiThreadedEventLoopGroup for you
      • This method also now supports overriding the default NIO.ClientBootstrap and is the preferred way of building your own pipelines
  • RedisConnection.init is now internal, all connections are made with RedisConnection.connect !71
  • A few different logs have had their severity adjusted
    • Sending a command while the connection is closed is now a warning !71
  • Sorted Set methods zadd, zunionstore, and zinterstore, have stronger type safety with options defined as enums !70 and (0ecb3c1)
  • RESPValueConvertible is no longer used as an existential !69
    • This also changes RedisConnection.send(command:with:) to require the RESPValue arguments up front, rather than doing the conversion for you
  • RESPValue and RESPValueConvertible had many internal implementations changed !67
    • RESPValue.array no longer uses ContiguousArray
    • ContiguousArray is no longer RESPValueConvertible
    • several of the computed properties on RESPValue will no longer behave exactly the same, or have moved to the new RediStackTestUtils module
  • Redis.makeDefaultClientBootstrap(using:) was renamed and moved to ClientBootstrap.makeRedisTCPClient(group:) !64
    • The implementation for adding the "default" RESP handlers is now publicly available with Channel.addBaseRedisHandlers()
  • RESPTranslator saw a major refactor !63
    • It is now a struct instead of an enum
    • ByteBuffer.writeRESPValue(_:) is a new method carrying most of the implementation for writing out RESPValue
    • RESPTranslator.ParsingResult was removed
    • RESPTranslator now updates the passed in ByteBuffer.readerIndex on successful parses
    • RESPTranslator.parseBytes(from:) uses the passed in ByteBuffer entirely for position and recursion
  • RESPValueConvertible.init(_:) was renamed to .init(fromRESP:) !56


  • A new module RediStackTestUtils is available for some helpers with writing tests for RediStack !67


  • The observable behavior of closing a channel should be more straight forward and dependable !71

1.0.0-alpha.3 - Jul 11, 2019


  • NIO is no longer exported, you will need to explicitly import NIO !57
  • errorCaught in RedisCommandHandler now fails all pending responses, and does not increment RedisMetrics.commandFailureCount !59
  • EventLoopFuture.mapFromRESP has been renamed to `EventLoopFuture.convertFromRESPValue !60


  • The APPEND command is now available with the append(_:to:) method !61