Skip to content

Commit ad1e00b

Browse files
committed
MINOR: lua: handle proxy refcount
Implement proxy refcount for Lua proxy class. This is similar to the server class. In summary, proxy_take() is used to increment refcount when a Lua proxy is instantiated. proxy_drop() is called via Lua garbage collector. To ensure a deleted backend is released asap, hlua_check_proxy() now returns NULL if PR_FL_DELETED is set. This approach is directly dependable on Lua GC execution. As such, it probably suffers from the same limitations as the ones already described in the previous commit. With the current patch, "del backend" is not directly impacted though. However, the final proxy deinit may happen after a long period of time, which could cause memory pressure increase. One final observations regarding deinit : it is necessary to delay a BUG_ON() which checks that defaults proxies list is empty. Now this must be executed after Lua deinit (called via post_deinit_list). This should guarantee that all proxies and their defaults refcount are null.
1 parent f521c2c commit ad1e00b

2 files changed

Lines changed: 70 additions & 5 deletions

File tree

src/haproxy.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2824,10 +2824,6 @@ void deinit(void)
28242824
/* If named defaults were preserved, ensure <def_ref> count is resetted. */
28252825
if (!(global.tune.options & GTUNE_PURGE_DEFAULTS))
28262826
defaults_px_unref_all();
2827-
/* All proxies are removed now, so every defaults should also be freed
2828-
* when their <def_ref> count reached zero.
2829-
*/
2830-
BUG_ON(!LIST_ISEMPTY(&defaults_list));
28312827

28322828
userlist_free(userlist);
28332829

@@ -2838,6 +2834,11 @@ void deinit(void)
28382834
list_for_each_entry(pdf, &post_deinit_list, list)
28392835
pdf->fct();
28402836

2837+
/* All proxies are removed now, so every defaults should also be freed
2838+
* when their <def_ref> count reached zero.
2839+
*/
2840+
BUG_ON(!LIST_ISEMPTY(&defaults_list));
2841+
28412842
ha_free(&global.log_send_hostname);
28422843
chunk_destroy(&global.log_tag);
28432844
ha_free(&global.chroot);

src/hlua_fcn.c

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1966,16 +1966,31 @@ void hlua_listable_servers(lua_State *L, struct proxy *px)
19661966
lua_setmetatable(L, -2);
19671967
}
19681968

1969+
int hlua_proxy_gc(lua_State *L)
1970+
{
1971+
struct proxy *px = hlua_checkudata(L, 1, class_proxy_ref);
1972+
proxy_drop(px);
1973+
return 0;
1974+
}
1975+
19691976
static struct proxy *hlua_check_proxy(lua_State *L, int ud)
19701977
{
1971-
return hlua_checkudata(L, ud, class_proxy_ref);
1978+
struct proxy *px = hlua_checkudata(L, ud, class_proxy_ref);
1979+
if (px->flags & PR_FL_DELETED)
1980+
return NULL;
1981+
return px;
19721982
}
19731983

19741984
int hlua_proxy_get_name(lua_State *L)
19751985
{
19761986
struct proxy *px;
19771987

19781988
px = hlua_check_proxy(L, 1);
1989+
if (px == NULL) {
1990+
lua_pushnil(L);
1991+
return 0;
1992+
}
1993+
19791994
lua_pushstring(L, px->id);
19801995
return 1;
19811996
}
@@ -1986,6 +2001,11 @@ int hlua_proxy_get_uuid(lua_State *L)
19862001
char buffer[17];
19872002

19882003
px = hlua_check_proxy(L, 1);
2004+
if (px == NULL) {
2005+
lua_pushnil(L);
2006+
return 0;
2007+
}
2008+
19892009
snprintf(buffer, sizeof(buffer), "%d", px->uuid);
19902010
lua_pushstring(L, buffer);
19912011
return 1;
@@ -2024,6 +2044,9 @@ int hlua_proxy_pause(lua_State *L)
20242044
struct proxy *px;
20252045

20262046
px = hlua_check_proxy(L, 1);
2047+
if (px == NULL)
2048+
return 0;
2049+
20272050
/* safe to call without PROXY_LOCK - pause_proxy takes it */
20282051
pause_proxy(px);
20292052
return 0;
@@ -2034,6 +2057,9 @@ int hlua_proxy_resume(lua_State *L)
20342057
struct proxy *px;
20352058

