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 | rabbit_event :state (),
89
89
resource_alarm :: boolean (),
90
90
send_file_oct ::
@@ -912,10 +912,10 @@ open(info, {'DOWN', MonitorRef, process, _OsirisPid, _Reason},
912
912
StatemData ) ->
913
913
{Connection1 , State1 } =
914
914
case Monitors of
915
- #{MonitorRef := Stream } ->
915
+ #{MonitorRef := { MemberPid , Stream } } ->
916
916
Monitors1 = maps :remove (MonitorRef , Monitors ),
917
917
C = Connection # stream_connection {monitors = Monitors1 },
918
- case clean_state_after_stream_deletion_or_failure (Stream , C ,
918
+ case clean_state_after_stream_deletion_or_failure (MemberPid , Stream , C ,
919
919
State )
920
920
of
921
921
{cleaned , NewConnection , NewState } ->
@@ -1893,7 +1893,7 @@ handle_frame_post_auth(Transport,
1893
1893
{request , CorrelationId ,
1894
1894
{delete_publisher , PublisherId }}) ->
1895
1895
case Publishers of
1896
- #{PublisherId := # publisher {stream = Stream , reference = Ref }} ->
1896
+ #{PublisherId := # publisher {stream = Stream , reference = Ref , leader = LeaderPid }} ->
1897
1897
Connection1 =
1898
1898
Connection0 # stream_connection {publishers =
1899
1899
maps :remove (PublisherId ,
@@ -1902,7 +1902,7 @@ handle_frame_post_auth(Transport,
1902
1902
maps :remove ({Stream , Ref },
1903
1903
PubToIds )},
1904
1904
Connection2 =
1905
- maybe_clean_connection_from_stream (Stream , Connection1 ),
1905
+ maybe_clean_connection_from_stream (LeaderPid , Stream , Connection1 ),
1906
1906
response (Transport ,
1907
1907
Connection1 ,
1908
1908
delete_publisher ,
@@ -2418,7 +2418,7 @@ handle_frame_post_auth(Transport,
2418
2418
CorrelationId ),
2419
2419
{Connection1 , State1 } =
2420
2420
case
2421
- clean_state_after_stream_deletion_or_failure (Stream ,
2421
+ clean_state_after_stream_deletion_or_failure (undefined , Stream ,
2422
2422
Connection ,
2423
2423
State )
2424
2424
of
@@ -3155,7 +3155,7 @@ stream_r(Stream, #stream_connection{virtual_host = VHost}) ->
3155
3155
kind = queue ,
3156
3156
virtual_host = VHost }.
3157
3157
3158
- clean_state_after_stream_deletion_or_failure (Stream ,
3158
+ clean_state_after_stream_deletion_or_failure (MemberPid , Stream ,
3159
3159
# stream_connection {virtual_host =
3160
3160
VirtualHost ,
3161
3161
stream_subscriptions
@@ -3180,16 +3180,30 @@ clean_state_after_stream_deletion_or_failure(Stream,
3180
3180
#{Stream := SubscriptionIds } = StreamSubscriptions ,
3181
3181
Requests1 = lists :foldl (
3182
3182
fun (SubId , Rqsts0 ) ->
3183
- rabbit_stream_metrics :consumer_cancelled (self (),
3184
- stream_r (Stream ,
3185
- C0 ),
3186
- SubId ),
3187
3183
#{SubId := Consumer } = Consumers ,
3188
- Rqsts1 = maybe_unregister_consumer (
3189
- VirtualHost , Consumer ,
3190
- single_active_consumer (Consumer ),
3191
- Rqsts0 ),
3192
- Rqsts1
3184
+ case {MemberPid , Consumer } of
3185
+ {undefined , _C } ->
3186
+ rabbit_stream_metrics :consumer_cancelled (self (),
3187
+ stream_r (Stream ,
3188
+ C0 ),
3189
+ SubId ),
3190
+ maybe_unregister_consumer (
3191
+ VirtualHost , Consumer ,
3192
+ single_active_consumer (Consumer ),
3193
+ Rqsts0 );
3194
+ {MemberPid , # consumer {configuration =
3195
+ # consumer_configuration {member_pid = MemberPid }}} ->
3196
+ rabbit_stream_metrics :consumer_cancelled (self (),
3197
+ stream_r (Stream ,
3198
+ C0 ),
3199
+ SubId ),
3200
+ maybe_unregister_consumer (
3201
+ VirtualHost , Consumer ,
3202
+ single_active_consumer (Consumer ),
3203
+ Rqsts0 );
3204
+ _ ->
3205
+ Rqsts0
3206
+ end
3193
3207
end , Requests0 , SubscriptionIds ),
3194
3208
{true ,
3195
3209
C0 # stream_connection {stream_subscriptions =
@@ -3208,17 +3222,25 @@ clean_state_after_stream_deletion_or_failure(Stream,
3208
3222
{PurgedPubs , PurgedPubToIds } =
3209
3223
maps :fold (fun (PubId ,
3210
3224
# publisher {stream = S , reference = Ref },
3211
- {Pubs , PubToIds }) ->
3212
- case S of
3213
- Stream ->
3225
+ {Pubs , PubToIds }) when S =:= Stream andalso MemberPid =:= undefined ->
3226
+ rabbit_stream_metrics :publisher_deleted (self (),
3227
+ stream_r (Stream ,
3228
+ C1 ),
3229
+ PubId ),
3230
+ {maps :remove (PubId , Pubs ),
3231
+ maps :remove ({Stream , Ref }, PubToIds )};
3232
+ (PubId ,
3233
+ # publisher {stream = S , reference = Ref , leader = MPid },
3234
+ {Pubs , PubToIds }) when S =:= Stream andalso MPid =:= MemberPid ->
3214
3235
rabbit_stream_metrics :publisher_deleted (self (),
3215
- stream_r (S ,
3236
+ stream_r (Stream ,
3216
3237
C1 ),
3217
3238
PubId ),
3218
3239
{maps :remove (PubId , Pubs ),
3219
3240
maps :remove ({Stream , Ref }, PubToIds )};
3220
- _ -> {Pubs , PubToIds }
3221
- end
3241
+
3242
+ (_PubId , _Publisher , {Pubs , PubToIds }) ->
3243
+ {Pubs , PubToIds }
3222
3244
end ,
3223
3245
{Publishers , PublisherToIds }, Publishers ),
3224
3246
{true ,
@@ -3240,7 +3262,7 @@ clean_state_after_stream_deletion_or_failure(Stream,
3240
3262
orelse LeadersCleaned
3241
3263
of
3242
3264
true ->
3243
- C3 = demonitor_stream (Stream , C2 ),
3265
+ C3 = demonitor_stream (MemberPid , Stream , C2 ),
3244
3266
{cleaned , C3 # stream_connection {stream_leaders = Leaders1 }, S2 };
3245
3267
false ->
3246
3268
{not_cleaned , C2 # stream_connection {stream_leaders = Leaders1 }, S2 }
@@ -3279,7 +3301,7 @@ remove_subscription(SubscriptionId,
3279
3301
# stream_connection_state {consumers = Consumers } = State ) ->
3280
3302
#{SubscriptionId := Consumer } = Consumers ,
3281
3303
# consumer {log = Log ,
3282
- configuration = # consumer_configuration {stream = Stream }} =
3304
+ configuration = # consumer_configuration {stream = Stream , member_pid = MemberPid }} =
3283
3305
Consumer ,
3284
3306
rabbit_log :debug (" Deleting subscription ~tp (stream ~tp )" ,
3285
3307
[SubscriptionId , Stream ]),
@@ -3299,7 +3321,7 @@ remove_subscription(SubscriptionId,
3299
3321
Connection # stream_connection {stream_subscriptions =
3300
3322
StreamSubscriptions1 },
3301
3323
Consumers1 = maps :remove (SubscriptionId , Consumers ),
3302
- Connection2 = maybe_clean_connection_from_stream (Stream , Connection1 ),
3324
+ Connection2 = maybe_clean_connection_from_stream (MemberPid , Stream , Connection1 ),
3303
3325
rabbit_stream_metrics :consumer_cancelled (self (),
3304
3326
stream_r (Stream , Connection2 ),
3305
3327
SubscriptionId ),
@@ -3312,7 +3334,7 @@ remove_subscription(SubscriptionId,
3312
3334
{Connection2 # stream_connection {outstanding_requests = Requests1 },
3313
3335
State # stream_connection_state {consumers = Consumers1 }}.
3314
3336
3315
- maybe_clean_connection_from_stream (Stream ,
3337
+ maybe_clean_connection_from_stream (MemberPid , Stream ,
3316
3338
# stream_connection {stream_leaders =
3317
3339
Leaders } =
3318
3340
Connection0 ) ->
@@ -3321,7 +3343,7 @@ maybe_clean_connection_from_stream(Stream,
3321
3343
stream_has_subscriptions (Stream , Connection0 )}
3322
3344
of
3323
3345
{false , false } ->
3324
- demonitor_stream (Stream , Connection0 );
3346
+ demonitor_stream (MemberPid , Stream , Connection0 );
3325
3347
_ ->
3326
3348
Connection0
3327
3349
end ,
@@ -3330,26 +3352,27 @@ maybe_clean_connection_from_stream(Stream,
3330
3352
3331
3353
maybe_monitor_stream (Pid , Stream ,
3332
3354
# stream_connection {monitors = Monitors } = Connection ) ->
3333
- case lists :member (Stream , maps :values (Monitors )) of
3355
+ case lists :member ({ Pid , Stream } , maps :values (Monitors )) of
3334
3356
true ->
3335
3357
Connection ;
3336
3358
false ->
3337
3359
MonitorRef = monitor (process , Pid ),
3338
3360
Connection # stream_connection {monitors =
3339
- maps :put (MonitorRef , Stream ,
3361
+ maps :put (MonitorRef , { Pid , Stream } ,
3340
3362
Monitors )}
3341
3363
end .
3342
3364
3343
- demonitor_stream (Stream ,
3365
+ demonitor_stream (MemberPid , Stream ,
3344
3366
# stream_connection {monitors = Monitors0 } = Connection ) ->
3345
3367
Monitors =
3346
- maps :fold (fun (MonitorRef , Strm , Acc ) ->
3347
- case Strm of
3348
- Stream ->
3349
- demonitor (MonitorRef , [flush ]),
3368
+ maps :fold (fun (MonitorRef , {MPid , Strm }, Acc ) when MPid =:= MemberPid andalso Strm =:= Stream ->
3369
+ demonitor (MonitorRef , [flush ]),
3370
+ Acc ;
3371
+ (MonitorRef , {_MPid , Strm }, Acc ) when MemberPid =:= undefined andalso Strm =:= Stream ->
3372
+ demonitor (MonitorRef , [flush ]),
3350
3373
Acc ;
3351
- _ -> maps : put (MonitorRef , Strm , Acc )
3352
- end
3374
+ (MonitorRef , { MPid , Strm } , Acc ) ->
3375
+ maps : put ( MonitorRef , { MPid , Strm }, Acc )
3353
3376
end ,
3354
3377
#{}, Monitors0 ),
3355
3378
Connection # stream_connection {monitors = Monitors }.
0 commit comments