Skip to content

Commit dfebc67

Browse files
authored
RESPBulkString (#271)
* RESPBulkString Replace ByteBuffer with RESPBulkString as return type from commands that return a bulk string Signed-off-by: Adam Fowler <adamfowler71@gmail.com> * Fixup custom commands to use RESPBulkString Signed-off-by: Adam Fowler <adamfowler71@gmail.com> * Fix gitignore, so we can add RESPBulkString Signed-off-by: Adam Fowler <adamfowler71@gmail.com> * Remove fromBulkString in init Signed-off-by: Adam Fowler <adamfowler71@gmail.com> * Update documentation Signed-off-by: Adam Fowler <adamfowler71@gmail.com> * Update docs again Signed-off-by: Adam Fowler <adamfowler71@gmail.com> * Added tests Signed-off-by: Adam Fowler <adamfowler71@gmail.com> --------- Signed-off-by: Adam Fowler <adamfowler71@gmail.com>
1 parent 5be72b2 commit dfebc67

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+626
-445
lines changed

Benchmarks/ValkeyBenchmarks/ValkeyClientBenchmarks.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ func makeClientGETSequentialBenchmark() -> Benchmark? {
4242
benchmark.startMeasurement()
4343
for _ in benchmark.scaledIterations {
4444
let foo = try await client.get("foo")
45-
precondition(foo.map { String(buffer: $0) } == "Bar")
45+
precondition(foo.map { String($0) } == "Bar")
4646
}
4747
benchmark.stopMeasurement()
4848

@@ -87,7 +87,7 @@ func makeClient20ConcurrentGETBenchmark() -> Benchmark? {
8787
group.addTask {
8888
for _ in 0..<iterationsPerConnection {
8989
let foo = try await client.get("foo")
90-
precondition(foo.map { String(buffer: $0) } == "Bar")
90+
precondition(foo.map { String($0) } == "Bar")
9191
}
9292
}
9393
}
@@ -138,7 +138,7 @@ func makeClient50Concurrent20ConnectionGETBenchmark() -> Benchmark? {
138138
group.addTask {
139139
for _ in 0..<iterationsPerConnection {
140140
let foo = try await client.get("foo")
141-
precondition(foo.map { String(buffer: $0) } == "Bar")
141+
precondition(foo.map { String($0) } == "Bar")
142142
}
143143
}
144144
}

Benchmarks/ValkeyBenchmarks/ValkeyConnectionBenchmark.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ func makeConnectionGETBenchmark() -> Benchmark? {
8181
benchmark.startMeasurement()
8282
for _ in benchmark.scaledIterations {
8383
let foo = try await connection.get("foo")
84-
precondition(foo.map { String(buffer: $0) } == "Bar")
84+
precondition(foo.map { String($0) } == "Bar")
8585
}
8686
benchmark.stopMeasurement()
8787
}
@@ -112,7 +112,7 @@ func makeConnectionGETNoOpTracerBenchmark() -> Benchmark? {
112112
benchmark.startMeasurement()
113113
for _ in benchmark.scaledIterations {
114114
let foo = try await connection.get("foo")
115-
precondition(foo.map { String(buffer: $0) } == "Bar")
115+
precondition(foo.map { String($0) } == "Bar")
116116
}
117117
benchmark.stopMeasurement()
118118
}
@@ -145,7 +145,7 @@ func makeConnectionPipelineBenchmark() -> Benchmark? {
145145
GET("foo"),
146146
GET("foo")
147147
)
148-
let result = try foo.2.get().map { String(buffer: $0) }
148+
let result = try foo.2.get().map { String($0) }
149149
precondition(result == "Bar")
150150
}
151151
benchmark.stopMeasurement()

Package.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ let defaultSwiftSettings: [SwiftSetting] =
1010

1111
// https://github.com/swiftlang/swift-evolution/blob/main/proposals/0444-member-import-visibility.md
1212
.enableUpcomingFeature("MemberImportVisibility"),
13+
14+
// https://forums.swift.org/t/experimental-support-for-lifetime-dependencies-in-swift-6-2-and-beyond/78638
15+
.enableExperimentalFeature("Lifetimes"),
1316
]
1417