20362059
px = hlua_check_proxy(L, 1);
2060+
if (px == NULL)
2061+
return 0;
2062+
20372063
/* safe to call without PROXY_LOCK - resume_proxy takes it */
20382064
resume_proxy(px);
20392065
return 0;
@@ -2044,6 +2070,9 @@ int hlua_proxy_stop(lua_State *L)
20442070
struct proxy *px;
20452071

20462072
px = hlua_check_proxy(L, 1);
2073+
if (px == NULL)
2074+
return 0;
2075+
20472076
/* safe to call without PROXY_LOCK - stop_proxy takes it */
20482077
stop_proxy(px);
20492078
return 0;
@@ -2055,6 +2084,11 @@ int hlua_proxy_get_cap(lua_State *L)
20552084
const char *str;
20562085

20572086
px = hlua_check_proxy(L, 1);
2087+
if (px == NULL) {
2088+
lua_pushnil(L);
2089+
return 0;
2090+
}
2091+
20582092
str = proxy_cap_str(px->cap);
20592093
lua_pushstring(L, str);
20602094
return 1;
@@ -2066,6 +2100,11 @@ int hlua_proxy_get_stats(lua_State *L)
20662100
int i;
20672101

20682102
px = hlua_check_proxy(L, 1);
2103+
if (px == NULL) {
2104+
lua_pushnil(L);
2105+
return 0;
2106+
}
2107+
20692108
if (px->cap & PR_CAP_BE)
20702109
stats_fill_be_line(px, STAT_F_SHLGNDS, stats, STATS_LEN, NULL);
20712110
else
@@ -2086,6 +2125,11 @@ int hlua_proxy_get_mode(lua_State *L)
20862125
const char *str;
20872126

20882127
px = hlua_check_proxy(L, 1);
2128+
if (px == NULL) {
2129+
lua_pushnil(L);
2130+
return 0;
2131+
}
2132+
20892133
str = proxy_mode_str(px->mode);
20902134
lua_pushstring(L, str);
20912135
return 1;
@@ -2096,6 +2140,9 @@ int hlua_proxy_shut_bcksess(lua_State *L)
20962140
struct proxy *px;
20972141

20982142
px = hlua_check_proxy(L, 1);
2143+
if (px == NULL)
2144+
return 0;
2145+
20992146
srv_shutdown_backup_streams(px, SF_ERR_KILLED);
21002147
return 0;
21012148
}
@@ -2105,6 +2152,11 @@ int hlua_proxy_get_srv_act(lua_State *L)
21052152
struct proxy *px;
21062153

21072154
px = hlua_check_proxy(L, 1);
2155+
if (px == NULL) {
2156+
lua_pushnil(L);
2157+
return 0;
2158+
}
2159+
21082160
lua_pushinteger(L, px->srv_act);
21092161
return 1;
21102162
}
@@ -2114,6 +2166,11 @@ int hlua_proxy_get_srv_bck(lua_State *L)
21142166
struct proxy *px;
21152167

21162168
px = hlua_check_proxy(L, 1);
2169+
if (px == NULL) {
2170+
lua_pushnil(L);
2171+
return 0;
2172+
}
2173+
21172174
lua_pushinteger(L, px->srv_bck);
21182175
return 1;
21192176
}
@@ -2128,6 +2185,10 @@ int hlua_proxy_get_mailers(lua_State *L)
21282185
struct mailer *mailer;
21292186

21302187
px = hlua_check_proxy(L, 1);
2188+
if (px == NULL) {
2189+
lua_pushnil(L);
2190+
return 0;
2191+
}
21312192

21322193
if (!px->email_alert.mailers.m)
21332194
return 0; /* email-alert mailers not found on proxy */
@@ -2208,6 +2269,8 @@ int hlua_fcn_new_proxy(lua_State *L, struct proxy *px)
22082269
lua_pushlightuserdata(L, px);
22092270
lua_rawseti(L, -2, 0);
22102271

2272+
proxy_take(px);
2273+
22112274
/* set public methods */
22122275
hlua_class_function(L, "get_name", hlua_proxy_get_name);
22132276
hlua_class_function(L, "get_uuid", hlua_proxy_get_uuid);
@@ -3233,6 +3296,7 @@ void hlua_fcn_reg_core_fcn(lua_State *L)
32333296

32343297
/* Create proxy object. */
32353298
lua_newtable(L);
3299+
hlua_class_function(L, "__gc", hlua_proxy_gc);
32363300
hlua_class_function(L, "__index", hlua_proxy_index);
32373301
class_proxy_ref = hlua_register_metatable(L, CLASS_PROXY);
32383302

0 commit comments

Comments
 (0)