QLua и БД

Страницы: 1
RSS
QLua и БД, QLua и БД
 
Есть проблема, с которой борюсь довольно давно, но к сожалению, так ее и не удалось решить, и похоже все дело именно в связке QUIK-QLua-Lua.
Я написал скрипт на Lua, который периодически записывает данные о параметрах опционов (волатильность и т.д.) в БД, чтобы в дальнейшем использовать данную информацию для сложных запросов. Для записи в БД пробовал пользоваться несколькими сторонними библиотеками: LuaSQL (https://keplerproject.github.io/luasql/) и LuaSQLite3 (http://lua.sqlite.org/index.cgi/index). При этом в случае LuaSQL пробовал реализацию для sqlite и mysql.
Сами библиотеки прикрутить к QUIK'у удалось, хотя это непросто. Но итоговый результат к сожалению печальный: скрипт работает определенное время, делает записи в БД, как надо, но потом QUIK просто падает (без дампа, без всего). Если записи в БД делать два раза в секунду, то падает через несколько минут. Если писать раз в минуту (как изначально мной предполагалось), то падает через полчаса, а может через пару часов. Мне нужна стабильная работа в течение всего дня. За одну итерацию пишу около сотен строк в БД, что полная ерунда для современных мощностей. Смотрел на использование ЦП QUIK'ом во время работы скрипта - все нормально. Пробовал запись как из потока main, так и из функций обратного вызова - результат один и тот же.
То, что один и тот же результат воспроизводится для различных библиотек и различных СУБД, говорит о том, что дело не в них, а в QUIK'е или QLua. Если записывать все нужные данные просто в файл csv, а не в БД, то все стабильно работает. По опыту могу сказать, что падение может быть вызвано ошибкой при одновременном доступе к одному участку памяти в QUIK'е или запил памяти, но так как у меня нет исходного кода ни qlua.dll, ни quik.exe, то я не могу ничего сказать и сделать. Неужели моя задача никак не решается с использованием QUIK? Хотелось бы получить ответ от разработчиков. Я могу дать код скрипта, если нужно. Пробовал на версиях QUIK 7.14 и 7.16.
 
Цитата
Сергей написал:
То, что один и тот же результат воспроизводится для различных библиотек и различных СУБД, говорит о том, что дело не в них, а в QUIK'е или QLua.
Цитата
Сергей написал:
Если записывать все нужные данные просто в файл csv, а не в БД, то все стабильно работает.
Первое утверждение противоречит второму. Косяк явно в коде работы с БД.

Попробуйте вынести весь свой скрипт в отдельный процесс через LuaRPC (найдите любую реализацию в сети, к примеру, есть готовая под QLua: quik-lua-rpc), и посмотрите, какой процесс у вас будет падать в итоге...
 
Цитата
Suntor написал:
Первое утверждение противоречит второму. Косяк явно в коде работы с БД.
Не вполне пойму, в чем противоречие. У меня в скрипте довольно тонкая прослойка к упомянутым третьесторонним библиотекам - открываю соединение, получаю данные из QUIK'а о нужных инструментах, делаю вызов INSERT, как в примере https://keplerproject.github.io/luasql/examples.html. У LuaSQLite3 другой API и обращение к другой dll - и падение то же самое повторяется. Если бы в моем скрипте была бы ошибка, то не работало бы вообще.




Цитата
Suntor написал:
Попробуйте вынести весь свой скрипт в отдельный процесс через LuaRPC (найдите любую реализацию в сети, к примеру, есть готовая под QLua: quik-lua-rpc), и посмотрите, какой процесс у вас будет падать в итоге...
Не очень знаком с технологиями "Protocol Buffers", "ZeroMQ", которые тут указаны. Я так понял смысл в том, что мой скрипт будет запущен обычным интерпретатором Lua и будет RPC-клиентом. Для получения данных из QUIK он будет делать RPC вызовы на скрипт (RPC-сервер) запущенный в это время в QUIK'е. Я правильно понимаю? В итоге получается, что "вынести в отдельный процесс" означает по сути "переписать всю программу" на этих неизвестных мне технологиях. Думаю легче сделать по другому: написать dll, которая сама будет делать inset'ы в базу, а lua-скрипт из QUIK'а просто будет давать dll'ке нужные данные.
 
Добрый день.
Проблема скорее всего в Вашем скрипте.
Использую LuaSQLite3. Читаю ТВС. Раз в полсекунды (уверен, можно и чаще) пишу новые сделки в таблицу. Далее транзакциями пишу в базу свежую порцию сделок... Итак уже полгода и по всем акциям и фьючам. База занимает 2 гига.
 
Цитата
Сергей написал:
Думаю легче сделать по другому: написать dll, которая сама будет делать inset'ы в базу,
еще проще это сделать свою структуру и писать ее lua-скриптом.

http://lua-users.org/wiki/StructurePacking

чем проще решение, тем оно стабильнее и более управляемо.
 
Цитата
Сергей написал:
Не вполне пойму, в чем противоречие.
Противоречие в том, что как вы сами пишите, когда ваш скрипт пишет в файл, то ничего не падает, а когда ваш скрипт пишет в БД, то падает. В обоих случаях Quik один и тот же, разница только в вашем коде работы с БД и в библиотеках работы с БД. Значит Quik отбрасываем. Остаются ваш код и библиотеки работы с БД. Но вы перепробовали их несколько, и падение повторилось в каждом случае. Значит их тоже отбрасываем. Остаётся только ваш код работы с БД... простой метод исключений, немного дедукции, и виновник найден... Элементарно! )))
Цитата
Сергей написал:
Не очень знаком с технологиями "Protocol Buffers", "ZeroMQ", которые тут указаны. Я так понял смысл в том, что мой скрипт будет запущен обычным интерпретатором Lua и будет RPC-клиентом.
Смысл в том, чтобы вынести ваш код работы с БД в другой процесс физически. И если там ошибка, то упадёт другой процесс, а Quik останется работать вместе с LuaRPC частью. И вы убедитесь, что валится именно процесс с вашим кодом... что там внутри той же  quik-lua-rpc вам знать не нужно, вам лишь нужно, чтобы ваш скрипт работал в другом процессе и делал вызовы в Quik через посредника.
 
