Skip to content

Commit bf42613

Browse files
committed
Split hello from other pending commands
Move version to Version.swift Rename ValkeyPromise.ignore to forget Signed-off-by: Adam Fowler <[email protected]>
1 parent 0545ac4 commit bf42613

File tree

7 files changed

+65
-42
lines changed

7 files changed

+65
-42
lines changed

Sources/Valkey/Connection/ValkeyChannelHandler+stateMachine.swift

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,12 @@ extension ValkeyChannelHandler {
6565
@usableFromInline
6666
struct ConnectedState {
6767
let context: Context
68+
let pendingHelloCommand: PendingCommand
6869
var pendingCommands: Deque<PendingCommand>
6970

70-
func cancel(requestID: Int) -> Deque<PendingCommand>? {
71-
if pendingCommands.first?.requestID == requestID {
72-
return pendingCommands
71+
func cancel(requestID: Int) -> [PendingCommand]? {
72+
if pendingHelloCommand.requestID == requestID {
73+
return [pendingHelloCommand] + pendingCommands
7374
}
7475
return nil
7576
}
@@ -85,11 +86,11 @@ extension ValkeyChannelHandler {
8586

8687
/// handler has become active
8788
@usableFromInline
88-
mutating func setConnected(context: Context, pendingCommands: Deque<PendingCommand>) {
89+
mutating func setConnected(context: Context, pendingHelloCommand: PendingCommand, pendingCommands: Deque<PendingCommand>) {
8990
switch consume self.state {
9091
case .initialized:
9192
self = .connected(
92-
.init(context: context, pendingCommands: pendingCommands)
93+
.init(context: context, pendingHelloCommand: pendingHelloCommand, pendingCommands: pendingCommands)
9394
)
9495
case .connected:
9596
preconditionFailure("Cannot set connected state when state is connected")
@@ -155,18 +156,15 @@ extension ValkeyChannelHandler {
155156
switch consume self.state {
156157
case .initialized:
157158
preconditionFailure("Cannot send command when initialized")
158-
case .connected(var state):
159-
guard let helloCommand = state.pendingCommands.popFirst() else {
160-
preconditionFailure("Cannot be in connected state with no pending commands")
161-
}
159+
case .connected(let state):
162160
switch token.value {
163161
case .bulkError(let message), .simpleError(let message):
164162
let error = ValkeyClientError(.commandError, message: String(buffer: message))
165163
self = .closed(error)
166-
return .respondAndClose(helloCommand, error)
164+
return .respondAndClose(state.pendingHelloCommand, error)
167165
default:
168166
self = .active(.init(context: state.context, pendingCommands: state.pendingCommands))
169-
return .respond(helloCommand, .cancel)
167+
return .respond(state.pendingHelloCommand, .cancel)
170168
}
171169
case .active(var state):
172170
guard let command = state.pendingCommands.popFirst() else {
@@ -228,14 +226,11 @@ extension ValkeyChannelHandler {
228226
case .initialized:
229227
preconditionFailure("Cannot wait until connection has succeeded")
230228
case .connected(let state):
231-
guard let helloCommand = state.pendingCommands.first else {
232-
preconditionFailure("Cannot be in connected state with no pending commands")
233-
}
234-
switch helloCommand.promise {
229+
switch state.pendingHelloCommand.promise {
235230
case .nio(let promise):
236231
self = .connected(state)
237232
return .waitForPromise(promise)
238-
case .swift, .ignore:
233+
case .swift, .forget:
239234
preconditionFailure("Connected state cannot be setup with a Swift continuation")
240235
}
241236
case .active(let state):
@@ -263,15 +258,14 @@ extension ValkeyChannelHandler {
263258
case .initialized:
264259
preconditionFailure("Cannot cancel when initialized")
265260
case .connected(let state):
266-
guard let helloCommand = state.pendingCommands.first else {
267-
preconditionFailure("Cannot be in connected state with no pending commands")
268-
}
269-
if helloCommand.deadline <= now {
261+
if state.pendingHelloCommand.deadline <= now {
270262
self = .closed(ValkeyClientError(.timeout))
271-
return .failPendingCommandsAndClose(state.context, state.pendingCommands)
263+
var pendingCommands = state.pendingCommands
264+
pendingCommands.prepend(state.pendingHelloCommand)
265+
return .failPendingCommandsAndClose(state.context, pendingCommands)
272266
} else {
273267
self = .connected(state)
274-
return .reschedule(helloCommand.deadline)
268+
return .reschedule(state.pendingHelloCommand.deadline)
275269
}
276270
case .active(let state):
277271
if let firstCommand = state.pendingCommands.first {
@@ -373,7 +367,9 @@ extension ValkeyChannelHandler {
373367
self = .closed(nil)
374368
return .doNothing
375369
case .connected(let state):
376-
self = .closing(.init(context: state.context, pendingCommands: state.pendingCommands))
370+
var pendingCommands = state.pendingCommands
371+
pendingCommands.prepend(state.pendingHelloCommand)
372+
self = .closing(.init(context: state.context, pendingCommands: pendingCommands))
377373
return .waitForPendingCommands(state.context)
378374
case .active(let state):
379375
if state.pendingCommands.count > 0 {
@@ -406,6 +402,8 @@ extension ValkeyChannelHandler {
406402
return .doNothing
407403
case .connected(let state):
408404
self = .closed(nil)
405+
var pendingCommands = state.pendingCommands
406+
pendingCommands.prepend(state.pendingHelloCommand)
409407
return .failPendingCommandsAndClose(state.context, state.pendingCommands)
410408
case .active(let state):
411409
self = .closed(nil)
@@ -434,6 +432,8 @@ extension ValkeyChannelHandler {
434432
return .doNothing
435433
case .connected(let state):
436434
self = .closed(nil)
435+
var pendingCommands = state.pendingCommands
436+
pendingCommands.prepend(state.pendingHelloCommand)
437437
return .failPendingCommandsAndSubscriptions(state.pendingCommands)
438438
case .active(let state):
439439
self = .closed(nil)

Sources/Valkey/Connection/ValkeyChannelHandler.swift

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,15 @@ import NIOCore
2020
enum ValkeyPromise<T: Sendable>: Sendable {
2121
case nio(EventLoopPromise<T>)
2222
case swift(CheckedContinuation<T, any Error>)
23-
case ignore
23+
case forget
2424

2525
func succeed(_ t: T) {
2626
switch self {
2727
case .nio(let eventLoopPromise):
2828
eventLoopPromise.succeed(t)
2929
case .swift(let checkedContinuation):
3030
checkedContinuation.resume(returning: t)
31-
case .ignore:
31+
case .forget:
3232
break
3333
}
3434
}
@@ -39,7 +39,7 @@ enum ValkeyPromise<T: Sendable>: Sendable {
3939
eventLoopPromise.fail(e)
4040
case .swift(let checkedContinuation):
4141
checkedContinuation.resume(throwing: e)
42-
case .ignore:
42+
case .forget:
4343
break
4444
}
4545
}
@@ -288,8 +288,8 @@ final class ValkeyChannelHandler: ChannelInboundHandler {
288288
)
289289
)
290290
// set client info
291-
let clientInfoLibName = CLIENT.SETINFO(attr: .libname(ValkeyClient.libraryName))
292-
let clientInfoLibVersion = CLIENT.SETINFO(attr: .libver(ValkeyClient.libraryVersion))
291+
let clientInfoLibName = CLIENT.SETINFO(attr: .libname(valkeySwiftLibraryName))
292+
let clientInfoLibVersion = CLIENT.SETINFO(attr: .libver(valkeySwiftLibraryVersion))
293293

294294
self.encoder.reset()
295295
helloCommand.encode(into: &self.encoder)
@@ -304,10 +304,10 @@ final class ValkeyChannelHandler: ChannelInboundHandler {
304304

305305
self.stateMachine.setConnected(
306306
context: context,
307+
pendingHelloCommand: .init(promise: .nio(promise), requestID: 0, deadline: deadline),
307308
pendingCommands: [
308-
.init(promise: .nio(promise), requestID: 0, deadline: deadline), // HELLO
309-
.init(promise: .ignore, requestID: 0, deadline: deadline), // CLIENT.SETINFO libname
310-
.init(promise: .ignore, requestID: 0, deadline: deadline), // CLIENT.SETINFO libver
309+
.init(promise: .forget, requestID: 0, deadline: deadline), // CLIENT.SETINFO libname
310+
.init(promise: .forget, requestID: 0, deadline: deadline), // CLIENT.SETINFO libver
311311
]
312312
)
313313
}

Sources/Valkey/ValkeyClient.swift

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -162,14 +162,6 @@ extension ValkeyClient {
162162
}
163163
}
164164

165-
@available(valkeySwift 1.0, *)
166-
extension ValkeyClient {
167-
/// library name reported to server using CLIENT SETINFO
168-
package static var libraryName: String { "valkey-swift" }
169-
/// library version reported to server using CLIENT SETINFO
170-
package static var libraryVersion: String { "0.1.0" }
171-
}
172-
173165
#if ServiceLifecycleSupport
174166
@available(valkeySwift 1.0, *)
175167
extension ValkeyClient: Service {}

Sources/Valkey/Version.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the valkey-swift open source project
4+
//
5+
// Copyright (c) 2025 the valkey-swift project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See CONTRIBUTORS.txt for the list of valkey-swift project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
/// library name reported to server using CLIENT SETINFO
16+
package let valkeySwiftLibraryName = "valkey-swift"
17+
/// library version reported to server using CLIENT SETINFO
18+
package let valkeySwiftLibraryVersion = "0.1.0"

Tests/IntegrationTests/ValkeyTests.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -859,4 +859,16 @@ struct GeneratedCommands {
859859
}
860860
}
861861
}
862+
863+
@available(valkeySwift 1.0, *)
864+
@Test
865+
func testClientInfo() async throws {
866+
var logger = Logger(label: "Valkey")
867+
logger.logLevel = .trace
868+
try await withValkeyClient(.hostname(valkeyHostname, port: 6379), logger: logger) { client in
869+
let clients = try await String(buffer: client.clientList())
870+
#expect(clients.firstRange(of: "lib-name=\(valkeySwiftLibraryName)") != nil)
871+
#expect(clients.firstRange(of: "lib-ver=\(valkeySwiftLibraryVersion)") != nil)
872+
}
873+
}
862874
}

Tests/ValkeyTests/Utils/NIOAsyncTestingChannel+hello.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ extension NIOAsyncTestingChannel {
2424
var expectedBuffer = ByteBuffer()
2525
expectedBuffer.writeImmutableBuffer(RESPToken(.array([.bulkString("HELLO"), .bulkString("3")])).base)
2626
expectedBuffer.writeImmutableBuffer(
27-
RESPToken(.array([.bulkString("CLIENT"), .bulkString("SETINFO"), .bulkString("lib-name"), .bulkString(ValkeyClient.libraryName)])).base
27+
RESPToken(.array([.bulkString("CLIENT"), .bulkString("SETINFO"), .bulkString("lib-name"), .bulkString(valkeySwiftLibraryName)])).base
2828
)
2929
expectedBuffer.writeImmutableBuffer(
30-
RESPToken(.array([.bulkString("CLIENT"), .bulkString("SETINFO"), .bulkString("lib-ver"), .bulkString(ValkeyClient.libraryVersion)])).base
30+
RESPToken(.array([.bulkString("CLIENT"), .bulkString("SETINFO"), .bulkString("lib-ver"), .bulkString(valkeySwiftLibraryVersion)])).base
3131
)
3232
#expect(hello == expectedBuffer)
3333
try await self.writeInbound(

Tests/ValkeyTests/ValkeyChannelHandlerStateMachineTests.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -543,7 +543,8 @@ extension ValkeyChannelHandler.StateMachine {
543543
let promise = EmbeddedEventLoop().makePromise(of: RESPToken.self)
544544
self.setConnected(
545545
context: context,
546-
pendingCommands: [.init(promise: .nio(promise), requestID: 0, deadline: .now() + .seconds(30))]
546+
pendingHelloCommand: .init(promise: .nio(promise), requestID: 0, deadline: .now() + .seconds(30)),
547+
pendingCommands: []
547548
)
548549
}
549550

0 commit comments

Comments
 (0)