84
84
heartbeat :: undefined | integer (),
85
85
heartbeater :: any (),
86
86
client_properties = #{} :: #{binary () => binary ()},
87
- monitors = #{} :: #{reference () => stream ()},
87
+ monitors = #{} :: #{reference () => { pid (), stream ()} },
88
88
stats_timer :: undefined | reference (),
89
89
resource_alarm :: boolean (),
90
90
send_file_oct ::
@@ -918,10 +918,10 @@ open(info, {'DOWN', MonitorRef, process, _OsirisPid, _Reason},
918
918
StatemData ) ->
919
919
{Connection1 , State1 } =
920
920
case Monitors of
921
- #{MonitorRef := Stream } ->
921
+ #{MonitorRef := { MemberPid , Stream } } ->
922
922
Monitors1 = maps :remove (MonitorRef , Monitors ),
923
923
C = Connection # stream_connection {monitors = Monitors1 },
924
- case clean_state_after_stream_deletion_or_failure (Stream , C ,
924
+ case clean_state_after_stream_deletion_or_failure (MemberPid , Stream , C ,
925
925
State )
926
926
of
927
927
{cleaned , NewConnection , NewState } ->
@@ -1859,7 +1859,7 @@ handle_frame_post_auth(Transport,
1859
1859
{request , CorrelationId ,
1860
1860
{delete_publisher , PublisherId }}) ->
1861
1861
case Publishers of
1862
- #{PublisherId := # publisher {stream = Stream , reference = Ref }} ->
1862
+ #{PublisherId := # publisher {stream = Stream , reference = Ref , leader = LeaderPid }} ->
1863
1863
Connection1 =
1864
1864
Connection0 # stream_connection {publishers =
1865
1865
maps :remove (PublisherId ,
@@ -1868,7 +1868,7 @@ handle_frame_post_auth(Transport,
1868
1868
maps :remove ({Stream , Ref },
1869
1869
PubToIds )},
1870
1870
Connection2 =
1871
- maybe_clean_connection_from_stream (Stream , Connection1 ),
1871
+ maybe_clean_connection_from_stream (LeaderPid , Stream , Connection1 ),
1872
1872
response (Transport ,
1873
1873
Connection1 ,
1874
1874
delete_publisher ,
@@ -2371,7 +2371,7 @@ handle_frame_post_auth(Transport,
2371
2371
CorrelationId ),
2372
2372
{Connection1 , State1 } =
2373
2373
case
2374
- clean_state_after_stream_deletion_or_failure (Stream ,
2374
+ clean_state_after_stream_deletion_or_failure (undefined , Stream ,
2375
2375
Connection ,
2376
2376
State )
2377
2377
of
@@ -3116,7 +3116,7 @@ stream_r(Stream, #stream_connection{virtual_host = VHost}) ->
3116
3116
kind = queue ,
3117
3117
virtual_host = VHost }.
3118
3118
3119
- clean_state_after_stream_deletion_or_failure (Stream ,
3119
+ clean_state_after_stream_deletion_or_failure (MemberPid , Stream ,
3120
3120
# stream_connection {virtual_host =
3121
3121
VirtualHost ,
3122
3122
stream_subscriptions
@@ -3141,16 +3141,30 @@ clean_state_after_stream_deletion_or_failure(Stream,
3141
3141
#{Stream := SubscriptionIds } = StreamSubscriptions ,
3142
3142
Requests1 = lists :foldl (
3143
3143
fun (SubId , Rqsts0 ) ->
3144
- rabbit_stream_metrics :consumer_cancelled (self (),
3145
- stream_r (Stream ,
3146
- C0 ),
3147
- SubId ),
3148
3144
#{SubId := Consumer } = Consumers ,
3149
- Rqsts1 = maybe_unregister_consumer (
3150
- VirtualHost , Consumer ,
3151
- single_active_consumer (Consumer ),
3152
- Rqsts0 ),
3153
- Rqsts1
3145
+ case {MemberPid , Consumer } of
3146
+ {undefined , _C } ->
3147
+ rabbit_stream_metrics :consumer_cancelled (self (),
3148
+ stream_r (Stream ,
3149
+ C0 ),
3150
+ SubId ),
3151
+ maybe_unregister_consumer (
3152
+ VirtualHost , Consumer ,
3153
+ single_active_consumer (Consumer ),
3154
+ Rqsts0 );
3155
+ {MemberPid , # consumer {configuration =
3156
+ # consumer_configuration {member_pid = MemberPid }}} ->
3157
+ rabbit_stream_metrics :consumer_cancelled (self (),
3158
+ stream_r (Stream ,
3159
+ C0 ),
3160
+ SubId ),
3161
+ maybe_unregister_consumer (
3162
+ VirtualHost , Consumer ,
3163
+ single_active_consumer (Consumer ),
3164
+ Rqsts0 );
3165
+ _ ->
3166
+ Rqsts0
3167
+ end
3154
3168
end , Requests0 , SubscriptionIds ),
3155
3169
{true ,
3156
3170
C0 # stream_connection {stream_subscriptions =
@@ -3169,17 +3183,25 @@ clean_state_after_stream_deletion_or_failure(Stream,
3169
3183
{PurgedPubs , PurgedPubToIds } =
3170
3184
maps :fold (fun (PubId ,
3171
3185
# publisher {stream = S , reference = Ref },
3172
- {Pubs , PubToIds }) ->
3173
- case S of
3174
- Stream ->
3186
+ {Pubs , PubToIds }) when S =:= Stream andalso MemberPid =:= undefined ->
3187
+ rabbit_stream_metrics :publisher_deleted (self (),
3188
+ stream_r (Stream ,
3189
+ C1 ),
3190
+ PubId ),
3191
+ {maps :remove (PubId , Pubs ),
3192
+ maps :remove ({Stream , Ref }, PubToIds )};
3193
+ (PubId ,
3194
+ # publisher {stream = S , reference = Ref , leader = MPid },
3195
+ {Pubs , PubToIds }) when S =:= Stream andalso MPid =:= MemberPid ->
3175
3196
rabbit_stream_metrics :publisher_deleted (self (),
3176
- stream_r (S ,
3197
+ stream_r (Stream ,
3177
3198
C1 ),
3178
3199
PubId ),
3179
3200
{maps :remove (PubId , Pubs ),
3180
3201
maps :remove ({Stream , Ref }, PubToIds )};
3181
- _ -> {Pubs , PubToIds }
3182
- end
3202
+
3203
+ (_PubId , _Publisher , {Pubs , PubToIds }) ->
3204
+ {Pubs , PubToIds }
3183
3205
end ,
3184
3206
{Publishers , PublisherToIds }, Publishers ),
3185
3207
{true ,
@@ -3201,7 +3223,7 @@ clean_state_after_stream_deletion_or_failure(Stream,
3201
3223
orelse LeadersCleaned
3202
3224
of
3203
3225
true ->
3204
- C3 = demonitor_stream (Stream , C2 ),
3226
+ C3 = demonitor_stream (MemberPid , Stream , C2 ),
3205
3227
{cleaned , C3 # stream_connection {stream_leaders = Leaders1 }, S2 };
3206
3228
false ->
3207
3229
{not_cleaned , C2 # stream_connection {stream_leaders = Leaders1 }, S2 }
@@ -3240,7 +3262,7 @@ remove_subscription(SubscriptionId,
3240
3262
# stream_connection_state {consumers = Consumers } = State ) ->
3241
3263
#{SubscriptionId := Consumer } = Consumers ,
3242
3264
# consumer {log = Log ,
3243
- configuration = # consumer_configuration {stream = Stream }} =
3265
+ configuration = # consumer_configuration {stream = Stream , member_pid = MemberPid }} =
3244
3266
Consumer ,
3245
3267
rabbit_log :debug (" Deleting subscription ~tp (stream ~tp )" ,
3246
3268
[SubscriptionId , Stream ]),
@@ -3260,7 +3282,7 @@ remove_subscription(SubscriptionId,
3260
3282
Connection # stream_connection {stream_subscriptions =
3261
3283
StreamSubscriptions1 },
3262
3284
Consumers1 = maps :remove (SubscriptionId , Consumers ),
3263
- Connection2 = maybe_clean_connection_from_stream (Stream , Connection1 ),
3285
+ Connection2 = maybe_clean_connection_from_stream (MemberPid , Stream , Connection1 ),
3264
3286
rabbit_stream_metrics :consumer_cancelled (self (),
3265
3287
stream_r (Stream , Connection2 ),
3266
3288
SubscriptionId ),
@@ -3273,7 +3295,7 @@ remove_subscription(SubscriptionId,
3273
3295
{Connection2 # stream_connection {outstanding_requests = Requests1 },
3274
3296
State # stream_connection_state {consumers = Consumers1 }}.
3275
3297
3276
- maybe_clean_connection_from_stream (Stream ,
3298
+ maybe_clean_connection_from_stream (MemberPid , Stream ,
3277
3299
# stream_connection {stream_leaders =
3278
3300
Leaders } =
3279
3301
Connection0 ) ->
@@ -3282,7 +3304,7 @@ maybe_clean_connection_from_stream(Stream,
3282
3304
stream_has_subscriptions (Stream , Connection0 )}
3283
3305
of
3284
3306
{false , false } ->
3285
- demonitor_stream (Stream , Connection0 );
3307
+ demonitor_stream (MemberPid , Stream , Connection0 );
3286
3308
_ ->
3287
3309
Connection0
3288
3310
end ,
@@ -3291,26 +3313,27 @@ maybe_clean_connection_from_stream(Stream,
3291
3313
3292
3314
maybe_monitor_stream (Pid , Stream ,
3293
3315
# stream_connection {monitors = Monitors } = Connection ) ->
3294
- case lists :member (Stream , maps :values (Monitors )) of
3316
+ case lists :member ({ Pid , Stream } , maps :values (Monitors )) of
3295
3317
true ->
3296
3318
Connection ;
3297
3319
false ->
3298
3320
MonitorRef = monitor (process , Pid ),
3299
3321
Connection # stream_connection {monitors =
3300
- maps :put (MonitorRef , Stream ,
3322
+ maps :put (MonitorRef , { Pid , Stream } ,
3301
3323
Monitors )}
3302
3324
end .
3303
3325
3304
- demonitor_stream (Stream ,
3326
+ demonitor_stream (MemberPid , Stream ,
3305
3327
# stream_connection {monitors = Monitors0 } = Connection ) ->
3306
3328
Monitors =
3307
- maps :fold (fun (MonitorRef , Strm , Acc ) ->
3308
- case Strm of
3309
- Stream ->
3310
- demonitor (MonitorRef , [flush ]),
3329
+ maps :fold (fun (MonitorRef , {MPid , Strm }, Acc ) when MPid =:= MemberPid andalso Strm =:= Stream ->
3330
+ demonitor (MonitorRef , [flush ]),
3331
+ Acc ;
3332
+ (MonitorRef , {_MPid , Strm }, Acc ) when MemberPid =:= undefined andalso Strm =:= Stream ->
3333
+ demonitor (MonitorRef , [flush ]),
3311
3334
Acc ;
3312
- _ -> maps : put (MonitorRef , Strm , Acc )
3313
- end
3335
+ (MonitorRef , { MPid , Strm } , Acc ) ->
3336
+ maps : put ( MonitorRef , { MPid , Strm }, Acc )
3314
3337
end ,
3315
3338
#{}, Monitors0 ),
3316
3339
Connection # stream_connection {monitors = Monitors }.
0 commit comments