Заказываю тики через CreateDataSource:SetUpdateCallback().
Запускаю Квик: -Загружаю скрипт. -Запускаю скрипт. -Скрипт вызывает CreateDataSource. -CreateDataSource возвращает нулевую таблицу, что говорит о том, что данные придут позже в колбек. -Колбек больше НИКОГДА не вызывается.
Выгружаю Скрипт и СРАЗУ же его запускаю - данные сразу же начинают приходить.
Quikos написал: Кто встречался с такой ситуацией ?
Заказываю тики через CreateDataSource:SetUpdateCallback().
Запускаю Квик: -Загружаю скрипт. -Запускаю скрипт. -Скрипт вызывает CreateDataSource. -CreateDataSource возвращает нулевую таблицу, что говорит о том, что данные придут позже в колбек. -Колбек больше НИКОГДА не вызывается.
Выгружаю Скрипт и СРАЗУ же его запускаю - данные сразу же начинают приходить.
Кто косячит ? Я или криворукие разрабы ?
Скрипт запускаете руками или автоматом с запуском квика? Если автоматом, то в скрипте надо делать ожидание. ---------------- Проще, если вам нужны тики, то просто подпишитесь на них через меню и они будут приходить при старте квика без проблем.
nikolz написал: Скрипт запускаете руками или автоматом с запуском квика? Если автоматом, то в скрипте надо делать ожидание. ---------------- Проще, если вам нужны тики, то просто подпишитесь на них через меню и они будут приходить при старте квика без проблем.
Скрипт запускается полностью вручную.
Это хорошо, что можно подписаться через меню. Но это явный косяк в API.
nikolz написал: Скрипт запускаете руками или автоматом с запуском квика? Если автоматом, то в скрипте надо делать ожидание. ---------------- Проще, если вам нужны тики, то просто подпишитесь на них через меню и они будут приходить при старте квика без проблем.
Скрипт запускается полностью вручную.
Это хорошо, что можно подписаться через меню. Но это явный косяк в API.
nikolz написал: Скрипт запускаете руками или автоматом с запуском квика? Если автоматом, то в скрипте надо делать ожидание. ---------------- Проще, если вам нужны тики, то просто подпишитесь на них через меню и они будут приходить при старте квика без проблем.
Скрипт запускается полностью вручную.
Это хорошо, что можно подписаться через меню. Но это явный косяк в API.
чтобы понять причину надо смотреть ваш скрипт.
Скрипт простейший:
Код
function my_callback_CreateDataSource(my_table_data_, code_class_, code_paper_, interval_, cntr)
message(code_paper_)
end
-----------------------------------------------------------------------------------------------------------int main:-----------------------------------------------------------------------------------------------------
function main()
local code_class1 = "TQBR"
local code_paper1 = "GAZP"
local interval1 = INTERVAL_TICK
local code_class2 = "TQBR"
local code_paper2 = "SBER"
local interval2 = INTERVAL_TICK
local my_table1, error_desc1 = CreateDataSource(code_class1, code_paper1, interval1) --Вызываем собсвенно CreateDataSource
------------------------Проверка на ошибки:-------------------
if error_desc1 ~= nil then
message("Error")
end
--------------------------------------------------------------
message(tostring(my_table1.Size()))
if my_table1.Size() == 0 then
message("data requested from the server")
end
local my_table2, error_desc2 = CreateDataSource(code_class2, code_paper2, interval2) --Вызываем собсвенно CreateDataSource
------------------------Проверка на ошибки:-------------------
if error_desc2 ~= nil then
message("Error")
end
--------------------------------------------------------------
message(tostring(my_table2.Size()))
if my_table2.Size() == 0 then
message("data requested from the server")
end
my_table1:SetUpdateCallback(function(idx)my_callback_CreateDataSource(my_table_data1, code_class1, code_paper1, interval1) end)
my_table2:SetUpdateCallback(function(idx)my_callback_CreateDataSource(my_table_data2, code_class2, code_paper2, interval2) end)
-------------------------
while not stopped do
sleep(1)
end
-------------------------
end -- end main()
И если бы была ошибка в скрипте - то на второй раз запуска скрипта, колбек так же бы не вызывался, НО на второй раз все рабоатет, как и ожидается. Но только на второй раз.
Переписал Ваш скрипт , но действительно, если таблица обезличенных сделок не открыта, то руками запускается со второго раза, а автоматом - с первого. Очевидно это какая-то особенность или ошибка библиотеки QLUA.
Код
local code_class1 = "TQBR"
local code_paper1 = "GAZP"
local interval1 = INTERVAL_TICK
local code_class2 = "TQBR"
local code_paper2 = "SBER"
local interval2 = INTERVAL_TICK
------------------------
local function my_cb_CDS(idx,tabl)
message(tostring(tabl.sec)..","..tostring(idx),1)
Sleep(100);
end
--------int main:---------------
function main()
if tab1==nil then tab1 = CreateDataSource(code_class1, code_paper1, interval1);
if tab1 then
tab1.clas=code_class1; tab1.sec=code_paper1; tab1.int=interval1;
tab1:SetUpdateCallback(function(idx) my_cb_CDS(idx,tab1) end)
end
end
if tab2==nil then tab2= CreateDataSource(code_class2, code_paper2, interval2);
if tab2 then
tab2.clas=code_class2; tab2.sec=code_paper2; tab2.int=interval2;
tab2:SetUpdateCallback( function(idx) my_cb_CDS(idx, tab2) end)
end
end
-------------------------
while not stopped do
-- message(tostring(my_table1:Size()),1)
sleep(1000)
end
-------------------------
end -- end main()
function OnInit(script_path)
end
local code_class1 = "TQBR"
local code_paper1 = "GAZP"
local interval1 = INTERVAL_TICK
local code_class2 = "TQBR"
local code_paper2 = "SBER"
local interval2 = INTERVAL_TICK
------------------------
local function my_cb_CDS(idx,tabl)
message(tostring(tabl.sec)..","..tostring(idx),1)
Sleep(100);
end
-----------------------------------------------------------------------------------------------------------int main:-----------------------------------------------------------------------------------------------------
function main()
while not stopped do
if tab1==nil then tab1 = CreateDataSource(code_class1, code_paper1, interval1);
if tab1 then
tab1.clas=code_class1; tab1.sec=code_paper1; tab1.int=interval1;
tab1:SetUpdateCallback(function(idx) my_cb_CDS(idx,tab1) end)
end
end
if tab2==nil then tab2= CreateDataSource(code_class2, code_paper2, interval2);
if tab2 then
tab2.clas=code_class2; tab2.sec=code_paper2; tab2.int=interval2;
tab2:SetUpdateCallback( function(idx) my_cb_CDS(idx, tab2) end)
end
end
-------------------------
-- message(tostring(my_table1:Size()),1)
sleep(1000)
end
-------------------------
end -- end main()
function OnInit(script_path)
end
nikolz написал: Переписал Ваш скрипт , но действительно, если таблица обезличенных сделок не открыта, то руками запускается со второго раза, а автоматом - с первого. Очевидно это какая-то особенность или ошибка библиотеки QLUA.
Причем для некоторых акций - запускается с первого раза, а для некоторых со второго. Навряд ли такое поведение можно называть "особенностью" - это явный косяк.
Ну еще счетчик циклов для повторной попытки загрузки
Не лучшее решение, оно блокирует исполнение кода. Запросы где время ответа неизвестно, лучше решать через очереди задач ожидания. Потоков в lua нет, но, как минимум, не блокировать весь код. Если, например, скрипт обрабатывает много инструментов и потоков данных, то ждать после каждого заказа - много времени пройдет пока до последнего дойдет. Или надо что-то другое постоянно контролировать, пока по другому инструменту заказ сделали. То что долго идет ответ - это не повод для уже работающих инструментов ждать.
Quikos написал: Я правильно понял, что нужно дождаться пока появится таблица заполнится и только потом вызвать SetUpdateCallback ?
я в настоящее время не использую тики, Но для таблице обезличенных сделок (тиков) я сделал DDE клиента который стартует всегда при загрузки квика и позволяет получать в фоновом режиме любые таблицы квика , например доску опционов, или таблицу обезличенных сделок. -------------- еще использовал колбек onAllTrade , тоже работает нормально.
Nikolay написал: Не лучшее решение, оно блокирует исполнение кода. Запросы где время ответа неизвестно, лучше решать через очереди задач ожидания. Потоков в lua нет, но, как минимум, не блокировать весь код. Если, например, скрипт обрабатывает много инструментов и потоков данных, то ждать после каждого заказа - много времени пройдет пока до последнего дойдет. Или надо что-то другое постоянно контролировать, пока по другому инструменту заказ сделали. То что долго идет ответ - это не повод для уже работающих инструментов ждать.
Не от хорошей жизни, данные не всегда успевают. Поскольку, как вы заметили, потоков в луа нет, пришлось на каждый инструмент(тикер) сделать по скрипту. Ну а в отдельном скрипте без базы никаких задач нет. К стати, пока ни при какой нагрузке ожидание начала загрузки больше секунды-двух не встретил, а базы подгружается в основном либо при запуске, либо на открытии сессии. Как и повода жаловаться на SetUpdateCallback. Хотя в основном как колбэк используется OnAllTrade, база больше для расчетов.
Nikolay написал: Не лучшее решение, оно блокирует исполнение кода. Запросы где время ответа неизвестно, лучше решать через очереди задач ожидания. Потоков в lua нет, но, как минимум, не блокировать весь код. Если, например, скрипт обрабатывает много инструментов и потоков данных, то ждать после каждого заказа - много времени пройдет пока до последнего дойдет. Или надо что-то другое постоянно контролировать, пока по другому инструменту заказ сделали. То что долго идет ответ - это не повод для уже работающих инструментов ждать.
Не от хорошей жизни, данные не всегда успевают. Поскольку, как вы заметили, потоков в луа нет, пришлось на каждый инструмент(тикер) сделать по скрипту. Ну а в отдельном скрипте без базы никаких задач нет. К стати, пока ни при какой нагрузке ожидание начала загрузки больше секунды-двух не встретил, а базы подгружается в основном либо при запуске, либо на открытии сессии. Как и повода жаловаться на SetUpdateCallback. Хотя в основном как колбэк используется OnAllTrade, база больше для расчетов.
В квике можно создавать сколько угодно потоков При этом надо использовать общий глобальный стек. В нем решены проблемы синхронизации для main и для любых других. ---------------- я приводил пример с пулом потоков Использовал его для обработки колбеков по 200 инструментов. в итоге максимальное количество потоков которые были открыты пулом составило 12. Никаких проблем с синхронизацией не было.
Kolossi написал: Как и повода жаловаться на SetUpdateCallback.
Хотите сказать - у Вас описываемого мной косяка разрабов не наблюдается ?
Нет не наблюдается. Просто может быть потому что я сразу подстраховался и забил. Жалко времени на это тратить. Реальная функция из скрипта, была написана на ранних версиях квика и с тех пор не трогалась:
Код
function GetDS(p) -- функция закачки данных
local error_desc=""
if p==1 then -- дневные
...
elseif p==2 then -- тиковые
dsa,error_desc=CreateDataSource(p_classcode, trw.p_seccode, INTERVAL_TICK)
while not dsa or dsa:Size()==0 do
local n=100
while n>0 do
sleep(100)
if dsa and dsa:Size()>0 then break end
n=n-1
end
if not dsa or dsa:Size()==0 then
dsa,error_desc=CreateDataSource(p_classcode, trw.p_seccode, INTERVAL_TICK) -- повтор
end
if error_desc~=nil and error_desc~="" then
message("TICK, "..p_classcode.."/"..trw.p_seccode.."/".."Source2 error==>" .. error_desc)
return 0
end
end
dsa:SetEmptyCallback()
return dsa:Size()
else
return 0
end
end
Полагаю счетчик и повтор решили возможную проблему.
nikolz написал: В квике можно создавать сколько угодно потоков При этом надо использовать общий глобальный стек. В нем решены проблемы синхронизации для main и для любых других. ---------------- я приводил пример с пулом потоков Использовал его для обработки колбеков по 200 инструментов. в итоге максимальное количество потоков которые были открыты пулом составило 12. Никаких проблем с синхронизацией не было.
Спасибо, посмотрю. Однако сейчас уже это не совсем актуально поскольку каждый скрипт и есть отдельный поток, а переменные между скриптами можно передавать через общее пространство переменных. Жаль только что нет возможности запускать дерево скриптов.
local code_class1 = "TQBR"
local code_paper1 = "GAZP"
local interval1 = INTERVAL_TICK
local code_class2 = "TQBR"
local code_paper2 = "SBER"
local interval2 = INTERVAL_TICK
------------------------
local function my_cb_CDS (idx,tabl)
message (tostring(tabl.sec) .. "," .. tostring(idx), 1 )
Sleep( 100 );
end
-----------------------------------------------------------------------------------------------------------int main:-----------------------------------------------------------------------------------------------------
function main ()
while not stopped do
if tab1 = = nil then tab1 = CreateDataSource (code_class1, code_paper1, interval1);
if tab1 then
tab1.clas = code_class1; tab1.sec = code_paper1; tab1.int = interval1;
tab1: SetUpdateCallback ( function (idx) my_cb_CDS(idx,tab1) end )
end
end
if tab2 = = nil then tab2 = CreateDataSource (code_class2, code_paper2, interval2);
if tab2 then
tab2.clas = code_class2; tab2.sec = code_paper2; tab2.int = interval2;
tab2: SetUpdateCallback ( function (idx) my_cb_CDS(idx, tab2) end )
end
end
-------------------------
-- message(tostring(my_table1:Size()),1)
sleep ( 1000 )
end
-------------------------
end -- end main()
function OnInit (script_path)
end
Данный код так же Не работает с Первого раза, ТОЛЬКО со Второго раза.
Kolossi написал: Как и повода жаловаться на SetUpdateCallback.
Хотите сказать - у Вас описываемого мной косяка разрабов не наблюдается ?
Нет не наблюдается. Просто может быть потому что я сразу подстраховался и забил. Жалко времени на это тратить. Реальная функция из скрипта, была написана на ранних версиях квика и с тех пор не трогалась: Полагаю счетчик и повтор решили возможную проблему.
С вероятностью 99,9% - Вы просто ее не замечаете, так как она наблюдается именно сразу после запуска Квика и после Первого запуска скрипта, на второй, третий и последующий разы - данная пробелма не наблюдается до тех пор пока Вы не перезапустите Квик заново.
При этом разработчики - собаки сутулые - в течении годов ничего с этим не делают.