Skip to content

Commit 1b69101

Browse files
authored
Add RedisClusterNodeDescription and RedisClusterNodeID (#92)
1 parent 41b7777 commit 1b69101

File tree

4 files changed

+146
-0
lines changed

4 files changed

+146
-0
lines changed
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the RediStack open source project
4+
//
5+
// Copyright (c) 2023 RediStack 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 RediStack project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
import NIOCore
16+
17+
/// A description of a single node that is part of a redis cluster
18+
public protocol RedisClusterNodeDescriptionProtocol: Sendable, Equatable {
19+
/// The node's host name.
20+
var host: String? { get }
21+
/// The node's ip address.
22+
var ip: String? { get }
23+
/// The nodes endpoint. This should normally be the ``host`` if the node has a routable hostname.
24+
/// Otherwise it is the ``ip``. This property is used to create connections to the node.
25+
var endpoint: String { get }
26+
/// The node's redis port
27+
var port: Int { get }
28+
/// Defines if TLS shall be used to create a connection to the node
29+
var useTLS: Bool { get }
30+
31+
/// A resolved SocketAddress to the node. We will remove this property as soon as we have fixed
32+
/// the underlying Redis implementation.
33+
var socketAddress: SocketAddress { get }
34+
}
35+
36+
extension RedisClusterNodeDescriptionProtocol {
37+
func isSame<Other: RedisClusterNodeDescriptionProtocol>(_ other: Other) -> Bool {
38+
return self.ip == other.ip
39+
&& self.port == other.port
40+
&& self.endpoint == other.endpoint
41+
&& self.useTLS == other.useTLS
42+
&& self.host == other.host
43+
}
44+
}
45+
46+
extension RedisClusterNodeDescriptionProtocol {
47+
@inlinable
48+
public var id: RedisClusterNodeID {
49+
RedisClusterNodeID(endpoint: self.endpoint, port: self.port)
50+
}
51+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the RediStack open source project
4+
//
5+
// Copyright (c) 2023 RediStack 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 RediStack project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
/// Properties to identifiy a Node in a Redis cluster
16+
public struct RedisClusterNodeID: Hashable, Sendable {
17+
/// The node's endpoint. This might be the hostname (preferred) or ip address
18+
public var endpoint: String
19+
/// The node's redis port
20+
public var port: Int
21+
22+
public init(endpoint: String, port: Int) {
23+
self.endpoint = endpoint
24+
self.port = port
25+
}
26+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the RediStack open source project
4+
//
5+
// Copyright (c) 2023 RediStack 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 RediStack project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
import XCTest
16+
@testable import RediStack
17+
18+
final class RedisClusterNodeDescriptionProtocolTests: XCTestCase {
19+
func testIsSame() {
20+
let node1 = MockNodeDescription(host: "redis1", ip: "127.0.0.1", useTLS: true)
21+
let node2 = MockNodeDescription(host: "redis2", ip: "127.0.0.2", useTLS: true)
22+
23+
XCTAssertTrue(node1.isSame(node1))
24+
XCTAssertTrue(node2.isSame(node2))
25+
XCTAssertFalse(node2.isSame(node1))
26+
}
27+
28+
func testNodeID() {
29+
let node1 = MockNodeDescription(host: "redis1", ip: "127.0.0.1", useTLS: true)
30+
let node2 = MockNodeDescription(host: "redis2", ip: "127.0.0.2", useTLS: true)
31+
32+
XCTAssertEqual(node1.id, .init(endpoint: "redis1", port: 6379))
33+
XCTAssertEqual(node2.id, .init(endpoint: "redis2", port: 6379))
34+
}
35+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the RediStack open source project
4+
//
5+
// Copyright (c) 2023 RediStack 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 RediStack project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
import RediStack
16+
import NIOCore
17+
18+
struct MockNodeDescription: RedisClusterNodeDescriptionProtocol, Hashable {
19+
var host: String?
20+
var endpoint: String
21+
var ip: String?
22+
var port: Int = 5432
23+
var useTLS: Bool
24+
25+
var socketAddress: SocketAddress { try! .makeAddressResolvingHost(self.endpoint, port: self.port) }
26+
27+
init(host: String? = "localhost", ip: String, endpoint: String? = nil, port: Int = 6379, useTLS: Bool) {
28+
self.host = host
29+
self.ip = ip
30+
self.endpoint = endpoint ?? host ?? ip
31+
self.port = port
32+
self.useTLS = useTLS
33+
}
34+
}

0 commit comments

Comments
 (0)