Цитата
Suntor написал:
Смысл в том, чтобы вынести ваш код работы с БД в другой процесс физически. И если там ошибка, то упадёт другой процесс, а Quik останется работать вместе с LuaRPC частью. И вы убедитесь, что валится именно процесс с вашим кодом... что там внутри той же  quik-lua-rpc вам знать не нужно, вам лишь нужно, чтобы ваш скрипт работал в другом процессе и делал вызовы в Quik через посредника.
Поддерживаю!
Цитата
Сергей написал:
Если записи в БД делать два раза в секунду, то падает через несколько минут.
А память сжирается процессом квика за эти несколько минут?
 
Кажется, причина ясна.Дело оказалось вовсе не в БД, а в одновременном доступе к мапу из разных ниток.
В потоке main() делалось чтение из базы и загрузка данных из нее в глобальный мап типа { "SR" = {...}, "GZ" = {...}, "RI" = {} } (то есть таблица, где ключом является не индекс, а строки).
В функции обратного вызова делалось чтение из этого глобального мапа с использованием pairs(). Пока вторая нитка перебирала элементы, первая как раз в этот же момент изменила мап, и все упало.
Я конечно знаю про потокобезопасные функции table.sinsert и т.д., но они только для нумерованных таблиц.
Так что придется использовать что-то типа эмуляции критической секции, как описано здесь https://forum.quik.ru/forum10/topic3272/ или поменять структуру данных. Сделать все в один поток не получится, потому что скрипт сложный и большой и он не только занимается работой с базой.
 
Все же лучше смотреть в сторону отдельного процесса. Я сделал так: lua-скрипт в OnAllTrade вызывает ф-ю dll для передачи нужных параметров (практически - всех) строки таблицы всех сделок. Длл-ка в свою очередь при инициализации подключена к именованному пайп-серверу (почему-то пайпы выбрал, а не tcp/ip). А вот пайп-сервер - уже отдельно запущенное приложение со своими потоками - принимает от пайп-клиента данные, сохраняет/обрабатывает/отправляет ответ клиенту (т.е. в  длл). Если длл получает ответ - вызывает коллбэк уже в квике. Работает стабильно.
 
Продолжил работать над задачей описанной в начале темы. Поместил методы записи в базу в отдельную dll (таким образом почти полностью переписал функционал с lua на c++), к сожалению проблема осталось той же: QUIK падает через некоторое время работы. Зато теперь падает с дампом. Уважаемая тех. поддержка, куда мне нужно направить файл дампа, чтобы кто-нибудь мог посмотреть возможную причину? Так как pdb у меня нет, то символы из дампа я загрузить не могу, вижу только ошибку "Access violation reading location xxxx".
 
Добрый день.
Пришлите дамп падения на quiksupport@arqatech.com вместе со скриптом и библиотеками.
Страницы: 1
Читают тему (гостей: 1)
Наверх