Ошибка при вызове sendTransaction из нескольких потоков

Страницы: 1
RSS
Ошибка при вызове sendTransaction из нескольких потоков
 
Если функцию sendTransaction вызвать одновременно из двух потоков - один вызов из main, а другой из функции обратного вызова, то на корректную транзакцию может прийти ответ с ошибкой "Неверный формат заявки".

Ниже приведён скрипт, воспроизводящий проблему. В нём нужно перед запуском заменить номер счёта в первой строке. Для появления ошибки может потребоваться несколько запусков скрипта.

В терминале версии 7.2.2.3 ошибки не было. В версиях 7.4, 7.5 и 7.6 ошибка есть.

Скрипт:
Скрытый текст
 
Добрый день,

Ваше сообщение получено, проблема изучается. Постараемся в ближайшее время дать ответ.
 
Очень хорошо, что у Вас получилось воспроизвести ошибку "Неверный формат заявки". У нас она тоже изредка появляется, хотя мы не отправляем заявки из разных потоков, но в терминале одновременно работает несколько скриптов, каждый из которых шлёт заявки из своего main-потока. Теперь разработчики, скорее всего, быстро найдут и устранят причину (скорее всего, баг синхронного доступа к общему ресурсу). По нашему обращению не получилось этого сделать.
 
SG,      Добрый день,
   
    Описанная в данном инциденте ошибка будет исправлена в одной из следующих версий программы.
    Приносим извинения за причиненные неудобства.
 
Цитата
SG написал:
Если функцию sendTransaction вызвать одновременно из двух потоков - один вызов из main, а другой из функции обратного вызова, то на корректную транзакцию может прийти ответ с ошибкой "Неверный формат заявки".

Ниже приведён скрипт, воспроизводящий проблему. В нём нужно перед запуском заменить номер счёта в первой строке. Для появления ошибки может потребоваться несколько запусков скрипта.

В терминале версии 7.2.2.3 ошибки не было. В версиях 7.4, 7.5 и 7.6 ошибка есть.

Скрипт:
    Скрытый текст      
Код
   local  accountName  =   "SPBFUT00000"    -- заменить на правильный номер счёта 
 local  classCode  =   "SPBFUT" 
 local  secCode  =   "SRZ6" 
 local  priceMin  =   nil 
 local  logFile  =   nil 
 local  running  =   true 
 local  testStarted  =   false 
 local  activeOrders  =  {}

 function   Log ( message )
    if  logFile ~ =   nil   then 
       local  timestamp  =   os.date ( "[%Y-%m-%d %X]" )
      logFile:write(timestamp  ..   " "   ..   message   ..   "\n" )
      logFile:flush()
    end 
 end 

 function   LogTable ( message , tbl)
    local  res  =  {}
    for  key, value  in  pairs(tbl)  do 
       local  vtype  =  type(value)
       if  vtype  =  =   "nil"   then 
         res[ # res  +   1 ]  =  key  ..   " = <nil>" 
       elseif  vtype  =  =   "number"   then 
         res[ # res  +   1 ]  =  key  ..   " = "   ..  value
       elseif  vtype  =  =   "string"   then 
         res[ # res  +   1 ]  =  key  ..   " = "   ..   string.format ( "%q" , value)
       else 
         res[ # res  +   1 ]  =  key  ..   " = ?" 
       end 
    end 
   Log( message   ..   table.concat (res,  "; " ))
 end    

 function   PlaceOrders (price, count, id)
    for  i  =   1 , count  do 
       local  transaction  =  {
         [ "ACTION" ]  =   "NEW_ORDER" ,
         [ "CLASSCODE" ]  =  classCode,
         [ "SECCODE" ]  =  secCode,
         [ "ACCOUNT" ]  =  accountName,
         [ "OPERATION" ]  =   "B" ,
         [ "PRICE" ]  =  tostring(price),
         [ "QUANTITY" ]  =   "1" ,
         [ "TRANS_ID" ]  =  tostring(id),
      }
      LogTable( "Placing order: " , transaction)
       local   message   =   sendTransaction (transaction)
      Log( "Result: "   ..  id  ..   ", ["   ..   message   ..   "]" )
      id  =  id  +   1 
    end    
 end 

 function   CancelOrders (id)
    for  ordernum, value  in  pairs(activeOrders)  do 
       local  transaction  =  {
         [ "ACTION" ]  =   "KILL_ORDER" ,
         [ "CLASSCODE" ]  =  classCode,
         [ "SECCODE" ]  =  secCode,
         [ "ORDER_KEY" ]  =  tostring(ordernum),
         [ "TRANS_ID" ]  =  tostring(id),
      }
      LogTable( "Cancelling order: " , transaction)
       local   message   =   sendTransaction (transaction)
      Log( "Result: "   ..  id  ..   ", ["   ..   message   ..   "]" )
      id  =  id  +   1 
    end 
 end 

 function   OnTransReply (transaction)
   LogTable( "OnTransReply: " , transaction)
    if   not  testStarted  then 
       -- этот код вызывается только один раз для старта теста 
      Log( "Starting test" )
      testStarted  =   true 
       -- ставим тестовые заявки 
      PlaceOrders(priceMin,  5 ,  3000 )
    end 
    if  transaction.status  =  =   3   then 
      activeOrders[transaction.order_num]  =   true 
    else 
       -- если попали сюда, значит произошла ошибка 
      Log( "ERROR: "   ..  transaction.result_msg)
    end 
 end 

 function   OnStop ()
   running  =   false 
 end 

 function   GetPriceMin ()
    local  param  =   getParamEx (classCode, secCode,  "pricemin" )
    if  param  =  =   nil   or  param.result ~ =   "1"   then 
       return   0 
    end 
    local  value  =  tonumber(param.param_value)
    if  value  =  =   nil   then 
       return   0 
    end 
   Log( "pricemin = "   ..  value)
    return  value
 end 

 function   OnInit (scriptName)
   logFile  =   io.open (scriptName  ..   ".log" ,  "at" )
 end 

 function   main ()
    -- получаем нижний лимит цены 
   priceMin  =  GetPriceMin()
    while  running  and  priceMin  =  =   0   do 
       sleep ( 100 )
      priceMin  =  GetPriceMin()
    end 

    -- отправляем первую заявку 
   PlaceOrders(priceMin,  1 ,  1000 )
   
    -- активное ожидание начала теста 
    while   not  testStarted  do 
    end 
   
    -- ставим тестовые заявки 
   PlaceOrders(priceMin,  5 ,  2000 )
    -- ждём исполнение всех транзакций 
    sleep ( 2000 )
   
    -- снимаем все заявки 
   CancelOrders( 4000 )
    -- ждём исполнение всех транзакций 
    sleep ( 2000 )
   
   logFile:close()
   logFile  =   nil 
 end 
  
    Добрый день,
   
    Описанная в данном инциденте проблема была устранена в версии 7.7.0     терминала QUIK.
    Рекомендуем Вам обновить версию программы.
   
    Приносим извинения за причиненные неудобства.
Страницы: 1
Читают тему
Наверх