2
2
//
3
3
// This source file is part of the RediStack open source project
4
4
//
5
- // Copyright (c) 2020 RediStack project authors
5
+ // Copyright (c) 2020-2022 RediStack project authors
6
6
// Licensed under Apache License v2.0
7
7
//
8
8
// See LICENSE.txt for license information
@@ -24,18 +24,35 @@ import NIO
24
24
/// - message: The message data that was received from the `publisher`.
25
25
public typealias RedisSubscriptionMessageReceiver = ( _ publisher: RedisChannelName , _ message: RESPValue ) -> Void
26
26
27
- /// A closure handler invoked for Pub/Sub subscription changes.
27
+ /// The details of the subscription change.
28
+ /// - Parameters:
29
+ /// - subscriptionKey: The subscribed channel or pattern that had its subscription status changed.
30
+ /// - currentSubscriptionCount: The current total number of subscriptions the connection has.
31
+ public typealias RedisSubscriptionChangeDetails = ( subscriptionKey: String , currentSubscriptionCount: Int )
32
+
33
+ /// A closure handler invoked for Pub/Sub subscribe commands.
28
34
///
29
35
/// This closure will be invoked only *once* for each individual channel or pattern that is having its subscription changed,
30
- /// even if it was done as a single PSUBSCRIBE, SUBSCRIBE, PUNSUBSCRIBE, or UNSUBSCRIBE command.
36
+ /// even if it was done as a single PSUBSCRIBE or SUBSCRIBE command.
37
+ /// - Warning: The receiver is called on the same `NIO.EventLoop` that processed the message.
38
+ ///
39
+ /// If you are doing non-trivial work in response to PubSub messages, it is **highly recommended** that the work be dispatched to another thread
40
+ /// so as to not block further messages from being processed.
41
+ /// - Parameter details: The details of the subscription.
42
+ public typealias RedisSubscribeHandler = ( _ details: RedisSubscriptionChangeDetails ) -> Void
43
+
44
+ /// A closure handler invoked for Pub/Sub unsubscribe commands.
45
+ ///
46
+ /// This closure will be invoked only *once* for each individual channel or pattern that is having its subscription changed,
47
+ /// even if it was done as a single PUNSUBSCRIBE or UNSUBSCRIBE command.
31
48
/// - Warning: The receiver is called on the same `NIO.EventLoop` that processed the message.
32
49
///
33
50
/// If you are doing non-trivial work in response to PubSub messages, it is **highly recommended** that the work be dispatched to another thread
34
51
/// so as to not block further messages from being processed.
35
52
/// - Parameters:
36
- /// - subscriptionKey : The subscribed channel or pattern that had its subscription status changed .
37
- /// - currentSubscriptionCount : The current total number of subscriptions the connection has .
38
- public typealias RedisSubscriptionChangeHandler = ( _ subscriptionKey : String , _ currentSubscriptionCount : Int ) -> Void
53
+ /// - details : The details of the subscription.
54
+ /// - error : The error triggering the unsubscribe, if any. If this is `nil`, then the subscription was expected as a response to a user-initiated unsubscribe .
55
+ public typealias RedisUnsubscribeHandler = ( _ details : RedisSubscriptionChangeDetails , _ error : Error ? ) -> Void
39
56
40
57
/// A list of patterns or channels that a Pub/Sub subscription change is targetting.
41
58
///
@@ -146,7 +163,7 @@ extension RedisPubSubHandler {
146
163
147
164
guard let subscription = self . subscriptions [ prefixedKey] else { return }
148
165
149
- subscription. onSubscribe ? ( subscriptionKey, subscriptionCount)
166
+ subscription. onSubscribe ? ( ( subscriptionKey, subscriptionCount) )
150
167
subscription. onSubscribe = nil // nil to free memory
151
168
self . subscriptions [ prefixedKey] = subscription
152
169
@@ -162,7 +179,7 @@ extension RedisPubSubHandler {
162
179
let prefixedKey = self . prefixKey ( subscriptionKey, with: keyPrefix)
163
180
guard let subscription = self . subscriptions. removeValue ( forKey: prefixedKey) else { return }
164
181
165
- subscription. onUnsubscribe ? ( subscriptionKey, subscriptionCount)
182
+ subscription. onUnsubscribe ? ( ( subscriptionKey, subscriptionCount) , nil )
166
183
subscription. type. gauge. decrement ( )
167
184
168
185
switch self . pendingUnsubscribes. removeValue ( forKey: prefixedKey) {
@@ -208,8 +225,8 @@ extension RedisPubSubHandler {
208
225
public func addSubscription(
209
226
for target: RedisSubscriptionTarget ,
210
227
messageReceiver receiver: @escaping RedisSubscriptionMessageReceiver ,
211
- onSubscribe subscribeHandler: RedisSubscriptionChangeHandler ? ,
212
- onUnsubscribe unsubscribeHandler: RedisSubscriptionChangeHandler ?
228
+ onSubscribe subscribeHandler: RedisSubscribeHandler ? ,
229
+ onUnsubscribe unsubscribeHandler: RedisUnsubscribeHandler ?
213
230
) -> EventLoopFuture < Int > {
214
231
guard self . eventLoop. inEventLoop else {
215
232
return self . eventLoop. flatSubmit {
@@ -481,7 +498,7 @@ extension RedisPubSubHandler: ChannelInboundHandler {
481
498
let receivers = self . subscriptions
482
499
self . subscriptions. removeAll ( )
483
500
receivers. forEach {
484
- $0. value. onUnsubscribe ? ( $0. key, 0 )
501
+ $0. value. onUnsubscribe ? ( ( $0. key, 0 ) , error )
485
502
$0. value. type. gauge. decrement ( )
486
503
}
487
504
}
@@ -521,14 +538,14 @@ extension RedisPubSubHandler {
521
538
fileprivate final class Subscription {
522
539
let type : SubscriptionType
523
540
let onMessage : RedisSubscriptionMessageReceiver
524
- var onSubscribe : RedisSubscriptionChangeHandler ? // will be set to nil after first call
525
- let onUnsubscribe : RedisSubscriptionChangeHandler ?
541
+ var onSubscribe : RedisSubscribeHandler ? // will be set to nil after first call
542
+ let onUnsubscribe : RedisUnsubscribeHandler ?
526
543
527
544
init (
528
545
type: SubscriptionType ,
529
546
messageReceiver: @escaping RedisSubscriptionMessageReceiver ,
530
- subscribeHandler: RedisSubscriptionChangeHandler ? ,
531
- unsubscribeHandler: RedisSubscriptionChangeHandler ?
547
+ subscribeHandler: RedisSubscribeHandler ? ,
548
+ unsubscribeHandler: RedisUnsubscribeHandler ?
532
549
) {
533
550
self . type = type
534
551
self . onMessage = messageReceiver
0 commit comments