Skip to content

Commit

Permalink
Merge branch 'chore/update-nio-api' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
helje5 committed Jan 29, 2024
2 parents e711ec5 + fa9610e commit 24dacc3
Show file tree
Hide file tree
Showing 18 changed files with 133 additions and 159 deletions.
3 changes: 1 addition & 2 deletions .github/workflows/swift.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ jobs:
fail-fast: false
matrix:
image:
- swift:4.2.4
- swift:5.6.1-bionic
- swift:5.9.2-focal
container: ${{ matrix.image }}
Expand All @@ -25,7 +24,7 @@ jobs:
- name: Build Swift Release Package
run: swift build -c release
nextstep:
runs-on: macos-latest
runs-on: macos-13
steps:
- name: Select latest available Xcode
uses: maxim-lobanov/setup-xcode@v1
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,5 @@ fastlane/test_output
.build-linux*
Package.resolved
dump*.json
.swiftpm

22 changes: 0 additions & 22 deletions .travis.d/before-install.sh

This file was deleted.

32 changes: 0 additions & 32 deletions .travis.d/install.sh

This file was deleted.

7 changes: 4 additions & 3 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// swift-tools-version:4.0
// swift-tools-version:5.0

import PackageDescription

Expand All @@ -10,10 +10,11 @@ let package = Package(
],
dependencies: [
.package(url: "https://github.com/SwiftNIOExtras/swift-nio-redis.git",
from: "0.9.0")
from: "0.11.0"),
.package(url: "https://github.com/apple/swift-atomics", from: "1.0.0")
],
targets: [
.target(name: "RedisServer", dependencies: [ "NIORedis" ]),
.target(name: "RedisServer", dependencies: [ "NIORedis", "Atomics" ]),
.target(name: "redi-s", dependencies: [ "RedisServer" ])
]
)
20 changes: 19 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,25 @@ Contributions welcome!! A lot of the missing stuff is really easy to add!
Performance differs, e.g. lists are implemented using arrays (hence RPUSH is
okayish, LPUSH is very slow).
But looking at just the simple GET/SET, it is surprisingly close to the
highly optimized C implementation:
highly optimized C implementation.

### 2024-01-30 Swift 5.9.2

Redi/S (1 NIO thread on M1 Mac Mini):
```
helge@M1ni ~ $ redis-benchmark -p 1337 -t SET,GET,RPUSH,INCR -n 500000 -q
WARNING: Could not fetch server CONFIG
SET: 163345.31 requests per second, p50=0.255 msec
GET: 167336.02 requests per second, p50=0.239 msec
INCR: 158780.56 requests per second, p50=0.239 msec
RPUSH: 157480.31 requests per second, p50=0.271 msec
```

Note that more threads end up being worse. Not entirely sure why.

### Those Are Older Numbers from 2018

- using Swift 4.2 on Intel, IIRC

