+  HandyCache форум
|-+  Главная категория» Новые предложения» Расширение с использованием модуля на Lua C API
Имя пользователя:
Пароль:
Страниц: [1]   Вниз
  Отправить эту тему    Печать  
Автор Тема: Расширение с использованием модуля на Lua C API  (Прочитано 2835 раз)
0 Пользователей и 1 Гость смотрят эту тему.
zed
Постоялец
***

Репутация: +4/-0
Offline Offline

Сообщений: 141


« : 26 января 2017, 22:54:33 »

Для одного расширения пишу свой модуль (.dll) на Lua C API и столкнулся с глобальным неудобством.

Сейчас логика такая (поправьте, если сильно ошибаюсь):
1. При старте HC создаёт Lua-машину, инициализирует расширение (выполняет событие Init), уничтожает Lua-машину (что приводит к выгрузке из памяти подключаемого модуля).
2. При поступлении http-запроса, на каждый запрос создаётся новая машина (выполняется загрузка модуля), выполняется скрипт и уничтожается машина, с выгрузкой модуля. Если расширение обрабатывает несколько запросов одновременно, то загрузка модуля происходит при поступлении первого запроса, а выгрузка - после отработки последнего.
3. При закрытии HC опять создаёт машину, выполняет событие Destroy и удаляет машину в последний раз.

Так вот, хотелось бы, чтобы машина созданная в п.1 не уничтожалась до конца работы HC и использовалась в п.3 и только там удалялась. Так же, желательно чтобы машины создаваемые в п.2 кэшировались и не умирали сразу же при закрытии запроса.

Внутри модуля мне нужно хранить некий глобальный объект, который может использоваться из расширения и выполнять полезную работу, но постоянная выгрузка модуля из памяти сводит всё на нет.
Сообщить модератору   Записан
zed
Постоялец
***

Репутация: +4/-0
Offline Offline

Сообщений: 141


« Ответ #1 : 29 января 2017, 12:32:01 »

И ещё, при создании Lua-машин нужно добавлять путь до папки с расширением в package.path и в package.сpath, чтобы расширение могло загружать модули (как .dll, так и .lua) из своей папки. В path надо добавлять путь вида %ExtensionPath%\?.lua, а в cpath вида %ExtensionPath%\?.dll. Пути добавляются через точку с запятой.

Пример кода добавления пути в path (взято тут):
Код: ("C++")
int setLuaPath( lua_State* L, const char* path )
{
    lua_getglobal( L, "package" );
    lua_getfield( L, -1, "path" ); // get field "path" from table at top of stack (-1)
    std::string cur_path = lua_tostring( L, -1 ); // grab path string from top of stack
    cur_path.append( ";" ); // do your path magic here
    cur_path.append( path );
    lua_pop( L, 1 ); // get rid of the string on the stack we just pushed on line 5
    lua_pushstring( L, cur_path.c_str() ); // push the new one
    lua_setfield( L, -2, "path" ); // set the field "path" in table at -2 with value at top of stack
    lua_pop( L, 1 ); // get rid of package table from top of stack
    return 0; // all done!
}
Аналогично путь добавляется и в cpath.

Сейчас же в скрипте приходится делать лишние проверки и перед загрузкой модулей инициализировать эти пути руками:
Код: ("Lua")
local script_path = string.match(hc.script_name, [[.*\]])

local lua_path = script_path .. '?.lua'
if not string.find(package.path, lua_path) then
  package.path = package.path .. ';' .. lua_path
end

local c_path = script_path .. '?.dll'
if not string.find(package.cpath, c_path) then
  package.cpath = package.cpath .. ';' .. c_path
end
Сообщить модератору   Записан
mai62
Автор HC
*****

Репутация: +226/-4
Offline Offline

Сообщений: 6383


« Ответ #2 : 29 января 2017, 13:06:32 »

Цитировать
Так вот, хотелось бы, чтобы машина созданная в п.1 не уничтожалась до конца работы HC и использовалась в п.3 и только там удалялась. Так же, желательно чтобы машины создаваемые в п.2 кэшировались и не умирали сразу же при закрытии запроса.
Это не возможно. НС может работать одновременно с сотнями запросов. Если каждое расширение будет работать только в одной Lua-машине, то придется все запросы ставить в очередь и обрабатывать одной машиной. Более того. Обработка запроса - не одномоментная акция. Данные по многим запросам поступают частями, таких частей может быть сотни или тысячи штук. Все они станут в очередь к единственной машине. Вы представляете какие будут пробки?
Сообщить модератору   Записан
zed
Постоялец
***

Репутация: +4/-0
Offline Offline

Сообщений: 141


« Ответ #3 : 29 января 2017, 13:08:34 »

Вы меня не так поняли. Я не предлагаю использовать всего одну машину. Я предлагаю использовать пул машин и не уничтожать по крайней мере одну, последнюю машину, после того, как все запросы отработают.
Сообщить модератору   Записан
zed
Постоялец
***

Репутация: +4/-0
Offline Offline

Сообщений: 141


« Ответ #4 : 29 января 2017, 14:30:01 »

Пул Lua-машин может сильно ускорить работу расширений вообще, абстрагируясь от моего случая. Точно так же, как пул потоков позволяет ускорить обработку входящих tcp-соединений.

Но, конкретно в моём случае, вопрос даже не в пуле (хотя он сам по себе важен), а в том, чтобы держать в памяти одну Lua машину (для расширения) на протяжении всей жизни HC. Мне даже не нужно, чтобы через эту конкретную машину ходили запросы и вызывались какие-то события. Важен сам факт того, что она загружена в память.

Если я правильно понимаю, события Init(), Destroy(), Options(), Timer1s(), Timer1m() вызываются из главного потока программы. И для каждого события создаётся/уничтожается своя машина. Так вот, требуется лишь чуть-чуть исправить логику программы, чтобы созданную машину для вызова события Init() не уничтожать тут же, а сохранить и использовать для всех остальных событий (Destroy(), Options(), Timer1s(), Timer1m()). Уничтожать эту машину можно после обработки события Destroy(). Для всех остальных событий (RequestHeaderReceived() и т.д.), которые обрабатываются в потоках входящих соединений, нужно создавать и использовать другие машины, т.е. тут ничего менять не нужно, если нет желания делать пул Lua машин.

Сообщить модератору   Записан
Страниц: [1]   Вверх
  Отправить эту тему    Печать  

 
Перейти в: