Skip to content

Commit

Permalink
final gc call implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
jean-christophe81 committed Feb 6, 2024
1 parent d6851aa commit 3745e43
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 21 deletions.
15 changes: 14 additions & 1 deletion broker/lua/inc/com/centreon/broker/lua/broker_event.hh
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,26 @@ namespace lua {
*
*/
class broker_event {
struct gc_info {
gc_info() : _broker_event_cpt(0), _last_full_gc(time(nullptr)) {}

unsigned _broker_event_cpt;
time_t _last_full_gc;
};

static std::map<const lua_State*, gc_info> _gc_info;
static std::mutex _gc_info_m;

static int l_broker_event_destructor(lua_State* L);

public:
static void broker_event_reg(lua_State* L);
static void create(lua_State* L, std::shared_ptr<io::data> e);
static void create_as_table(lua_State* L, const io::data& e);
static void lua_close(const lua_State* L);
};
} // namespace lua

}
} // namespace com::centreon::broker

#endif // !CCB_LUA_BROKER_EVENT_HH
3 changes: 0 additions & 3 deletions broker/lua/inc/com/centreon/broker/lua/luabinding.hh
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,6 @@ class luabinding {
void _init_script(std::map<std::string, misc::variant> const& conf_params);
void _update_lua_path(std::string const& path);

unsigned _gc_broker_event_cpt;
time_t _gc_last_full_gc;

public:
luabinding(std::string const& lua_script,
std::map<std::string, misc::variant> const& conf_params,
Expand Down
47 changes: 46 additions & 1 deletion broker/lua/src/broker_event.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "com/centreon/broker/io/data.hh"
#include "com/centreon/broker/io/protobuf.hh"
#include "com/centreon/broker/mapping/entry.hh"
#include "com/centreon/broker/multiplexing/muxer.hh"
#include "com/centreon/exceptions/msg_fmt.hh"

using namespace com::centreon::broker;
Expand All @@ -32,6 +33,8 @@ static void _write_item(lua_State* L,
const google::protobuf::Message* p,
const google::protobuf::FieldDescriptor* f);

std::map<const lua_State*, broker_event::gc_info> broker_event::_gc_info;
std::mutex broker_event::_gc_info_m;

/**
* The Lua broker_event constructor
Expand All @@ -49,6 +52,32 @@ void broker_event::create(lua_State* L, std::shared_ptr<io::data> e) {

luaL_getmetatable(L, "broker_event");
lua_setmetatable(L, -2);
bool have_to_gc_collect = false;
{
std::lock_guard l(_gc_info_m);

/*In V2, lua stores only a userdata that contains a shared_ptr of event
* (16 bytes). So garbage collector don't see amount of memory used by
* events.
* So we need to call garbage collector ourselves to reduce memory
* consumption
* So we call at least gc every minute or
* at most every 10s if lua own more than
* com::centreon::broker::multiplexing::muxer::event_queue_max_size() events
* */
time_t now = time(nullptr);
gc_info& gc_inf = _gc_info[L];
if ((++gc_inf._broker_event_cpt > com::centreon::broker::multiplexing::
muxer::event_queue_max_size() &&
gc_inf._last_full_gc + 10 < now) ||
(gc_inf._last_full_gc + 60 < now)) {
gc_inf._last_full_gc = now;
have_to_gc_collect = true;
}
}
if (have_to_gc_collect) {
lua_gc(L, LUA_GCCOLLECT, 0);
}
}

static void _message_to_table(lua_State* L,
Expand Down Expand Up @@ -345,12 +374,18 @@ void broker_event::create_as_table(lua_State* L, const io::data& d) {
*
* @return 0
*/
static int l_broker_event_destructor(lua_State* L) {
int broker_event::l_broker_event_destructor(lua_State* L) {
void* ptr = luaL_checkudata(L, 1, "broker_event");

if (ptr) {
auto event = static_cast<std::shared_ptr<io::data>*>(ptr);
event->reset();
std::lock_guard l(_gc_info_m);

gc_info& gc_inf = _gc_info[L];
if (gc_inf._broker_event_cpt > 0) {
--gc_inf._broker_event_cpt;
}
}
return 0;
}
Expand Down Expand Up @@ -759,3 +794,13 @@ void broker_event::broker_event_reg(lua_State* L) {

lua_setglobal(L, name);
}

/**
* @brief when a lua_State is closed we clean _gc_info
*
* @param The Lua interpreter as a lua_State*
*/
void broker_event::lua_close(const lua_State* L) {
std::lock_guard l(_gc_info_m);
_gc_info.erase(L);
}
18 changes: 2 additions & 16 deletions broker/lua/src/luabinding.cc
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,7 @@ luabinding::luabinding(std::string const& lua_script,
_flush{false},
_cache(cache),
_total{0},
_broker_api_version{1},
_gc_broker_event_cpt(0),
_gc_last_full_gc(time(nullptr)) {
_broker_api_version{1} {
size_t pos(lua_script.find_last_of('/'));
std::string path(lua_script.substr(0, pos));
_L = _load_interpreter();
Expand Down Expand Up @@ -93,6 +91,7 @@ int32_t luabinding::stop() {
if (_L) {
retval = flush();
lua_close(_L);
broker_event::lua_close(_L);
_L = nullptr;
}
return retval;
Expand Down Expand Up @@ -398,19 +397,6 @@ int luabinding::write(std::shared_ptr<io::data> const& data) noexcept {
} break;
case 2:
broker_event::create(_L, data);
/*In V2, lua stores only a userdata that contains a shared_ptr of event
* (16 bytes). So garbage collector don't see amount of memory used by
* events.
* So we need to call garbage collector ourselves to reduce memory
* consumption */
time_t now = time(nullptr);
if ((++_gc_broker_event_cpt > 1000 && _gc_last_full_gc + 5 < now) ||
(_gc_last_full_gc + 30 < now)) {
_gc_broker_event_cpt = 0;
_gc_last_full_gc = now;
lua_gc(_L, LUA_GCCOLLECT, 0);
}

break;
}

Expand Down

0 comments on commit 3745e43

Please sign in to comment.