Redi/S (2 NIO threads on MacPro 3,7 GHz Quad-Core Intel Xeon E5):
```
Expand Down
2 changes: 1 addition & 1 deletion Sources/RedisServer/Commands/CommandTable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ extension RedisServer {
static let defaultCommandTable : RedisCommandTable = [
// command is funny in that arity is 0
Command(name : "COMMAND",
type : .optionalValue(Commands.COMMAND), // FIXME: multivalue
type : .optionalValue(Commands.COMMAND), // FIXME: multivalue!
flags : [ .loading, .stale ]),

Command(name : "PING",
Expand Down
35 changes: 25 additions & 10 deletions Sources/RedisServer/Commands/ServerCommands.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//
// This source file is part of the swift-nio-redis open source project
//
// Copyright (c) 2018 ZeeZide GmbH. and the swift-nio-redis project authors
// Copyright (c) 2018-2024 ZeeZide GmbH. and the swift-nio-redis project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
Expand All @@ -24,13 +24,27 @@ extension Commands {
let commandTable = ctx.handler.server.commandTable

if let value = value {
// TODO: Only supports one parameter here.
guard let s = value.stringValue else {
throw RedisError.unknownSubcommand // TBD? ProtocolError?
}

switch s.uppercased() {
case "COUNT": ctx.write(commandTable.count)
default: throw RedisError.unknownSubcommand
case "COUNT":
ctx.write(commandTable.count)
case "LIST":
// TODO: [FILTERBY <MODULE name| ACLCAT cat| PATTERN ...>]
ctx.write(commandTable.map(\.name))
case "DOCS":
throw RedisError.unsupportedSubcommand
case "GETKEYS":
throw RedisError.unsupportedSubcommand
case "GETKEYSANDFLAGS":
throw RedisError.unsupportedSubcommand
case "INFO":
throw RedisError.unsupportedSubcommand
default:
throw RedisError.unknownSubcommand
}
}
else {
Expand Down Expand Up @@ -91,18 +105,20 @@ extension Commands {

static func MONITOR(_ ctx: CommandContext) throws {
let client = ctx.handler
guard !client.isMonitoring.load() else { return ctx.write(RESPValue.ok) }
guard !client.isMonitoring.load(ordering: .relaxed) else {
return ctx.write(RESPValue.ok)
}

client.isMonitoring.store(true)
_ = client.server.monitors.add(1)
client.isMonitoring.store(true, ordering: .relaxed)
client.server.monitors.wrappingIncrement(ordering: .relaxed)
ctx.write(RESPValue.ok)
}

static func QUIT(_ ctx: CommandContext) throws {
ctx.context.channel.close(mode: .input, promise: nil)

ctx.context.writeAndFlush(NIOAny(RESPValue.ok))
.whenComplete {
.whenComplete { _ in
ctx.context.channel.close(promise: nil)
}
}
Expand Down Expand Up @@ -167,7 +183,6 @@ extension Commands {

// do not block the server
listQueue.async {
let nl : [ UInt8 ] = [ 10 ]
var count = clients.count
guard count > 0 else { return ctx.write("") } // Never

Expand All @@ -177,8 +192,8 @@ extension Commands {
assert(count > 0)
count -= 1

result.write(string: info.redisClientLogLine)
result.write(bytes: nl)
result.writeString(info.redisClientLogLine)
result.writeInteger(10 as UInt8)

if count == 0 {
ctx.write(.bulkString(result))
Expand Down
12 changes: 6 additions & 6 deletions Sources/RedisServer/Commands/StringCommands.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//
// This source file is part of the swift-nio-redis open source project
//
// Copyright (c) 2018 ZeeZide GmbH. and the swift-nio-redis project authors
// Copyright (c) 2018-2024 ZeeZide GmbH. and the swift-nio-redis project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
Expand All @@ -25,10 +25,10 @@ extension Commands {
{
guard var bb = value.byteBuffer else { throw RedisError.wrongType }

let result : Int = try ctx.writeInDatabase { db in
if let oldValue = db[key] {
let result : Int = try ctx.writeInDatabase { ( db : Databases.Database ) in
if let oldValue : RedisValue = db[key] {
guard case .string(var s) = oldValue else { throw RedisError.wrongType }
s.write(buffer: &bb)
s.writeBuffer(&bb)
db[key] = .string(s)
return s.readableBytes
}
Expand Down Expand Up @@ -253,11 +253,11 @@ extension Commands {

if index > s.readableBytes { // if index > count, 0-padded!!!
let countToWrite = index - s.readableBytes
s.write(bytes: repeatElement(UInt8(0), count: countToWrite))
s.writeRepeatingByte(0, count: countToWrite)
}

s.moveWriterIndex(to: s.readerIndex + index)
s.write(buffer: &bb)
s.writeBuffer(&bb)

db[key] = .string(s)
return s.readableBytes
Expand Down
22 changes: 14 additions & 8 deletions Sources/RedisServer/Helpers/RedisLogger.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//
// This source file is part of the swift-nio-redis open source project
//
// Copyright (c) 2018 ZeeZide GmbH. and the swift-nio-redis project authors
// Copyright (c) 2018-2024 ZeeZide GmbH. and the swift-nio-redis project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
Expand All @@ -22,22 +22,26 @@ public protocol RedisLogger {

public extension RedisLogger {

public func error(_ msg: @autoclosure () -> String, _ values: Any?...) {
@inlinable
func error(_ msg: @autoclosure () -> String, _ values: Any?...) {
primaryLog(.Error, msg, values)
}
public func warn (_ msg: @autoclosure () -> String, _ values: Any?...) {
@inlinable
func warn (_ msg: @autoclosure () -> String, _ values: Any?...) {
primaryLog(.Warn, msg, values)
}
public func log (_ msg: @autoclosure () -> String, _ values: Any?...) {
@inlinable
func log (_ msg: @autoclosure () -> String, _ values: Any?...) {
primaryLog(.Log, msg, values)
}
public func info (_ msg: @autoclosure () -> String, _ values: Any?...) {
@inlinable
func info (_ msg: @autoclosure () -> String, _ values: Any?...) {
primaryLog(.Info, msg, values)
}
public func trace(_ msg: @autoclosure () -> String, _ values: Any?...) {
@inlinable
func trace(_ msg: @autoclosure () -> String, _ values: Any?...) {
primaryLog(.Trace, msg, values)
}

}

public enum RedisLogLevel : Int8 {
Expand Down Expand Up @@ -86,10 +90,13 @@ fileprivate let redisLogDateFmt : DateFormatter = {
return formatter
}()

private let pid = getpid()

public struct RedisPrintLogger : RedisLogger {

public let logLevel : LogLevel

@inlinable
public init(logLevel: LogLevel = .Log) {
self.logLevel = logLevel
}
Expand All @@ -100,7 +107,6 @@ public struct RedisPrintLogger : RedisLogger {
{
guard logLevel.rawValue <= self.logLevel.rawValue else { return }

let pid = getpid()
let now = Date()

let prefix =
Expand Down
6 changes: 4 additions & 2 deletions Sources/RedisServer/Server/PubSub.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//
// This source file is part of the swift-nio-redis open source project
//
// Copyright (c) 2018 ZeeZide GmbH. and the swift-nio-redis project authors
// Copyright (c) 2018-2024 ZeeZide GmbH. and the swift-nio-redis project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
Expand Down Expand Up @@ -138,7 +138,9 @@ class PubSub {

guard var loopToSubscribers = registry[key] else { return }
guard var subscribers = loopToSubscribers[loopID] else { return }
guard let idx = subscribers.index(where: { $0 === handler }) else { return }
guard let idx = subscribers.firstIndex(where: { $0 === handler }) else {
return
}

subscribers.remove(at: idx)
if subscribers.isEmpty {
Expand Down
11 changes: 6 additions & 5 deletions Sources/RedisServer/Server/RedisCommandContext.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//
// This source file is part of the swift-nio-redis open source project
//
// Copyright (c) 2018 ZeeZide GmbH. and the swift-nio-redis project authors
// Copyright (c) 2018-2024 ZeeZide GmbH. and the swift-nio-redis project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
Expand Down Expand Up @@ -118,12 +118,13 @@ public struct RedisCommandContext {
let handler = self.handler

if eventLoop.inEventLoop {
handler.write(ctx: context, value: value.toRESPValue(), promise: nil)
handler.write(context: context, value: value.toRESPValue(), promise: nil)
if flush { context.channel.flush() }
}
else {
eventLoop.execute {
handler.write(ctx: context, value: value.toRESPValue(), promise: nil)
handler.write(context: context, value: value.toRESPValue(),
promise: nil)
if flush { context.channel.flush() }
}
}
Expand All @@ -134,12 +135,12 @@ public struct RedisCommandContext {
let handler = self.handler

if eventLoop.inEventLoop {
handler.write(ctx: context, value: value, promise: nil)
handler.write(context: context, value: value, promise: nil)
if flush { context.channel.flush() }
}
else {
eventLoop.execute {
handler.write(ctx: context, value: value, promise: nil)
handler.write(context: context, value: value, promise: nil)
if flush { context.channel.flush() }
}
}
Expand Down
Loading

0 comments on commit 24dacc3

Please sign in to comment.