1518
let package = Package(
@@ -29,7 +32,7 @@ let package = Package(
2932
.package(url: "https://github.com/apple/swift-collections.git", from: "1.1.4"),
3033
.package(url: "https://github.com/apple/swift-log.git", from: "1.6.3"),
3134
.package(url: "https://github.com/apple/swift-distributed-tracing.git", from: "1.3.0"),
32-
.package(url: "https://github.com/apple/swift-nio.git", from: "2.81.0"),
35+
.package(url: "https://github.com/apple/swift-nio.git", from: "2.90.0"),
3336
.package(url: "https://github.com/apple/swift-nio-ssl.git", from: "2.29.0"),
3437
.package(url: "https://github.com/apple/swift-nio-transport-services.git", from: "1.26.0"),
3538
.package(url: "https://github.com/swift-server/swift-service-lifecycle.git", from: "2.8.0"),

Sources/Valkey/Cluster/ValkeyClusterError.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,6 @@ public struct ValkeyClusterError: Error, Equatable {
5959
/// Wait for discovery failed three times after receiving a MOVED error
6060
static public var waitedForDiscoveryAfterMovedErrorThreeTimes: Self { .init(.waitedForDiscoveryAfterMovedErrorThreeTimes) }
6161
/// Pipelined result not returned. If you receive this, it is an internal error and should be reported as a bug
62-
static public var pipelinedResultNotReturned: Self { .init(.waitedForDiscoveryAfterMovedErrorThreeTimes) }
62+
static public var pipelinedResultNotReturned: Self { .init(.pipelinedResultNotReturned) }
6363

6464
}

Sources/Valkey/Commands/ClusterCommands.swift

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ public enum CLUSTER {
7474
/// Advances the cluster config epoch.
7575
@_documentation(visibility: internal)
7676
public struct BUMPEPOCH: ValkeyCommand {
77-
public typealias Response = ByteBuffer
77+
public typealias Response = RESPBulkString
7878

7979
@inlinable public static var name: String { "CLUSTER BUMPEPOCH" }
8080

@@ -113,7 +113,7 @@ public enum CLUSTER {
113113
}
114114

115115
@inlinable public func encode(into commandEncoder: inout ValkeyCommandEncoder) {
116-
commandEncoder.encodeArray("CLUSTER", "COUNT-FAILURE-REPORTS", RESPBulkString(nodeId))
116+
commandEncoder.encodeArray("CLUSTER", "COUNT-FAILURE-REPORTS", RESPRenderableBulkString(nodeId))
117117
}
118118
}
119119

@@ -277,7 +277,7 @@ public enum CLUSTER {
277277
}
278278

279279
@inlinable public func encode(into commandEncoder: inout ValkeyCommandEncoder) {
280-
commandEncoder.encodeArray("CLUSTER", "FORGET", RESPBulkString(nodeId))
280+
commandEncoder.encodeArray("CLUSTER", "FORGET", RESPRenderableBulkString(nodeId))
281281
}
282282
}
283283

@@ -332,7 +332,7 @@ public enum CLUSTER {
332332
/// Returns information about the state of a node.
333333
@_documentation(visibility: internal)
334334
public struct INFO: ValkeyCommand {
335-
public typealias Response = ByteBuffer
335+
public typealias Response = RESPBulkString
336336

337337
@inlinable public static var name: String { "CLUSTER INFO" }
338338

@@ -358,7 +358,7 @@ public enum CLUSTER {
358358
}
359359

360360
@inlinable public func encode(into commandEncoder: inout ValkeyCommandEncoder) {
361-
commandEncoder.encodeArray("CLUSTER", "KEYSLOT", RESPBulkString(key))
361+
commandEncoder.encodeArray("CLUSTER", "KEYSLOT", RESPRenderableBulkString(key))
362362
}
363363
}
364364

@@ -391,7 +391,7 @@ public enum CLUSTER {
391391
}
392392

393393
@inlinable public func encode(into commandEncoder: inout ValkeyCommandEncoder) {
394-
commandEncoder.encodeArray("CLUSTER", "MEET", RESPBulkString(ip), port, clusterBusPort)
394+
commandEncoder.encodeArray("CLUSTER", "MEET", RESPRenderableBulkString(ip), port, clusterBusPort)
395395
}
396396
}
397397

@@ -431,15 +431,15 @@ public enum CLUSTER {
431431

432432
@inlinable
433433
public var respEntries: Int {
434-
"SLOTSRANGE".respEntries + ranges.respEntries + "NODE".respEntries + RESPBulkString(nodeId).respEntries
434+
"SLOTSRANGE".respEntries + ranges.respEntries + "NODE".respEntries + RESPRenderableBulkString(nodeId).respEntries
435435
}
436436

437437
@inlinable
438438
public func encode(into commandEncoder: inout ValkeyCommandEncoder) {
439439
"SLOTSRANGE".encode(into: &commandEncoder)
440440
ranges.encode(into: &commandEncoder)
441441
"NODE".encode(into: &commandEncoder)
442-
RESPBulkString(nodeId).encode(into: &commandEncoder)
442+
RESPRenderableBulkString(nodeId).encode(into: &commandEncoder)
443443
}
444444
}
445445
@inlinable public static var name: String { "CLUSTER MIGRATESLOTS" }
@@ -484,7 +484,7 @@ public enum CLUSTER {
484484
/// Returns the cluster configuration for a node.
485485
@_documentation(visibility: internal)
486486
public struct NODES: ValkeyCommand {
487-
public typealias Response = ByteBuffer
487+
public typealias Response = RESPBulkString
488488

489489
@inlinable public static var name: String { "CLUSTER NODES" }
490490

@@ -510,7 +510,7 @@ public enum CLUSTER {
510510
}
511511

512512
@inlinable public func encode(into commandEncoder: inout ValkeyCommandEncoder) {
513-
commandEncoder.encodeArray("CLUSTER", "REPLICAS", RESPBulkString(nodeId))
513+
commandEncoder.encodeArray("CLUSTER", "REPLICAS", RESPRenderableBulkString(nodeId))
514514
}
515515
}
516516

@@ -700,7 +700,7 @@ public enum CLUSTER {
700700
}
701701

702702
@inlinable public func encode(into commandEncoder: inout ValkeyCommandEncoder) {
703-
commandEncoder.encodeArray("CLUSTER", "SLAVES", RESPBulkString(nodeId))
703+
commandEncoder.encodeArray("CLUSTER", "SLAVES", RESPRenderableBulkString(nodeId))
704704
}
705705
}
706706

@@ -896,7 +896,7 @@ extension ValkeyClientProtocol {
896896
/// * [String]: If the node already has the greatest config epoch in the cluster.
897897
@inlinable
898898
@discardableResult
899-
public func clusterBumpepoch() async throws -> ByteBuffer {
899+
public func clusterBumpepoch() async throws -> RESPBulkString {
900900
try await execute(CLUSTER.BUMPEPOCH())
901901
}
902902

@@ -1038,7 +1038,7 @@ extension ValkeyClientProtocol {
10381038
/// - Response: [String]: A map between named fields and values in the form of <field>:<value> lines separated by newlines composed by the two bytes CRLF
10391039
@inlinable
10401040
@discardableResult
1041-
public func clusterInfo() async throws -> ByteBuffer {
1041+
public func clusterInfo() async throws -> RESPBulkString {
10421042
try await execute(CLUSTER.INFO())
10431043
}
10441044

@@ -1120,7 +1120,7 @@ extension ValkeyClientProtocol {
11201120
/// - Response: [String]: The serialized cluster configuration.
11211121
@inlinable
11221122
@discardableResult
1123-
public func clusterNodes() async throws -> ByteBuffer {
1123+
public func clusterNodes() async throws -> RESPBulkString {
11241124
try await execute(CLUSTER.NODES())
11251125
}
11261126

Sources/Valkey/Commands/ConnectionCommands.swift

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,14 @@ extension CLIENT {
5959
}
6060

6161
@inlinable public func encode(into commandEncoder: inout ValkeyCommandEncoder) {
62-
commandEncoder.encodeArray("CLIENT", "CAPA", capabilities.map { RESPBulkString($0) })
62+
commandEncoder.encodeArray("CLIENT", "CAPA", capabilities.map { RESPRenderableBulkString($0) })
6363
}
6464
}
6565

6666
/// Returns the name of the connection.
6767
@_documentation(visibility: internal)
6868
public struct GETNAME: ValkeyCommand {
69-
public typealias Response = ByteBuffer?
69+
public typealias Response = RESPBulkString?
7070

7171
@inlinable public static var name: String { "CLIENT GETNAME" }
7272

@@ -157,7 +157,7 @@ extension CLIENT {
157157
/// Returns information about the connection.
158158
@_documentation(visibility: internal)
159159
public struct INFO: ValkeyCommand {
160-
public typealias Response = ByteBuffer
160+
public typealias Response = RESPBulkString
161161

162162
@inlinable public static var name: String { "CLIENT INFO" }
163163

@@ -419,7 +419,7 @@ extension CLIENT {
419419
}
420420
}
421421
}
422-
public typealias Response = ByteBuffer
422+
public typealias Response = RESPBulkString
423423

424424
@inlinable public static var name: String { "CLIENT LIST" }
425425

@@ -720,7 +720,7 @@ extension CLIENT {
720720
}
721721

722722
@inlinable public func encode(into commandEncoder: inout ValkeyCommandEncoder) {
723-
commandEncoder.encodeArray("CLIENT", "SETNAME", RESPBulkString(connectionName))
723+
commandEncoder.encodeArray("CLIENT", "SETNAME", RESPRenderableBulkString(connectionName))
724724
}
725725
}
726726

@@ -864,7 +864,7 @@ public struct AUTH<Password: RESPStringRenderable>: ValkeyCommand {
864864
}
865865

866866
@inlinable public func encode(into commandEncoder: inout ValkeyCommandEncoder) {
867-
commandEncoder.encodeArray("AUTH", username, RESPBulkString(password))
867+
commandEncoder.encodeArray("AUTH", username, RESPRenderableBulkString(password))
868868
}
869869
}
870870

@@ -884,7 +884,7 @@ public struct CLIENT: ValkeyCommand {
884884
/// Returns the given string.
885885
@_documentation(visibility: internal)
886886
public struct ECHO<Message: RESPStringRenderable>: ValkeyCommand {
887-
public typealias Response = ByteBuffer
887+
public typealias Response = RESPBulkString
888888

889889
@inlinable public static var name: String { "ECHO" }
890890

@@ -895,7 +895,7 @@ public struct ECHO<Message: RESPStringRenderable>: ValkeyCommand {
895895
}
896896

897897
@inlinable public func encode(into commandEncoder: inout ValkeyCommandEncoder) {
898-
commandEncoder.encodeArray("ECHO", RESPBulkString(message))
898+
commandEncoder.encodeArray("ECHO", RESPRenderableBulkString(message))
899899
}
900900
}
901901

@@ -1164,7 +1164,7 @@ extension ValkeyClientProtocol {
11641164
notDb: Int? = nil,
11651165
notCapa: String? = nil,
11661166
notIp: String? = nil
1167-
) async throws -> ByteBuffer {
1167+
) async throws -> RESPBulkString {
11681168
try await execute(
11691169
CLIENT.LIST(
11701170
clientType: clientType,
@@ -1273,7 +1273,7 @@ extension ValkeyClientProtocol {
12731273
/// - Response: [String]: The given string
12741274
@inlinable
12751275
@discardableResult
1276-
public func echo<Message: RESPStringRenderable>(message: Message) async throws -> ByteBuffer {
1276+
public func echo<Message: RESPStringRenderable>(message: Message) async throws -> RESPBulkString {
12771277
try await execute(ECHO(message: message))
12781278
}
12791279

@@ -1361,7 +1361,7 @@ extension ValkeyConnection {
13611361
/// * [Null]: Connection name was not set
13621362
@inlinable
13631363
@discardableResult
1364-
public func clientGetname() async throws -> ByteBuffer? {
1364+
public func clientGetname() async throws -> RESPBulkString? {
13651365
try await execute(CLIENT.GETNAME())
13661366
}
13671367

@@ -1385,7 +1385,7 @@ extension ValkeyConnection {
13851385
/// - Response: [String]: A unique string, as described at the CLIENT LIST page, for the current client.
13861386
@inlinable
13871387
@discardableResult
1388-
public func clientInfo() async throws -> ByteBuffer {
1388+
public func clientInfo() async throws -> RESPBulkString {
13891389
try await execute(CLIENT.INFO())
13901390
}
13911391

Sources/Valkey/Commands/Custom/HashCustomCommands.swift

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ import NIOCore
1010
/// Sorted set entry
1111
@_documentation(visibility: internal)
1212
public struct HashEntry: RESPTokenDecodable, Sendable {
13-
public let field: ByteBuffer
14-
public let value: ByteBuffer
13+
public let field: RESPBulkString
14+
public let value: RESPBulkString
1515

16-
init(field: ByteBuffer, value: ByteBuffer) {
16+
init(field: RESPBulkString, value: RESPBulkString) {
1717
self.field = field
1818
self.value = value
1919
}
@@ -40,17 +40,17 @@ extension HSCAN {
4040

4141
/// if HSCAN was called with the `NOVALUES` parameter use this
4242
/// function to get an array of fields
43-
public func withoutValues() throws -> [ByteBuffer] {
44-
try self.elements.decode(as: [ByteBuffer].self)
43+
public func withoutValues() throws -> [RESPBulkString] {
44+
try self.elements.decode(as: [RESPBulkString].self)
4545
}
4646

4747
/// if HSCAN was called without the `NOVALUES` parameter use this
4848
/// function to get an array of fields and values
4949
public func withValues() throws -> [HashEntry] {
5050
var array: [HashEntry] = []
5151
for respElement in try self.elements.asMap() {
52-
let field = try ByteBuffer(fromRESP: respElement.key)
53-
let value = try ByteBuffer(fromRESP: respElement.value)
52+
let field = try RESPBulkString(fromRESP: respElement.key)
53+
let value = try RESPBulkString(fromRESP: respElement.value)
5454
array.append(.init(field: field, value: value))
5555
}
5656
return array
@@ -78,22 +78,22 @@ extension HRANDFIELD {
7878
}
7979

8080
/// Get single random field when HRANDFIELD was called without COUNT
81-
/// - Returns: Random field name as ByteBuffer, or nil if key doesn't exist
81+
/// - Returns: Random field name as RESPBulkString, or nil if key doesn't exist
8282
/// - Throws: RESPDecodeError if response format is unexpected
83-
public func singleField() throws -> ByteBuffer? {
83+
public func singleField() throws -> RESPBulkString? {
8484
// Handle .null as it is expected when the key doesn't exist
8585
if token.value == .null {
8686
return nil
8787
}
88-
return try ByteBuffer(fromRESP: token)
88+
return try RESPBulkString(fromRESP: token)
8989
}
9090

9191
/// Get multiple random fields when HRANDFIELD was called with COUNT but without WITHVALUES
92-
/// - Returns: Array of field names as ByteBuffer, or empty array if key doesn't exist
92+
/// - Returns: Array of field names as RESPBulkString, or empty array if key doesn't exist
9393
/// - Throws: RESPDecodeError if response format is unexpected
9494
@inlinable
95-
public func multipleFields() throws -> [ByteBuffer]? {
96-
try [ByteBuffer]?(fromRESP: token)
95+
public func multipleFields() throws -> [RESPBulkString]? {
96+
try [RESPBulkString]?(fromRESP: token)
9797
}
9898

9999
/// Get multiple random field-value pairs when HRANDFIELD was called with COUNT and WITHVALUES
@@ -141,8 +141,8 @@ extension HRANDFIELD {
141141
// Iterate over pairs
142142
var iterator = array.makeIterator()
143143
while let field = iterator.next(), let value = iterator.next() {
144-
let fieldBuffer = try ByteBuffer(fromRESP: field)
145-
let valueBuffer = try ByteBuffer(fromRESP: value)
144+
let fieldBuffer = try RESPBulkString(fromRESP: field)
145+
let valueBuffer = try RESPBulkString(fromRESP: value)
146146
entries.append(HashEntry(field: fieldBuffer, value: valueBuffer))
147147
}
148148

0 commit comments

Comments
 (0)