Skip to content

Commit b2367ac

Browse files
committed
81 -- Add Configuration types for initialization
1 parent ec1a38b commit b2367ac

14 files changed

+699
-200
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,9 @@ import NIO
6060
import RediStack
6161

6262
let eventLoop: EventLoop = ...
63-
let connection = RedisConnection.connect(
64-
to: try .init(ipAddress: "127.0.0.1", port: RedisConnection.defaultPort),
65-
on: eventLoop
63+
let connection = RedisConnection.make(
64+
configuration: try .init(hostname: "127.0.0.1"),
65+
boundEventLoop: eventLoop
6666
).wait()
6767

6868
let result = try connection.set("my_key", to: "some value")

Sources/RediStack/Configuration.swift

Lines changed: 315 additions & 0 deletions
Large diffs are not rendered by default.

Sources/RediStack/RedisConnection.swift

Lines changed: 40 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -20,71 +20,71 @@ import NIO
2020
import NIOConcurrencyHelpers
2121

2222
extension RedisConnection {
23-
/// The documented default port that Redis connects through.
24-
///
25-
/// See [https://redis.io/topics/quickstart](https://redis.io/topics/quickstart)
26-
public static let defaultPort = 6379
2723

28-
/// Creates a new connection to a Redis instance.
24+
/// Creates a new connection with provided configuration and sychronization objects.
2925
///
30-
/// If you would like to specialize the `NIO.ClientBootstrap` that the connection communicates on, override the default by passing it in as `tcpClient`.
26+
/// If you would like to specialize the `NIO.ClientBootstrap` that the connection communicates on, override the default by passing it in as `configuredTCPClient`.
3127
///
3228
/// let eventLoopGroup: EventLoopGroup = ...
3329
/// var customTCPClient = ClientBootstrap.makeRedisTCPClient(group: eventLoopGroup)
3430
/// customTCPClient.channelInitializer { channel in
3531
/// // channel customizations
3632
/// }
37-
/// let connection = RedisConnection.connect(
38-
/// to: ...,
39-
/// on: eventLoopGroup.next(),
40-
/// password: ...,
41-
/// tcpClient: customTCPClient
33+
/// let connection = RedisConnection.make(
34+
/// configuration: ...,
35+
/// boundEventLoop: eventLoopGroup.next(),
36+
/// configuredTCPClient: customTCPClient
4237
/// ).wait()
4338
///
4439
/// It is recommended that you be familiar with `ClientBootstrap.makeRedisTCPClient(group:)` and `NIO.ClientBootstrap` in general before doing so.
4540
///
4641
/// Note: Use of `wait()` in the example is for simplicity. Never call `wait()` on an event loop.
4742
///
4843
/// - Important: Call `close()` on the connection before letting the instance deinit to properly cleanup resources.
49-
/// - Note: If a `password` is provided, the connection will send an "AUTH" command to Redis as soon as it has been opened.
50-
///
44+
/// - Invariant: If a `password` is provided in the configuration, the connection will send an "AUTH" command to Redis as soon as it has been opened.
45+
/// - Invariant: If a `database` index is provided in the configuration, the connection will send a "SELECT" command to Redis after it has been authenticated.
5146
/// - Parameters:
52-
/// - socket: The `NIO.SocketAddress` information of the Redis instance to connect to.
53-
/// - eventLoop: The `NIO.EventLoop` that this connection will execute all tasks on.
54-
/// - password: The optional password to use for authorizing the connection with Redis.
55-
/// - logger: The `Logging.Logger` instance to use for all client logging purposes. If one is not provided, one will be created.
56-
/// A `Foundation.UUID` will be attached to the metadata to uniquely identify this connection instance's logs.
57-
/// - tcpClient: If you have chosen to configure a `NIO.ClientBootstrap` yourself, this will be used instead of the `makeRedisTCPClient` instance.
58-
/// - Returns: A `NIO.EventLoopFuture` that resolves with the new connection after it has been opened, and if a `password` is provided, authenticated.
59-
public static func connect(
60-
to socket: SocketAddress,
61-
on eventLoop: EventLoop,
62-
password: String? = nil,
63-
logger: Logger = .redisBaseConnectionLogger,
64-
tcpClient: ClientBootstrap? = nil
47+
/// - config: The configuration to use for creating the connection.
48+
/// - eventLoop: The `NIO.EventLoop` that the connection will be bound to.
49+
/// - client: If you have chosen to configure a `NIO.ClientBootstrap` yourself, this will be used instead of the `.makeRedisTCPClient` factory instance.
50+
/// - Returns: A `NIO.EventLoopFuture` that resolves with the new connection after it has been opened, configured, and authenticated per the `configuration` object.
51+
public static func make(
52+
configuration config: Configuration,
53+
boundEventLoop eventLoop: EventLoop,
54+
configuredTCPClient client: ClientBootstrap? = nil
6555
) -> EventLoopFuture<RedisConnection> {
66-
let client = tcpClient ?? ClientBootstrap.makeRedisTCPClient(group: eventLoop)
56+
let client = client ?? .makeRedisTCPClient(group: eventLoop)
6757

68-
return client.connect(to: socket)
69-
.map { return RedisConnection(configuredRESPChannel: $0, context: logger) }
70-
.flatMap { connection in
71-
guard let pw = password else {
72-
return connection.eventLoop.makeSucceededFuture(connection)
73-
}
74-
return connection.authorize(with: pw)
75-
.map { return connection }
58+
var future = client
59+
.connect(to: config.address)
60+
.map { return RedisConnection(configuredRESPChannel: $0, context: config.defaultLogger) }
61+
62+
// if a password is specified, use it to authenticate before further operations happen
63+
if let password = config.password {
64+
future = future.flatMap { connection in
65+
return connection.authorize(with: password).map { connection }
66+
}
67+
}
68+
69+
// if a database index is specified, use it to switch the selected database before further operations happen
70+
if let database = config.initialDatabase {
71+
future = future.flatMap { connection in
72+
return connection.select(database: database).map { connection }
7673
}
74+
}
75+
76+
return future
7777
}
7878
}
7979

80-
/// A concrete `RedisClient` implementation that represents an individual connection to a Redis database instance.
80+
/// A concrete `RedisClient` implementation that represents an individual connection to a Redis instance.
8181
///
82-
/// For basic setups, you will just need a `NIO.SocketAddress` and a `NIO.EventLoop` and perhaps a `password`.
82+
/// For basic setups, you will just need a `NIO.EventLoop` and perhaps a `password`.
8383
///
8484
/// let eventLoop: EventLoop = ...
85-
/// let connection = RedisConnection.connect(
86-
/// to: try .makeAddressResolvingHost("my.redis.url", port: RedisConnection.defaultPort),
87-
/// on: eventLoop
85+
/// let connection = RedisConnection.make(
86+
/// configuration: .init(hostname: "my.redis.url", password: "some_password"),
87+
/// boundEventLoop: eventLoop
8888
/// ).wait()
8989
///
9090
/// let result = try connection.set("my_key", to: "some value")
@@ -94,8 +94,6 @@ extension RedisConnection {
9494
/// print(result) // Optional("some value")
9595
///
9696
/// Note: `wait()` is used in the example for simplicity. Never call `wait()` on an event loop.
97-
///
98-
/// See `NIO.SocketAddress`, `NIO.EventLoop`, and `RedisClient`.
9997
public final class RedisConnection: RedisClient, RedisClientWithUserContext {
10098
/// A unique identifer to represent this connection.
10199
public let id = UUID()

0 commit comments

Comments
 (0)