@@ -41,24 +41,31 @@ start_child({VHost, ShovelName} = Name, Def) ->
41
41
LockId = rabbit_shovel_locks :lock (Name ),
42
42
cleanup_specs (),
43
43
rabbit_log_shovel :debug (" Starting a mirrored supervisor named '~s ' in virtual host '~s '" , [ShovelName , VHost ]),
44
- Result = case mirrored_supervisor :start_child (
44
+ case child_exists (Name )
45
+ orelse mirrored_supervisor :start_child (
45
46
? SUPERVISOR ,
46
47
{id (Name ), {rabbit_shovel_dyn_worker_sup , start_link , [Name , obfuscated_uris_parameters (Def )]},
47
48
transient , ? WORKER_WAIT , worker , [rabbit_shovel_dyn_worker_sup ]}) of
49
+ true -> ok ;
48
50
{ok , _Pid } -> ok ;
49
51
{error , {already_started , _Pid }} -> ok
50
52
end ,
51
53
% % release the lock if we managed to acquire one
52
54
rabbit_shovel_locks :unlock (LockId ),
53
- Result .
55
+ ok .
54
56
55
57
obfuscated_uris_parameters (Def ) when is_map (Def ) ->
56
58
to_map (rabbit_shovel_parameters :obfuscate_uris_in_definition (to_list (Def )));
57
59
obfuscated_uris_parameters (Def ) when is_list (Def ) ->
58
60
rabbit_shovel_parameters :obfuscate_uris_in_definition (Def ).
59
61
60
62
child_exists (Name ) ->
61
- lists :any (fun ({{_ , N }, _ , _ , _ }) -> N =:= Name end ,
63
+ Id = id (Name ),
64
+ % % older format, pre 3.13.0, 3.12.8 and 3.11.25. See rabbitmq/rabbitmq-server#9894.
65
+ OldId = old_id (Name ),
66
+ lists :any (fun ({ChildId , _ , _ , _ }) ->
67
+ ChildId =:= Id orelse ChildId =:= OldId
68
+ end ,
62
69
mirrored_supervisor :which_children (? SUPERVISOR )).
63
70
64
71
stop_child ({VHost , ShovelName } = Name ) ->
@@ -67,8 +74,18 @@ stop_child({VHost, ShovelName} = Name) ->
67
74
case get ({shovel_worker_autodelete , Name }) of
68
75
true -> ok ; % % [1]
69
76
_ ->
70
- ok = mirrored_supervisor :terminate_child (? SUPERVISOR , id (Name )),
71
- ok = mirrored_supervisor :delete_child (? SUPERVISOR , id (Name )),
77
+ case mirrored_supervisor :terminate_child (? SUPERVISOR , id (Name )) of
78
+ ok ->
79
+ ok = mirrored_supervisor :delete_child (? SUPERVISOR , id (Name ));
80
+ {error , not_found } ->
81
+ % % try older format, pre 3.13.0, 3.12.8 and 3.11.25. See rabbitmq/rabbitmq-server#9894.
82
+ case mirrored_supervisor :terminate_child (? SUPERVISOR , old_id (Name )) of
83
+ ok ->
84
+ ok = mirrored_supervisor :delete_child (? SUPERVISOR , old_id (Name ));
85
+ {error , not_found } ->
86
+ ok
87
+ end
88
+ end ,
72
89
rabbit_shovel_status :remove (Name )
73
90
end ,
74
91
rabbit_shovel_locks :unlock (LockId ),
@@ -83,19 +100,38 @@ stop_child({VHost, ShovelName} = Name) ->
83
100
% % See rabbit_shovel_worker:terminate/2
84
101
85
102
cleanup_specs () ->
86
- SpecsSet = sets :from_list ([element (2 , element (1 , S )) || S <- mirrored_supervisor :which_children (? SUPERVISOR )]),
87
- ParamsSet = sets :from_list ([ {proplists :get_value (vhost , S ), proplists :get_value (name , S )}
88
- || S <- rabbit_runtime_parameters :list_component (<<" shovel" >>) ]),
89
- F = fun (Name , ok ) ->
90
- _ = mirrored_supervisor :delete_child (? SUPERVISOR , id (Name )),
103
+ Children = mirrored_supervisor :which_children (? SUPERVISOR ),
104
+
105
+ ChildIdSet = sets :from_list ([element (1 , S ) || S <- Children ]),
106
+ ParamsSet = sets :from_list (
107
+ lists :flatmap (
108
+ fun (S ) ->
109
+ Name = {proplists :get_value (vhost , S ), proplists :get_value (name , S )},
110
+ % % Supervisor Id format was different pre 3.13.0, 3.12.8 and 3.11.25.
111
+ % % Try both formats to cover the transitionary mixed version cluster period.
112
+ [id (Name ), old_id (Name )]
113
+ end ,
114
+ rabbit_runtime_parameters :list_component (<<" shovel" >>))),
115
+ F = fun (ChildId , ok ) ->
116
+ try
117
+ _ = mirrored_supervisor :delete_child (? SUPERVISOR , ChildId )
118
+ catch _ :_ :_Stacktrace ->
119
+ ok
120
+ end ,
91
121
ok
92
122
end ,
93
- ok = sets :fold (F , ok , sets :subtract (SpecsSet , ParamsSet )).
123
+ % % Delete any supervisor children that do not have their respective runtime parameters in the database.
124
+ SetToCleanUp = sets :subtract (ChildIdSet , ParamsSet ),
125
+ ok = sets :fold (F , ok , SetToCleanUp ).
94
126
95
127
% %----------------------------------------------------------------------------
96
128
97
129
init ([]) ->
98
130
{ok , {{one_for_one , 3 , 10 }, []}}.
99
131
100
132
id ({V , S } = Name ) ->
101
- {[V , S ], Name }.
133
+ {[V , S ], Name }.
134
+
135
+ % % older format, pre 3.13.0, 3.12.8 and 3.11.25. See rabbitmq/rabbitmq-server#9894
136
+ old_id ({_V , _S } = Name ) ->
137
+ Name .
0 commit comments