BUG/MINOR: spoe: Allow applet creation when closing the last one during stopping
authorChristopher Faulet <cfaulet@haproxy.com>
Wed, 19 Feb 2025 10:33:02 +0000 (11:33 +0100)
committerChristopher Faulet <cfaulet@haproxy.com>
Wed, 19 Feb 2025 12:08:33 +0000 (13:08 +0100)
When the last SPOE applet is closed, for any reason, if there are still some
pending messages, in the shared sending queueu or the shared waiting queue, a
new applet is automatically created to be able to pocess these messages. Howver,
this was not performed when HAProxy was stopping. But it was an error because it
was then possible to abort some messages and reported them on error with the
status code set to 256.

So, now, it is still possible to create applet, if necessary, when HAProxy is
stopping.

This patch should partially fix the issue #2868. It must be backported to all
stable versions.

src/flt_spoe.c

index 5eb4cc8..7d8c89c 100644 (file)
@@ -1330,13 +1330,12 @@ spoe_release_appctx(struct appctx *appctx)
        }
        else {
                /* It is the last running applet and the sending and async
-                * waiting queues are not empty. So try to start a new applet if
-                * HAproxy is not stopping. On success, we remove reference on
-                * the current appctx from streams in the async waiting queue.
-                * In async mode, the ACK may be received from another appctx.
+                * waiting queues are not empty. So try to start a new applet.
+                * On success, we remove reference on the current appctx
+                * from streams in the async waiting queue.  In async mode, the
+                * ACK may be received from another appctx.
                 */
-               if (!stopping &&
-                   (!LIST_ISEMPTY(&agent->rt[tid].sending_queue) || !LIST_ISEMPTY(&agent->rt[tid].waiting_queue)) &&
+               if ((!LIST_ISEMPTY(&agent->rt[tid].sending_queue) || !LIST_ISEMPTY(&agent->rt[tid].waiting_queue)) &&
                    spoe_create_appctx(agent->spoe_conf)) {
                        list_for_each_entry_safe(ctx, back, &agent->rt[tid].waiting_queue, list) {
                                if (ctx->spoe_appctx == spoe_appctx)