23
23
-export ([init /1 ]).
24
24
25
25
-export ([start_link /0 , start /0 ]).
26
- -export ([vhost_sup /1 , vhost_sup /2 ]).
27
- -export ([start_vhost /1 , stop_and_delete_vhost /1 , delete_on_all_nodes /1 ]).
26
+ -export ([vhost_sup /1 , vhost_sup /2 , save_vhost_sup /3 ]).
27
+ -export ([delete_on_all_nodes /1 ]).
28
+ -export ([start_vhost /1 , start_vhost /2 , start_on_all_nodes /1 ]).
29
+
30
+ % % Internal
31
+ -export ([stop_and_delete_vhost /1 ]).
32
+
33
+ -record (vhost_sup , {vhost , vhost_sup_pid , wrapper_pid }).
28
34
29
35
start () ->
30
36
rabbit_sup :start_supervisor_child (? MODULE ).
@@ -33,39 +39,67 @@ start_link() ->
33
39
supervisor2 :start_link ({local , ? MODULE }, ? MODULE , []).
34
40
35
41
init ([]) ->
36
- ets :new (? MODULE , [named_table , public ]),
37
- {ok , {{simple_one_for_one , 1 , 5 },
38
- [{rabbit_vhost , {rabbit_vhost_sup_sup , start_vhost , []},
39
- transient , infinity , supervisor ,
40
- [rabbit_vhost_sup_sup , rabbit_vhost_sup ]}]}}.
42
+ ets :new (? MODULE , [named_table , public , {keypos , # vhost_sup .vhost }]),
43
+ {ok , {{simple_one_for_one , 0 , 5 },
44
+ [{rabbit_vhost , {rabbit_vhost_sup_wrapper , start_link , []},
45
+ permanent , infinity , supervisor ,
46
+ [rabbit_vhost_sup_wrapper , rabbit_vhost_sup ]}]}}.
47
+
48
+ start_on_all_nodes (VHost ) ->
49
+ [ {ok , _ } = start_vhost (VHost , Node ) || Node <- rabbit_nodes :all_running () ],
50
+ ok .
41
51
42
- start_vhost (VHost ) ->
43
- case rabbit_vhost_sup :start_link (VHost ) of
44
- {ok , Pid } ->
45
- ok = save_vhost_pid (VHost , Pid ),
46
- ok = rabbit_vhost :recover (VHost ),
52
+ delete_on_all_nodes (VHost ) ->
53
+ [ stop_and_delete_vhost (VHost , Node ) || Node <- rabbit_nodes :all_running () ],
54
+ ok .
55
+
56
+ start_vhost (VHost , Node ) when Node == node (self ()) ->
57
+ start_vhost (VHost );
58
+ start_vhost (VHost , Node ) ->
59
+ case rabbit_misc :rpc_call (Node , rabbit_vhost_sup_sup , start_vhost , [VHost ]) of
60
+ {ok , Pid } when is_pid (Pid ) ->
47
61
{ok , Pid };
48
- Other ->
49
- Other
62
+ { badrpc , RpcErr } ->
63
+ { error , RpcErr }
50
64
end .
51
65
52
- stop_and_delete_vhost (VHost ) ->
53
- case vhost_pid (VHost ) of
54
- no_pid -> ok ;
55
- Pid when is_pid (Pid ) ->
56
- rabbit_log :info (" Stopping vhost supervisor ~p for vhost ~p~n " ,
57
- [Pid , VHost ]),
58
- case supervisor2 :terminate_child (? MODULE , Pid ) of
59
- ok ->
60
- ok = rabbit_vhost :delete_storage (VHost );
61
- Other ->
62
- Other
66
+ start_vhost (VHost ) ->
67
+ case rabbit_vhost :exists (VHost ) of
68
+ false -> {error , {no_such_vhost , VHost }};
69
+ true ->
70
+ case vhost_sup_pid (VHost ) of
71
+ no_pid ->
72
+ case supervisor2 :start_child (? MODULE , [VHost ]) of
73
+ {ok , _ } -> ok ;
74
+ {error , {already_started , _ }} -> ok ;
75
+ Error -> throw (Error )
76
+ end ,
77
+ {ok , _ } = vhost_sup_pid (VHost );
78
+ {ok , Pid } when is_pid (Pid ) ->
79
+ {ok , Pid }
63
80
end
64
81
end .
65
82
66
- delete_on_all_nodes (VHost ) ->
67
- [ stop_and_delete_vhost (VHost , Node ) || Node <- rabbit_nodes :all_running () ],
68
- ok .
83
+ stop_and_delete_vhost (VHost ) ->
84
+ case get_vhost_sup (VHost ) of
85
+ not_found -> ok ;
86
+ # vhost_sup {wrapper_pid = WrapperPid ,
87
+ vhost_sup_pid = VHostSupPid } = VHostSup ->
88
+ case is_process_alive (WrapperPid ) of
89
+ false -> ok ;
90
+ true ->
91
+ rabbit_log :info (" Stopping vhost supervisor ~p "
92
+ " for vhost ~p~n " ,
93
+ [VHostSupPid , VHost ]),
94
+ case supervisor2 :terminate_child (? MODULE , WrapperPid ) of
95
+ ok ->
96
+ ets :delete_object (? MODULE , VHostSup ),
97
+ ok = rabbit_vhost :delete_storage (VHost );
98
+ Other ->
99
+ Other
100
+ end
101
+ end
102
+ end .
69
103
70
104
% % We take an optimistic approach whan stopping a remote VHost supervisor.
71
105
stop_and_delete_vhost (VHost , Node ) when Node == node (self ()) ->
@@ -81,6 +115,7 @@ stop_and_delete_vhost(VHost, Node) ->
81
115
{error , RpcErr }
82
116
end .
83
117
118
+ -spec vhost_sup (rabbit_types :vhost (), node ()) -> {ok , pid ()}.
84
119
vhost_sup (VHost , Local ) when Local == node (self ()) ->
85
120
vhost_sup (VHost );
86
121
vhost_sup (VHost , Node ) ->
@@ -93,34 +128,33 @@ vhost_sup(VHost, Node) ->
93
128
94
129
-spec vhost_sup (rabbit_types :vhost ()) -> {ok , pid ()}.
95
130
vhost_sup (VHost ) ->
96
- case rabbit_vhost :exists (VHost ) of
97
- false -> {error , {no_such_vhost , VHost }};
98
- true ->
99
- case vhost_pid (VHost ) of
100
- no_pid ->
101
- case supervisor2 :start_child (? MODULE , [VHost ]) of
102
- {ok , Pid } -> {ok , Pid };
103
- {error , {already_started , Pid }} -> {ok , Pid };
104
- Error -> throw (Error )
105
- end ;
106
- Pid when is_pid (Pid ) ->
107
- {ok , Pid }
108
- end
109
- end .
131
+ start_vhost (VHost ).
110
132
111
- save_vhost_pid (VHost , Pid ) ->
112
- true = ets :insert (? MODULE , {VHost , Pid }),
133
+ -spec save_vhost_sup (rabbit_types :vhost (), pid (), pid ()) -> ok .
134
+ save_vhost_sup (VHost , WrapperPid , VHostPid ) ->
135
+ true = ets :insert (? MODULE , # vhost_sup {vhost = VHost ,
136
+ vhost_sup_pid = VHostPid ,
137
+ wrapper_pid = WrapperPid }),
113
138
ok .
114
139
115
- -spec vhost_pid (rabbit_types :vhost ()) -> no_pid | pid () .
116
- vhost_pid (VHost ) ->
140
+ -spec get_vhost_sup (rabbit_types :vhost ()) -> # vhost_sup {} .
141
+ get_vhost_sup (VHost ) ->
117
142
case ets :lookup (? MODULE , VHost ) of
118
- [] -> no_pid ;
119
- [{VHost , Pid }] ->
143
+ [] -> not_found ;
144
+ [# vhost_sup {} = VHostSup ] -> VHostSup
145
+ end .
146
+
147
+ -spec vhost_sup_pid (rabbit_types :vhost ()) -> no_pid | {ok , pid ()}.
148
+ vhost_sup_pid (VHost ) ->
149
+ case get_vhost_sup (VHost ) of
150
+ not_found ->
151
+ no_pid ;
152
+ # vhost_sup {vhost_sup_pid = Pid } = VHostSup ->
120
153
case erlang :is_process_alive (Pid ) of
121
- true -> Pid ;
154
+ true -> { ok , Pid } ;
122
155
false ->
123
- ets :delete_object (? MODULE , { VHost , Pid } ),
156
+ ets :delete_object (? MODULE , VHostSup ),
124
157
no_pid
125
158
end
126
159
end .
160
+
0 commit comments