/**
* Copyright 2024 Beijing Baolande Software Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Runtime Library Exception to the Apache 2.0 License:
*
* As an exception, if you use this Software to compile your source code and
* portions of this Software are embedded into the binary product as a result,
* you may redistribute such product without providing attribution as would
* otherwise be required by Sections 4(a), 4(b) and 4(d) of the License.
*/
package redis_sdk.client
/**
* Cluster集群的配置
*/
public class ClusterRedisClientConfig <: RedisClientConfigBase & Hashable & Equatable<ClusterRedisClientConfig> {
private let clusterHostAndPorts = HashSet<HostAndPort>()
// 最大重试次数,默认值:5
private var maxAttemptsVal: Int64 = 5
// 最大重试时间
private var maxTotalRetriesDurationVal: Duration = Duration.second * 30
// 更新槽位缓存信息的间隔时间
private var topologyRefreshPeriodVal: ?Duration = None
// 延迟关闭ClusterInfoCache(用于维护集群模式的槽位信息)的时间, 在该期间内ClusterInfoCache再次被引用则取消关闭
private var closeClusterInfoCacheDelayDurationVal = Duration.second * 10
public func addClusterHostAndPort(hostAndPort: HostAndPort) {
if (!clusterHostAndPorts.contains(hostAndPort)) {
clusterHostAndPorts.add(hostAndPort)
}
return this
}
public func addClusterHostAndPort(host: String, port: UInt16) {
let hostAndPort = HostAndPort(host, port)
addClusterHostAndPort(hostAndPort)
return this
}
public func addClusterHostAndPorts(hostAndPorts: Array<HostAndPort>) {
for (hostAndPort in hostAndPorts) {
addClusterHostAndPort(hostAndPort)
}
return this
}
public func addClusterHostAndPorts(hostAndPorts: ArrayList<HostAndPort>) {
for (hostAndPort in hostAndPorts) {
addClusterHostAndPort(hostAndPort)
}
return this
}
public func getClusterHostAndPorts(): HashSet<HostAndPort> {
return this.clusterHostAndPorts
}
public mut prop maxAttempts: Int64 {
get() {
return maxAttemptsVal
}
set(value) {
this.maxAttemptsVal = value
}
}
public mut prop maxTotalRetriesDuration: Duration {
get() {
return maxTotalRetriesDurationVal
}
set(value) {
this.maxTotalRetriesDurationVal = value
}
}
public mut prop topologyRefreshPeriod: ?Duration {
get() {
return topologyRefreshPeriodVal
}
set(value) {
if (let Some(value) <- value) {
if (value > Duration.Zero) {
this.topologyRefreshPeriodVal = value
}
}
}
}
public mut prop closeClusterInfoCacheDelayDuration: Duration {
get() {
return closeClusterInfoCacheDelayDurationVal
}
set(value) {
this.closeClusterInfoCacheDelayDurationVal = value
}
}
public override func configTcpEndpointOptions(endpoint: ClientEndpointConfig) {
super.configTcpEndpointOptions(endpoint)
endpoint.minConnections = 0
endpoint.maxConnections = 1
}
@OverflowWrapping
public open func hashCode(): Int64 {
let prime = 53
var hashCode = super.computeHashCode()
// 先排序再计算HashCode
let sortedHostAndPorts = ArrayList<HostAndPort>()
sortedHostAndPorts.add(all: clusterHostAndPorts)
sort(sortedHostAndPorts)
for (hostAndPort in sortedHostAndPorts) {
hashCode = hashCode + prime * hostAndPort.hashCode()
}
hashCode = hashCode + prime * maxAttemptsVal.hashCode()
hashCode = hashCode + prime * maxTotalRetriesDurationVal.hashCode()
if (let Some(topologyRefreshPeriod) <- topologyRefreshPeriodVal) {
hashCode = hashCode + prime * topologyRefreshPeriod.hashCode()
}
hashCode = hashCode + prime * closeClusterInfoCacheDelayDurationVal.hashCode()
return hashCode
}
public operator override func ==(other: ClusterRedisClientConfig): Bool {
if (!checkSameHostAndPorts(clusterHostAndPorts, other.clusterHostAndPorts)) {
return false
}
if (maxAttemptsVal != other.maxAttemptsVal) {
return false
}
if (maxTotalRetriesDurationVal != other.maxTotalRetriesDurationVal) {
return false
}
if (topologyRefreshPeriodVal != other.topologyRefreshPeriodVal) {
return false
}
if (closeClusterInfoCacheDelayDurationVal != other.closeClusterInfoCacheDelayDurationVal) {
return false
}
return super.checkEquals(other)
}
public operator override func !=(other: ClusterRedisClientConfig): Bool {
if (!checkSameHostAndPorts(clusterHostAndPorts, other.clusterHostAndPorts)) {
return true
}
if (maxAttemptsVal != other.maxAttemptsVal) {
return true
}
if (maxTotalRetriesDurationVal != other.maxTotalRetriesDurationVal) {
return true
}
if (topologyRefreshPeriodVal != other.topologyRefreshPeriodVal) {
return true
}
if (closeClusterInfoCacheDelayDurationVal != other.closeClusterInfoCacheDelayDurationVal) {
return true
}
return !super.checkEquals(other)
}
public func getStartNodes(): String {
let builder = StringBuilder()
let startNodes = ArrayList<HostAndPort>()
startNodes.add(all: this.clusterHostAndPorts)
for (i in 0..startNodes.size) {
builder.append(startNodes[i])
if (i < startNodes.size - 1) {
builder.append(",")
}
}
return builder.toString()
}
private static func checkSameHostAndPorts(
hostAndPorts: HashSet<HostAndPort>,
otherHostAndPorts: HashSet<HostAndPort>
): Bool {
if (hostAndPorts.size != otherHostAndPorts.size) {
return false
}
let sortedHostAndPorts = ArrayList<HostAndPort>()
sortedHostAndPorts.add(all: hostAndPorts)
sort(sortedHostAndPorts)
let otherSortedHostAndPorts = ArrayList<HostAndPort>()
otherSortedHostAndPorts.add(all: otherHostAndPorts)
sort(otherSortedHostAndPorts)
return sortedHostAndPorts == otherSortedHostAndPorts
}
public func clone(): ClusterRedisClientConfig {
let clientConfig = ClusterRedisClientConfig()
this.cloneTo(clientConfig)
clientConfig.clusterHostAndPorts.add(all: this.clusterHostAndPorts.clone())
clientConfig.maxAttempts = this.maxAttempts
clientConfig.maxTotalRetriesDuration = this.maxTotalRetriesDuration
clientConfig.topologyRefreshPeriod = this.topologyRefreshPeriod
clientConfig.closeClusterInfoCacheDelayDuration = this.closeClusterInfoCacheDelayDuration
return clientConfig
}
}