Название: Расширение с использованием модуля на Lua C API Отправлено: zed от 26 января 2017, 22:54:33 Для одного расширения пишу свой модуль (.dll) на Lua C API и столкнулся с глобальным неудобством.
Сейчас логика такая (поправьте, если сильно ошибаюсь): 1. При старте HC создаёт Lua-машину, инициализирует расширение (выполняет событие Init), уничтожает Lua-машину (что приводит к выгрузке из памяти подключаемого модуля). 2. При поступлении http-запроса, на каждый запрос создаётся новая машина (выполняется загрузка модуля), выполняется скрипт и уничтожается машина, с выгрузкой модуля. Если расширение обрабатывает несколько запросов одновременно, то загрузка модуля происходит при поступлении первого запроса, а выгрузка - после отработки последнего. 3. При закрытии HC опять создаёт машину, выполняет событие Destroy и удаляет машину в последний раз. Так вот, хотелось бы, чтобы машина созданная в п.1 не уничтожалась до конца работы HC и использовалась в п.3 и только там удалялась. Так же, желательно чтобы машины создаваемые в п.2 кэшировались и не умирали сразу же при закрытии запроса. Внутри модуля мне нужно хранить некий глобальный объект, который может использоваться из расширения и выполнять полезную работу, но постоянная выгрузка модуля из памяти сводит всё на нет. Название: Re: Расширение с использованием модуля на Lua C API Отправлено: zed от 29 января 2017, 12:32:01 И ещё, при создании Lua-машин нужно добавлять путь до папки с расширением в package.path и в package.сpath, чтобы расширение могло загружать модули (как .dll, так и .lua) из своей папки. В path надо добавлять путь вида %ExtensionPath%\?.lua, а в cpath вида %ExtensionPath%\?.dll. Пути добавляются через точку с запятой.
Пример кода добавления пути в path (взято тут (http://stackoverflow.com/a/4156038/6219657)): Код: ("C++") int setLuaPath( lua_State* L, const char* path ) Сейчас же в скрипте приходится делать лишние проверки и перед загрузкой модулей инициализировать эти пути руками: Код: ("Lua") local script_path = string.match(hc.script_name, [[.*\]]) Название: Re: Расширение с использованием модуля на Lua C API Отправлено: mai62 от 29 января 2017, 13:06:32 Цитировать Так вот, хотелось бы, чтобы машина созданная в п.1 не уничтожалась до конца работы HC и использовалась в п.3 и только там удалялась. Так же, желательно чтобы машины создаваемые в п.2 кэшировались и не умирали сразу же при закрытии запроса. Это не возможно. НС может работать одновременно с сотнями запросов. Если каждое расширение будет работать только в одной Lua-машине, то придется все запросы ставить в очередь и обрабатывать одной машиной. Более того. Обработка запроса - не одномоментная акция. Данные по многим запросам поступают частями, таких частей может быть сотни или тысячи штук. Все они станут в очередь к единственной машине. Вы представляете какие будут пробки?Название: Re: Расширение с использованием модуля на Lua C API Отправлено: zed от 29 января 2017, 13:08:34 Вы меня не так поняли. Я не предлагаю использовать всего одну машину. Я предлагаю использовать пул машин и не уничтожать по крайней мере одну, последнюю машину, после того, как все запросы отработают.
Название: Re: Расширение с использованием модуля на Lua C API Отправлено: zed от 29 января 2017, 14:30:01 Пул Lua-машин может сильно ускорить работу расширений вообще, абстрагируясь от моего случая. Точно так же, как пул потоков позволяет ускорить обработку входящих tcp-соединений.
Но, конкретно в моём случае, вопрос даже не в пуле (хотя он сам по себе важен), а в том, чтобы держать в памяти одну Lua машину (для расширения) на протяжении всей жизни HC. Мне даже не нужно, чтобы через эту конкретную машину ходили запросы и вызывались какие-то события. Важен сам факт того, что она загружена в память. Если я правильно понимаю, события Init(), Destroy(), Options(), Timer1s(), Timer1m() вызываются из главного потока программы. И для каждого события создаётся/уничтожается своя машина. Так вот, требуется лишь чуть-чуть исправить логику программы, чтобы созданную машину для вызова события Init() не уничтожать тут же, а сохранить и использовать для всех остальных событий (Destroy(), Options(), Timer1s(), Timer1m()). Уничтожать эту машину можно после обработки события Destroy(). Для всех остальных событий (RequestHeaderReceived() и т.д.), которые обрабатываются в потоках входящих соединений, нужно создавать и использовать другие машины, т.е. тут ничего менять не нужно, если нет желания делать пул Lua машин.
Powered by SMF 1.1.3 SMF © 2006, Simple Machines LLC
Joomla Bridge by JoomlaHacks.com |