From: James Jones Date: Mon, 27 Mar 2023 22:16:32 +0000 (-0500) Subject: First attempt at a state transition diagram for trunk requests (#4940) X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ce3ded0d8644fd77d347d4b48c624de87234721a;p=thirdparty%2Ffreeradius-server.git First attempt at a state transition diagram for trunk requests (#4940) Some of the functions cause two state transitions. Those are shown with dashed-style edges, with a distinct color. --- diff --git a/src/lib/server/trunk.c b/src/lib/server/trunk.c index 97ab792c662..e6c87f87e95 100644 --- a/src/lib/server/trunk.c +++ b/src/lib/server/trunk.c @@ -122,6 +122,7 @@ struct fr_trunk_request_s { /** Associates request queues with a connection * * @dotfile src/lib/server/trunk_conn.gv "Trunk connection state machine" + * @dotfile src/lib/server/trunk_req.gv "Trunk request state machine" */ struct fr_trunk_connection_s { struct fr_trunk_connection_pub_s pub; //!< Public fields in the trunk connection. diff --git a/src/lib/server/trunk_req.gv b/src/lib/server/trunk_req.gv new file mode 100644 index 00000000000..f4232e37a16 --- /dev/null +++ b/src/lib/server/trunk_req.gv @@ -0,0 +1,101 @@ +/* + * This program is is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + + /** + * $Id$ + * + * Copyright 2023 Network RADIUS SARL (legal@networkradius.com) + */ + + digraph fr_trunk_request_t_states { + label = "fr_trunk_request_t states" + condition_key [ + shape=plaintext + label=< + + + + + + + + +
[ no_cancel_mux ] [ !treq->pub.trunkfuncs.request_cancel_mux ]
[ enqueue_backlog ] { trunk_request_check_enqueue() == FR_TRUNK_ENQUEUE_IN_BACKLOG ]
[ enqueue_pending ] { trunk_request_check_enqueue() == FR_TRUNK_ENQUEUE_PENDING ]
[ on_connection ] { treq->pub.tconn == tconn ]
[ not_too_many ] { count < max ]
[ in_states ] { treq->pub.state & states ]
[ dequeueable ] { on_connection && not_too_many && in_states ]
+ >]; + + subgraph cluster_01 { + label = "Legend" + node [shape=point] + { + rank=same + d0 [style = invis]; + d1 [style = invis]; + p0 [style = invis]; + p1 [style = invis]; + } + d0 -> d1 [label="> 1 transition/call" style=dashed] + p0 -> p1 [label="1 transition/call"] + } + + node [shape = point, width=.1 ]; alloc; + node [shape = circle, label = "INIT", width=1 ]; init; + node [shape = doublecircle, label = "COMPLETE", width=1 ]; complete; + node [shape = doublecircle, label = "FAILED", width=1 ]; failed; + node [shape = doublecircle, label = "CANCEL COMPLETE", width=1 ]; cancel_complete; + node [shape = circle, label = "UNASSIGNED", width=1 ]; unassigned; + node [shape = circle, label = "BACKLOG", width=1 ]; backlog; + node [shape = circle, label = "PENDING", width=1 ]; pending; + node [shape = circle, label = "PARTIAL", width=1]; partial; + node [shape = circle, label = "SENT", width=1 ]; sent; + node [shape = circle, label = "CANCEL", width=1 ]; cancel; + node [shape = circle, label = "CANCEL SENT", width=1 ]; cancel_sent; + node [shape = circle, label = "CANCEL PARTIAL", width=1 ]; cancel_partial; + + {rank=source; alloc;} + + {rank=same; init; pending;} + + {rank=sink; complete;} + {rank=sink; failed;} + {rank=sink; cancel_complete;} + + alloc -> init + + backlog -> failed [label = "_trunk_free();"] + + {backlog, pending, cancel, cancel_partial, cancel_sent} -> unassigned [ label = "trunk_connection_requests_dequeue(); [ dequeueable ]" ] + + cancel -> cancel_partial [ label = "fr_trunk_request_signal_cancel_partial()" ] + + {cancel, cancel_partial} -> cancel_sent [ label = "trunk_request_signal_sent()" ] + + {cancel, cancel_sent} -> cancel_complete [ label = "fr_trunk_request_signal_cancel_complete(()" ] + + init -> backlog [ label = "fr_trunk_request_enqueue(); [ enqueue_backlog ]" ] + init -> pending [ label = "fr_trunk_request_enqueue(); [ enqueue_pending ]" ] + + {pending, partial} -> sent [ label = "fr_trunk_request_signal_sent()" ] + + {partial, sent} -> cancel [label = "fr_trunk_request_requeue()", style = dashed, color = red] + cancel -> pending [style = dashed, color = red] + {partial, sent} -> cancel [label = "fr_trunk_request_signal_cancel()", style = dashed, color = blue] + cancel -> unassigned [label = "no_cancel_mux", style = dashed, color = blue] + + {sent, pending} -> complete [ label = "fr_trunk_request_signal_complete()" ] + + pending -> partial [ label = "fr_trunk_request_signal_partial()" ] + +}