1
1
import { SinglyLinkedList , DoublyLinkedNode , DoublyLinkedList } from './linked-list' ;
2
2
import encodeCommand from '../RESP/encoder' ;
3
3
import { Decoder , PUSH_TYPE_MAPPING , RESP_TYPES } from '../RESP/decoder' ;
4
- import { CommandArguments , TypeMapping , ReplyUnion , RespVersions } from '../RESP/types' ;
5
- import { ChannelListeners , PubSub , PubSubCommand , PubSubListener , PubSubType , PubSubTypeListeners } from './pub-sub' ;
4
+ import { TypeMapping , ReplyUnion , RespVersions , CommandArguments } from '../RESP/types' ;
5
+ import { COMMANDS , ChannelListeners , PUBSUB_TYPE , PubSub , PubSubCommand , PubSubListener , PubSubType , PubSubTypeListeners } from './pub-sub' ;
6
6
import { AbortError , ErrorReply } from '../errors' ;
7
7
import { MonitorCallback } from '.' ;
8
8
@@ -51,6 +51,8 @@ export default class RedisCommandsQueue {
51
51
#chainInExecution: symbol | undefined ;
52
52
readonly decoder ;
53
53
readonly #pubSub = new PubSub ( ) ;
54
+ readonly #pushHandlers: Map < string , ( pushMsg : Array < any > ) => unknown > = new Map ( ) ;
55
+ readonly #builtInSet = new Set < string > ;
54
56
55
57
get isPubSubActive ( ) {
56
58
return this . #pubSub. isActive ;
@@ -64,6 +66,21 @@ export default class RedisCommandsQueue {
64
66
this . #respVersion = respVersion ;
65
67
this . #maxLength = maxLength ;
66
68
this . #onShardedChannelMoved = onShardedChannelMoved ;
69
+
70
+ this . #pushHandlers. set ( COMMANDS [ PUBSUB_TYPE . CHANNELS ] . message . toString ( ) , this . #pubSub. handleMessageReplyChannel . bind ( this . #pubSub) ) ;
71
+ this . #pushHandlers. set ( COMMANDS [ PUBSUB_TYPE . CHANNELS ] . subscribe . toString ( ) , this . #handleStatusReply. bind ( this ) ) ;
72
+ this . #pushHandlers. set ( COMMANDS [ PUBSUB_TYPE . CHANNELS ] . unsubscribe . toString ( ) , this . #handleStatusReply. bind ( this ) ) ;
73
+ this . #pushHandlers. set ( COMMANDS [ PUBSUB_TYPE . PATTERNS ] . message . toString ( ) , this . #pubSub. handleMessageReplyPattern . bind ( this . #pubSub) ) ;
74
+ this . #pushHandlers. set ( COMMANDS [ PUBSUB_TYPE . PATTERNS ] . subscribe . toString ( ) , this . #handleStatusReply. bind ( this ) ) ;
75
+ this . #pushHandlers. set ( COMMANDS [ PUBSUB_TYPE . PATTERNS ] . unsubscribe . toString ( ) , this . #handleStatusReply. bind ( this ) ) ;
76
+ this . #pushHandlers. set ( COMMANDS [ PUBSUB_TYPE . SHARDED ] . message . toString ( ) , this . #pubSub. handleMessageReplySharded . bind ( this . #pubSub) ) ;
77
+ this . #pushHandlers. set ( COMMANDS [ PUBSUB_TYPE . SHARDED ] . subscribe . toString ( ) , this . #handleStatusReply. bind ( this ) ) ;
78
+ this . #pushHandlers. set ( COMMANDS [ PUBSUB_TYPE . SHARDED ] . unsubscribe . toString ( ) , this . #handleShardedUnsubscribe. bind ( this ) ) ;
79
+
80
+ for ( const str in this . #pushHandlers. keys ) {
81
+ this . #builtInSet. add ( str ) ;
82
+ }
83
+
67
84
this . decoder = this . #initiateDecoder( ) ;
68
85
}
69
86
@@ -75,28 +92,44 @@ export default class RedisCommandsQueue {
75
92
this . #waitingForReply. shift ( ) ! . reject ( err ) ;
76
93
}
77
94
78
- #onPush( push : Array < any > ) {
79
- // TODO: type
80
- if ( this . #pubSub. handleMessageReply ( push ) ) return true ;
81
-
82
- const isShardedUnsubscribe = PubSub . isShardedUnsubscribe ( push ) ;
83
- if ( isShardedUnsubscribe && ! this . #waitingForReply. length ) {
95
+ #handleStatusReply( push : Array < any > ) {
96
+ const head = this . #waitingForReply. head ! . value ;
97
+ if (
98
+ ( Number . isNaN ( head . channelsCounter ! ) && push [ 2 ] === 0 ) ||
99
+ -- head . channelsCounter ! === 0
100
+ ) {
101
+ this . #waitingForReply. shift ( ) ! . resolve ( ) ;
102
+ }
103
+ }
104
+
105
+ #handleShardedUnsubscribe( push : Array < any > ) {
106
+ if ( ! this . #waitingForReply. length ) {
84
107
const channel = push [ 1 ] . toString ( ) ;
85
108
this . #onShardedChannelMoved(
86
109
channel ,
87
110
this . #pubSub. removeShardedListeners ( channel )
88
111
) ;
89
- return true ;
90
- } else if ( isShardedUnsubscribe || PubSub . isStatusReply ( push ) ) {
91
- const head = this . #waitingForReply. head ! . value ;
92
- if (
93
- ( Number . isNaN ( head . channelsCounter ! ) && push [ 2 ] === 0 ) ||
94
- -- head . channelsCounter ! === 0
95
- ) {
96
- this . #waitingForReply. shift ( ) ! . resolve ( ) ;
97
- }
112
+ } else {
113
+ this . #handleStatusReply( push ) ;
114
+ }
115
+ }
116
+
117
+ addPushHandler ( messageType : string , handler : ( pushMsg : Array < any > ) => unknown ) {
118
+ if ( this . #builtInSet. has ( messageType ) ) {
119
+ throw new Error ( "Cannot override built in push message handler" ) ;
120
+ }
121
+
122
+ this . #pushHandlers. set ( messageType , handler ) ;
123
+ }
124
+
125
+ #onPush( push : Array < any > ) {
126
+ const handler = this . #pushHandlers. get ( push [ 0 ] . toString ( ) ) ;
127
+ if ( handler ) {
128
+ handler ( push ) ;
98
129
return true ;
99
130
}
131
+
132
+ return false ;
100
133
}
101
134
102
135
#getTypeMapping( ) {
0 commit comments