Skip to content

Commit 0c3beee

Browse files
committed
95 -- Backport unexpected channel closure callback
This is a cherry-pick commit of ad316a9
1 parent edadec9 commit 0c3beee

File tree

2 files changed

+51
-1
lines changed

2 files changed

+51
-1
lines changed

Sources/RediStack/RedisConnection.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// This source file is part of the RediStack open source project
44
//
5-
// Copyright (c) 2019-2020 RediStack project authors
5+
// Copyright (c) 2019-2021 RediStack project authors
66
// Licensed under Apache License v2.0
77
//
88
// See LICENSE.txt for license information
@@ -139,6 +139,10 @@ public final class RedisConnection: RedisClient, RedisClientWithUserContext {
139139
], on: self.eventLoop)
140140
}
141141
}
142+
/// A closure to invoke when the connection closes unexpectedly.
143+
///
144+
/// An unexpected closure is when the connection is closed by any other method than by calling `close(logger:)`.
145+
public var onUnexpectedClosure: (() -> Void)?
142146

143147
internal let channel: Channel
144148
private let systemContext: Context
@@ -182,6 +186,7 @@ public final class RedisConnection: RedisClient, RedisClientWithUserContext {
182186
self.state = .closed
183187
self.logger.error("connection was closed unexpectedly")
184188
RedisMetrics.activeConnectionCount.decrement()
189+
self.onUnexpectedClosure?()
185190
}
186191

187192
self.logger.trace("connection created")
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the RediStack open source project
4+
//
5+
// Copyright (c) 2021 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 Logging
16+
import NIO
17+
@testable import RediStack
18+
import XCTest
19+
20+
final class RedisConnectionTests: XCTestCase {
21+
22+
}
23+
24+
// MARK: Unexpected Closures
25+
extension RedisConnectionTests {
26+
func test_connectionUnexpectedlyCloses_invokesCallback() throws {
27+
let loop = EmbeddedEventLoop()
28+
29+
let expectedClosureConnection = RedisConnection(configuredRESPChannel: EmbeddedChannel(loop: loop), context: Logger(label: ""))
30+
let expectedClosureExpectation = self.expectation(description: "this should not be fulfilled")
31+
expectedClosureExpectation.isInverted = true
32+
33+
expectedClosureConnection.onUnexpectedClosure = { expectedClosureExpectation.fulfill() }
34+
_ = expectedClosureConnection.close(logger: nil)
35+
36+
let channel = EmbeddedChannel(loop: loop)
37+
let notExpectedClosureConnection = RedisConnection(configuredRESPChannel: channel, context: Logger(label: ""))
38+
let notExpectedClosureExpectation = self.expectation(description: "this should be fulfilled")
39+
notExpectedClosureConnection.onUnexpectedClosure = { notExpectedClosureExpectation.fulfill() }
40+
41+
_ = try channel.finish(acceptAlreadyClosed: true)
42+
43+
self.waitForExpectations(timeout: 0.5)
44+
}
45+
}

0 commit comments

Comments
 (0)