|
33 | 33 | delete_super_stream/3,
|
34 | 34 | lookup_leader/2,
|
35 | 35 | lookup_local_member/2,
|
| 36 | + lookup_member/2, |
36 | 37 | topology/2,
|
37 | 38 | route/3,
|
38 | 39 | partitions/2,
|
@@ -100,11 +101,17 @@ lookup_leader(VirtualHost, Stream) ->
|
100 | 101 | lookup_local_member(VirtualHost, Stream) ->
|
101 | 102 | gen_server:call(?MODULE, {lookup_local_member, VirtualHost, Stream}).
|
102 | 103 |
|
| 104 | +-spec lookup_member(binary(), binary()) -> |
| 105 | + {ok, pid()} | {error, not_found} | |
| 106 | + {error, not_available}. |
| 107 | +lookup_member(VirtualHost, Stream) -> |
| 108 | + gen_server:call(?MODULE, {lookup_member, VirtualHost, Stream}). |
| 109 | + |
103 | 110 | -spec topology(binary(), binary()) ->
|
104 | 111 | {ok,
|
105 | 112 | #{leader_node => undefined | pid(),
|
106 | 113 | replica_nodes => [pid()]}} |
|
107 |
| - {error, stream_not_found} | {error, stream_not_available}. |
| 114 | + {error, not_found} | {error, not_available}. |
108 | 115 | topology(VirtualHost, Stream) ->
|
109 | 116 | gen_server:call(?MODULE, {topology, VirtualHost, Stream}).
|
110 | 117 |
|
@@ -292,119 +299,105 @@ handle_call({delete_super_stream, VirtualHost, SuperStream, Username},
|
292 | 299 | {reply, {error, Error}, State}
|
293 | 300 | end;
|
294 | 301 | handle_call({lookup_leader, VirtualHost, Stream}, _From, State) ->
|
295 |
| - Name = |
296 |
| - #resource{virtual_host = VirtualHost, |
297 |
| - kind = queue, |
298 |
| - name = Stream}, |
299 |
| - Res = case rabbit_amqqueue:lookup(Name) of |
| 302 | + Res = case lookup_stream(VirtualHost, Stream) of |
300 | 303 | {ok, Q} ->
|
301 |
| - case is_stream_queue(Q) of |
| 304 | + LeaderPid = amqqueue:get_pid(Q), |
| 305 | + case process_alive(LeaderPid) of |
302 | 306 | true ->
|
303 |
| - LeaderPid = amqqueue:get_pid(Q), |
304 |
| - case process_alive(LeaderPid) of |
305 |
| - true -> |
306 |
| - {ok, LeaderPid}; |
307 |
| - false -> |
308 |
| - case leader_from_members(Q) of |
309 |
| - {ok, Pid} -> |
310 |
| - {ok, Pid}; |
311 |
| - _ -> |
312 |
| - {error, not_available} |
313 |
| - end |
314 |
| - end; |
315 |
| - _ -> |
316 |
| - {error, not_found} |
| 307 | + {ok, LeaderPid}; |
| 308 | + false -> |
| 309 | + case leader_from_members(Q) of |
| 310 | + {ok, Pid} -> |
| 311 | + {ok, Pid}; |
| 312 | + _ -> |
| 313 | + {error, not_available} |
| 314 | + end |
317 | 315 | end;
|
318 |
| - {error, not_found} -> |
319 |
| - case rabbit_amqqueue:not_found_or_absent_dirty(Name) of |
320 |
| - not_found -> |
321 |
| - {error, not_found}; |
322 |
| - _ -> |
323 |
| - {error, not_available} |
324 |
| - end |
| 316 | + R -> |
| 317 | + R |
325 | 318 | end,
|
326 | 319 | {reply, Res, State};
|
327 | 320 | handle_call({lookup_local_member, VirtualHost, Stream}, _From,
|
328 | 321 | State) ->
|
329 |
| - Name = |
330 |
| - #resource{virtual_host = VirtualHost, |
331 |
| - kind = queue, |
332 |
| - name = Stream}, |
333 |
| - Res = case rabbit_amqqueue:lookup(Name) of |
| 322 | + Res = case lookup_stream(VirtualHost, Stream) of |
334 | 323 | {ok, Q} ->
|
335 |
| - case is_stream_queue(Q) of |
336 |
| - true -> |
337 |
| - #{name := StreamName} = amqqueue:get_type_state(Q), |
338 |
| - % FIXME check if pid is alive in case of stale information |
339 |
| - case rabbit_stream_coordinator:local_pid(StreamName) |
340 |
| - of |
341 |
| - {ok, Pid} when is_pid(Pid) -> |
342 |
| - {ok, Pid}; |
343 |
| - {error, timeout} -> |
344 |
| - {error, not_available}; |
345 |
| - _ -> |
346 |
| - {error, not_available} |
347 |
| - end; |
348 |
| - _ -> |
349 |
| - {error, not_found} |
350 |
| - end; |
351 |
| - {error, not_found} -> |
352 |
| - case rabbit_amqqueue:not_found_or_absent_dirty(Name) of |
353 |
| - not_found -> |
354 |
| - {error, not_found}; |
| 324 | + #{name := StreamName} = amqqueue:get_type_state(Q), |
| 325 | + % FIXME check if pid is alive in case of stale information |
| 326 | + case rabbit_stream_coordinator:local_pid(StreamName) of |
| 327 | + {ok, Pid} when is_pid(Pid) -> |
| 328 | + {ok, Pid}; |
| 329 | + {error, timeout} -> |
| 330 | + {error, not_available}; |
355 | 331 | _ ->
|
356 | 332 | {error, not_available}
|
357 |
| - end |
| 333 | + end; |
| 334 | + R -> |
| 335 | + R |
358 | 336 | end,
|
359 | 337 | {reply, Res, State};
|
360 |
| -handle_call({topology, VirtualHost, Stream}, _From, State) -> |
361 |
| - Name = |
362 |
| - #resource{virtual_host = VirtualHost, |
363 |
| - kind = queue, |
364 |
| - name = Stream}, |
365 |
| - Res = case rabbit_amqqueue:lookup(Name) of |
| 338 | +handle_call({lookup_member, VirtualHost, Stream}, _From, State) -> |
| 339 | + Res = case lookup_stream(VirtualHost, Stream) of |
366 | 340 | {ok, Q} ->
|
367 |
| - case is_stream_queue(Q) of |
368 |
| - true -> |
369 |
| - QState = amqqueue:get_type_state(Q), |
370 |
| - #{name := StreamName} = QState, |
| 341 | + #{name := StreamName} = amqqueue:get_type_state(Q), |
| 342 | + % FIXME check if pid is alive in case of stale information |
| 343 | + case rabbit_stream_coordinator:local_pid(StreamName) of |
| 344 | + {ok, Pid} when is_pid(Pid) -> |
| 345 | + {ok, Pid}; |
| 346 | + _ -> |
371 | 347 | case rabbit_stream_coordinator:members(StreamName) of
|
372 | 348 | {ok, Members} ->
|
373 |
| - {ok, |
374 |
| - maps:fold(fun (_Node, {undefined, _Role}, |
375 |
| - Acc) -> |
376 |
| - Acc; |
377 |
| - (LeaderNode, {_Pid, writer}, |
378 |
| - Acc) -> |
379 |
| - Acc#{leader_node => |
380 |
| - LeaderNode}; |
381 |
| - (ReplicaNode, {_Pid, replica}, |
382 |
| - Acc) -> |
383 |
| - #{replica_nodes := |
384 |
| - ReplicaNodes} = |
385 |
| - Acc, |
386 |
| - Acc#{replica_nodes => |
387 |
| - ReplicaNodes |
388 |
| - ++ [ReplicaNode]}; |
389 |
| - (_Node, _, Acc) -> |
390 |
| - Acc |
391 |
| - end, |
392 |
| - #{leader_node => undefined, |
393 |
| - replica_nodes => []}, |
394 |
| - Members)}; |
| 349 | + case lists:search(fun ({undefined, _Role}) -> |
| 350 | + false; |
| 351 | + ({P, _Role}) |
| 352 | + when is_pid(P) -> |
| 353 | + is_process_alive(P); |
| 354 | + (_) -> |
| 355 | + false |
| 356 | + end, |
| 357 | + maps:values(Members)) |
| 358 | + of |
| 359 | + {value, {Pid, _Role}} -> |
| 360 | + {ok, Pid}; |
| 361 | + _ -> |
| 362 | + {error, not_available} |
| 363 | + end; |
395 | 364 | _ ->
|
396 |
| - {error, stream_not_available} |
397 |
| - end; |
398 |
| - _ -> |
399 |
| - {error, stream_not_found} |
| 365 | + {error, not_available} |
| 366 | + end |
400 | 367 | end;
|
401 |
| - {error, not_found} -> |
402 |
| - case rabbit_amqqueue:not_found_or_absent_dirty(Name) of |
403 |
| - not_found -> |
404 |
| - {error, stream_not_found}; |
| 368 | + R -> |
| 369 | + R |
| 370 | + end, |
| 371 | + {reply, Res, State}; |
| 372 | +handle_call({topology, VirtualHost, Stream}, _From, State) -> |
| 373 | + Res = case lookup_stream(VirtualHost, Stream) of |
| 374 | + {ok, Q} -> |
| 375 | + QState = amqqueue:get_type_state(Q), |
| 376 | + #{name := StreamName} = QState, |
| 377 | + case rabbit_stream_coordinator:members(StreamName) of |
| 378 | + {ok, Members} -> |
| 379 | + {ok, |
| 380 | + maps:fold(fun (_Node, {undefined, _Role}, Acc) -> |
| 381 | + Acc; |
| 382 | + (LeaderNode, {_Pid, writer}, Acc) -> |
| 383 | + Acc#{leader_node => LeaderNode}; |
| 384 | + (ReplicaNode, {_Pid, replica}, Acc) -> |
| 385 | + #{replica_nodes := ReplicaNodes} = |
| 386 | + Acc, |
| 387 | + Acc#{replica_nodes => |
| 388 | + ReplicaNodes |
| 389 | + ++ [ReplicaNode]}; |
| 390 | + (_Node, _, Acc) -> |
| 391 | + Acc |
| 392 | + end, |
| 393 | + #{leader_node => undefined, |
| 394 | + replica_nodes => []}, |
| 395 | + Members)}; |
405 | 396 | _ ->
|
406 |
| - {error, stream_not_available} |
407 |
| - end |
| 397 | + {error, not_available} |
| 398 | + end; |
| 399 | + R -> |
| 400 | + R |
408 | 401 | end,
|
409 | 402 | {reply, Res, State};
|
410 | 403 | handle_call({route, RoutingKey, VirtualHost, SuperStream}, _From,
|
@@ -837,6 +830,28 @@ delete_super_stream_exchange(VirtualHost, Name, Username) ->
|
837 | 830 | {error, validation_failed}
|
838 | 831 | end.
|
839 | 832 |
|
| 833 | +lookup_stream(VirtualHost, Stream) -> |
| 834 | + Name = |
| 835 | + #resource{virtual_host = VirtualHost, |
| 836 | + kind = queue, |
| 837 | + name = Stream}, |
| 838 | + case rabbit_amqqueue:lookup(Name) of |
| 839 | + {ok, Q} -> |
| 840 | + case is_stream_queue(Q) of |
| 841 | + true -> |
| 842 | + {ok, Q}; |
| 843 | + _ -> |
| 844 | + {error, not_found} |
| 845 | + end; |
| 846 | + {error, not_found} -> |
| 847 | + case rabbit_amqqueue:not_found_or_absent_dirty(Name) of |
| 848 | + not_found -> |
| 849 | + {error, not_found}; |
| 850 | + _ -> |
| 851 | + {error, not_available} |
| 852 | + end |
| 853 | + end. |
| 854 | + |
840 | 855 | leader_from_members(Q) ->
|
841 | 856 | QState = amqqueue:get_type_state(Q),
|
842 | 857 | #{name := StreamName} = QState,
|
|
0 commit comments