Go to file
Helge Hess 54e12c2285
Badges
2018-04-11 00:44:25 +02:00
.travis.d Travis: Add Travis setup 2018-04-11 00:31:22 +02:00
Sources Initial drop 2018-04-11 00:27:29 +02:00
.gitignore Initial drop 2018-04-11 00:27:29 +02:00
.travis.yml Travis: Add Travis setup 2018-04-11 00:31:22 +02:00
CONTRIBUTORS.txt Initial drop 2018-04-11 00:27:29 +02:00
LICENSE.txt Initial drop 2018-04-11 00:27:29 +02:00
Package.swift Initial drop 2018-04-11 00:27:29 +02:00
README.md Badges 2018-04-11 00:44:25 +02:00

README.md

SwiftNIO Redis

Swift4 macOS tuxOS Travis

SwiftNIO Redis is a Swift package that contains a high performance Redis protocol implementation for SwiftNIO. This is a standalone project and has no other dependencies but SwiftNIO.

Apart from the protocol implementation which can encode and decode RESP (REdis Serialization Protocol), we also provide a Redis client module build on top.

What is Redis? Redis is a highly scalable in-memory data structure store, used as a database, cache and message broker. For example it can be used to implement a session store backing a web backend using its "expiring keys" feature, or it can be used as a relay to implement a chat server using its builtin PubSub features.

Performance

This implementation is focused on performance. It tries to reuse NIO ByteBuffers as much as possible to avoid copies.

The parser is based on a state machine, not on a buffering ByteToMessageDecoder/Encoder. That doesn't make it nice, but efficient ;-)

Importing the module using Swift Package Manager

An example Package.swift importing the necessary modules:

// swift-tools-version:4.0

import PackageDescription

let package = Package(
    name: "RedisTests",
    dependencies: [
        .package(url: "https://github.com/NozeIO/swift-nio-redis.git", 
                 from: "0.8.0")
    ],
    targets: [
        .target(name: "MyProtocolTool",
                dependencies: [ "NIORedis" ]),
        .target(name: "MyClientTool",
                dependencies: [ "Redis" ])
    ]
)

Using the SwiftNIO Redis protocol handler

The RESP protocol handler just implemented as a regular ChannelHandler, similar to NIOHTTP1. It takes incoming ByteBuffer data, parses that, and emits RESPValue items. Same the other way around, the user writes RESPValue (or RESPEncodable) objects, and the handler renders such into ByteBuffers.

The NIORedis module has a litte more information.

To add the RESP handler to a NIO Channel pipeline, the configureRedisPipeline method is called, e.g.:

bootstrap.channelInitializer { channel in
  channel.pipeline
    .configureRedisPipeline()
    .then { ... }
}

Using the Redis client module

The Redis client module is modeled after the Node.js node_redis module, but it also supports NIO like Promise/Future based methods in addition to the Node.js (err,result) style callbacks. Choose your poison.

Simple KVS use example:

import Redis

let client = Redis.createClient()

client.set ("counter", 0, expire: 2)
client.incr("counter", by: 10)
client.get ("counter") { err, value in
    print("Reply:", value)
}
client.keys("*") { err, reply in
    guard let keys = reply else { return print("got no keys!") }
    print("all keys in store:", keys.joined(separator: ","))
}

Using NIO Promises:

client
  .set ("counter", 0, expire: 2)
  .then {
    client.incr("counter", by: 10)
  }
  .then {
    client.get("counter")
  }
  .map {
    print("counter is:", $0)
  }

Status

The protocol implementation is considered complete. There are a few open ends in the telnet variant, yet the regular binary protocol is considered done.

The Redis client module has a few more open ends, but seems to work fine.

Who

Brought to you by ZeeZide. We like feedback, GitHub stars, cool contract work, presumably any form of praise you can think of.