return state;
}
+/* Store <sv> in <ctx> safely by using refcount to prevent server deletion. */
+static void promex_set_ctx_sv(struct promex_ctx *ctx, struct server *sv)
+{
+ srv_drop(ctx->sv);
+ ctx->sv = sv;
+ if (ctx->sv)
+ srv_take(ctx->sv);
+}
+
/* Convert a field to its string representation and write it in <out>, followed
* by a newline, if there is enough space. non-numeric value are converted in
* "NaN" because Prometheus only support numerical values (but it is unexepceted
&val, labels, &out, max))
goto full;
next_sv:
- ctx->sv = sv->next;
+ promex_set_ctx_sv(ctx, sv->next);
}
next_px:
ctx->px = px->next;
- ctx->sv = (ctx->px ? ctx->px->srv : NULL);
+ promex_set_ctx_sv(ctx, ctx->px ? ctx->px->srv : NULL);
}
ctx->flags |= PROMEX_FL_METRIC_HDR;
ctx->px = proxies_list;
- ctx->sv = (ctx->px ? ctx->px->srv : NULL);
+ promex_set_ctx_sv(ctx, ctx->px ? ctx->px->srv : NULL);
}
ctx->px = NULL;
ctx->st = NULL;
ctx->li = NULL;
- ctx->sv = NULL;
+ promex_set_ctx_sv(ctx, NULL);
ctx->flags |= (PROMEX_FL_METRIC_HDR|PROMEX_FL_INFO_METRIC);
ctx->obj_state = 0;
ctx->field_num = INF_NAME;
ctx->px = proxies_list;
ctx->st = NULL;
ctx->li = NULL;
- ctx->sv = NULL;
+ promex_set_ctx_sv(ctx, NULL);
ctx->flags &= ~PROMEX_FL_INFO_METRIC;
ctx->flags |= (PROMEX_FL_METRIC_HDR|PROMEX_FL_FRONT_METRIC);
ctx->obj_state = 0;
ctx->px = proxies_list;
ctx->st = NULL;
ctx->li = LIST_NEXT(&proxies_list->conf.listeners, struct listener *, by_fe);
- ctx->sv = NULL;
+ promex_set_ctx_sv(ctx, NULL);
ctx->flags &= ~PROMEX_FL_FRONT_METRIC;
ctx->flags |= (PROMEX_FL_METRIC_HDR|PROMEX_FL_LI_METRIC);
ctx->obj_state = 0;
ctx->px = proxies_list;
ctx->st = NULL;
ctx->li = NULL;
- ctx->sv = NULL;
+ promex_set_ctx_sv(ctx, NULL);
ctx->flags &= ~PROMEX_FL_LI_METRIC;
ctx->flags |= (PROMEX_FL_METRIC_HDR|PROMEX_FL_BACK_METRIC);
ctx->obj_state = 0;
ctx->px = proxies_list;
ctx->st = NULL;
ctx->li = NULL;
- ctx->sv = ctx->px ? ctx->px->srv : NULL;
+ promex_set_ctx_sv(ctx, ctx->px ? ctx->px->srv : NULL);
ctx->flags &= ~PROMEX_FL_BACK_METRIC;
ctx->flags |= (PROMEX_FL_METRIC_HDR|PROMEX_FL_SRV_METRIC);
ctx->obj_state = 0;
ctx->px = NULL;
ctx->st = stktables_list;
ctx->li = NULL;
- ctx->sv = NULL;
+ promex_set_ctx_sv(ctx, NULL);
ctx->flags &= ~(PROMEX_FL_METRIC_HDR|PROMEX_FL_SRV_METRIC);
ctx->flags |= (PROMEX_FL_METRIC_HDR|PROMEX_FL_STICKTABLE_METRIC);
ctx->field_num = STICKTABLE_SIZE;
ctx->px = NULL;
ctx->st = NULL;
ctx->li = NULL;
- ctx->sv = NULL;
+ promex_set_ctx_sv(ctx, NULL);
ctx->flags &= ~(PROMEX_FL_METRIC_HDR|PROMEX_FL_STICKTABLE_METRIC);
ctx->field_num = 0;
appctx->st1 = PROMEX_DUMPER_DONE;
ctx->px = NULL;
ctx->st = NULL;
ctx->li = NULL;
- ctx->sv = NULL;
+ promex_set_ctx_sv(ctx, NULL);
ctx->flags = 0;
ctx->field_num = 0;
appctx->st1 = PROMEX_DUMPER_DONE;
return 0;
}
+/* Callback function that releases a promex applet. This happens when the
+ * connection with the agent is closed. */
+static void promex_appctx_release(struct appctx *appctx)
+{
+ struct promex_ctx *ctx = appctx->svcctx;
+
+ if (appctx->st1 == PROMEX_DUMPER_SRV)
+ srv_drop(ctx->sv);
+}
+
/* The main I/O handler for the promex applet. */
static void promex_appctx_handle_io(struct appctx *appctx)
{
.name = "<PROMEX>", /* used for logging */
.init = promex_appctx_init,
.fct = promex_appctx_handle_io,
+ .release = promex_appctx_release,
};
static enum act_parse_ret service_parse_prometheus_exporter(const char **args, int *cur_arg, struct proxy *px,