Comments (13)
Вот этот парсер выглядит поновее и понадёжнее: https://github.com/starwing/lua-protobuf
есть ли планы по его внедрению?
from quik-lua-rpc.
Довольно странная ошибка, если учесть, что в getItem.proto
это поле имеет тип int32
:
// version: 1.0
syntax = "proto3";
package qlua.rpc.getItem;
option optimize_for = SPEED;
option java_package = "qlua.rpc";
message Request {
string table_name = 1;
int32 index = 2;
}
message Result {
map<string, string> table_row = 1;
}
Выложите, пожалуйста, свои версии файлов getItem.proto
и getItem_pb.lua
-- может быть, у нас с Вами как-то по-разному они обработались.
Ещё есть предположение, что это глючит энкодер на стороне Java, но если при смене типа в .proto
начинает работать, то теория шаткая. Я ещё проверю в своём клиенте сегодня эти вызовы.
Насчёт парсера: согласен, по сравнению с тем, на который Вы дали ссылку, используемый сейчас выглядит как поделка школьника. Мне и самому приходилось допиливать его напильником: оригинальный проект уже не поддерживается, а пофиксенные баги и новые фичи разбросаны по куче форков (часто тоже не первой свежести).
Посмотрю на досуге, спасибо!
from quik-lua-rpc.
getItem_pb.lua
Вот интересующий нас кусок. По типам всё честно, 32 битный нефиксированный int
module.REQUEST_INDEX_FIELD.name = 'index'
module.REQUEST_INDEX_FIELD.full_name = '.qlua.rpc.getItem.Request.index'
module.REQUEST_INDEX_FIELD.number = 2
module.REQUEST_INDEX_FIELD.index = 1
module.REQUEST_INDEX_FIELD.label = 1
module.REQUEST_INDEX_FIELD.has_default_value = false
module.REQUEST_INDEX_FIELD.default_value = 0
module.REQUEST_INDEX_FIELD.type = 5
module.REQUEST_INDEX_FIELD.cpp_type = 1
Энкодер в java оптимизировал размер структуры. когда числа вмешается в знаковый байт - он пишет один байт. Если шире - то уже два байта. Вот hexdump
структур, что я отправил в lua
:
$ hexdump -C firms128.dat
00000000 0a 05 66 69 72 6d 73 10 fd 01 |..firms...|
0000000a
$ hexdump -C firms127.dat
00000000 0a 05 66 69 72 6d 73 10 7f |..firms..|
00000009
В первом случае делал запрос к таблице firms
с индексом 128 (тогда и возникла ошибка). и во втором случае 127 (всё отработало корректно). Структуры отличаются на один байт. Изменение параметров в proto
файле (optimized_for
) не помогло.
from quik-lua-rpc.
Да, проблему подтверждаю.
Буду разбираться.
Пока что инспекция привела к тому, что при значении index = 128
protobuf-lua в файле init.lua
по какой-то причине не находит декодера для тега поля и пытается его скипнуть (строки 669-672). По какой-то (той же?) причине скиппер выбирается неверный: вместо _SkipVarint
используется _SkipFixed32
(код определения скиппера -- в файле decoder.lua
, функция _FieldSkipper()
). Я грешу на эту конструкцию:
local ord = string.byte
local sub = string.sub
...
local wire_type = ord(sub(tag_bytes, 1, 1)) % 8 + 1
Судя по документации Lua, string.byte
в разных локалях может давать разные результаты.
Пока что думаю всё же повозиться с фиксами в protobuf-lua, т.к. оно будет быстрее, чем переписывать всё на новый биндинг, но в итоге это надо будет сделать, а то не радует меня, сколько нам открытий чудных готовит protobuf-lua.
P.S.
Ещё мне что-то совсем не понравилась молчанка со стороны скрипта на сервере -- выплюнул ошибку в консоль и всё, а клиент при этом висит, не получив ответ. Тоже исправлю.
from quik-lua-rpc.
Ещё, судя по документации к Protocol Buffers (https://developers.google.com/protocol-buffers/docs/encoding#varints), можно сделать вывод, что у Вас protobuf на стороне клиента неверно кодирует число 128 в varint (либо Вы ошиблись, когда сохраняли байтовый вывод в файл). Либо я что-то не понял :)
$ hexdump -C firms128.dat
00000000 0a 05 66 69 72 6d 73 10 **fd 01** |..firms...|
0000000a
,где fd 01
по технике декодирования превращается в 253
.
Должно быть что-то типа
$ hexdump -C firms128.dat
00000000 0a 05 66 69 72 6d 73 10 **80 01** |..firms...|
0000000a
, где 80 01
по технике декодирования превращается в 128
.
Для достоверности можно проверить тут: https://protogen.marcgravell.com/decode
У меня в клиенте на Java запрос с параметрами "firms", 128
в hex выглядит примерно так:
ByteString: 000000000000000000000a056669726d73108001
. Но, конечно, один фиг, баг с декодером проявляется.
from quik-lua-rpc.
Проблемы появляются уже на этапе доставания байтов из ZeroMQ (скрипт service.lua
, строка 39).
С index = 127
из ret:data()
приходит 0A-05-66-69-72-6D-73-10-7F
, в то время как с index = 128
приходит не совсем понятное 0A-05-66-69-72-6D-73-10-EF-BF-BD-01
.
from quik-lua-rpc.
Проблема оказалась в коде самого Java-клиента:
в классе com.enfernuz.quik.lua.rpc.api.zmq.impl.ZmqTcpRpcGatewayImpl
в методе makeRequest
байтовый массив запроса преобразовывался в UTF8-строку. Мне почему-то показалось, что единственный способ создать экземпляр ZMsg
-- это вызвать ZMsg.newStringMsg(String... strings)
. Но, оказывается, можно создать new ZMsg()
и передать туда байтовый массив уже после.
Поправил код в репозитории Java-клиента -- теперь должно работать.
from quik-lua-rpc.
Да, всё полечилось. Спасибо. По пути ещё одну багу нашёл - если в терминале quik выставлен русский язык интерфейса, то при некорректном запросе в ответе содержится текст с русскими буквами. И это ломает декодер на стороне java, например в SendTransaction.Result.parseFrom(resultAsByteString);
. Но это уже мелочи
from quik-lua-rpc.
С этими кодировками вообще там беда. На моей системе с локалью Russian (Russia) QLua выдаёт текст в кодировке CP1251. Если ничего не делать, то на стороне Java то ли не удаётся это распарсить вообще (protobuf пишет про not valid UTF8 string), то ли кракозябры выводятся (точно уже не помню). В итоге я на стороне сервиса весь текст перевожу костылём в UTF8.
Возможно, где-то не углядел и не перевёл. Посмотрю.
Если QLua выдаёт текст в зависимости от системной локали, то дела будут плохи, конечно, т.к. надо будет всё переписывать.
from quik-lua-rpc.
Перекодировал сообщение об ошибке в UTF8 в коммите 567b909.
from quik-lua-rpc.
Играюсь сейчас с lua-protobuf
. Он, конечно, в целом, почище, чем protobuf-lua
, но тоже не без "подарков".
Например, кодирую в Java RPC-запрос к getOrderByNumber
:
string: class_code = "SPBFUT",
int64: order_number = 30745970930
Java hex sent: 0a0653504246555410f291e9c472
Lua hex received: 0a0653504246555410f291e9c472
Lua decoded struct:
{
class_code = "SPBFUT",
order_id = 681199858
}
Проставление типов uint64
, fixed64
к order_num
не помогло. Более мелкие числа обрабатываются нормально.
Онлайн-декодер на https://protogen.marcgravell.com/decode парсит корректно.
Примечательно, что тестовый пример с https://github.com/starwing/lua-protobuf на Lua 5.1
вместо данных phonenumber
выдаёт отрицательные числа. Если запускать на Lua 5.3
, то всё нормально.
Оставил репорт: starwing/lua-protobuf#58
from quik-lua-rpc.
Проблему вроде как решил. Буду продолжать внедрять lua-protobuf
.
from quik-lua-rpc.
Переход на lua-protobuf
в качестве Lua-обёртки для protobuf осуществлён.
from quik-lua-rpc.
Related Issues (20)
- Сломана обработка сделок в Quik 8.8.4 HOT 5
- assert error в protobuf_request_response_serde.lua:46 HOT 2
- Падает при вызове getQuoteLevel2_pb2 HOT 12
- Иногда скрипт падает после нескольких минут(или секунд) работы HOT 1
- Скрипт отъедает 30% процессорного времени на холостом ходу. HOT 6
- Ошибка после создания OTC заявки HOT 3
- Открытый список вызываемых функций HOT 5
- Использовать последнюю версию lzmq с поддержкой ZMQ_LOOPBACK_FASTPATH.
- Иногда падает ошибка на OnAllTrade HOT 1
- sendTransaction HOT 3
- У меня периодически падает quik с ошибкой Exception code: 0xc0000374 HOT 5
- get_depo возвращает 0 по всем позициям, get_depo_ex ничего не возвращают
- Скрипт луа не запускается, если в config.json только один endpoint типа PUB
- Асинхронные вызовы из Python (пример кода) и ACCESS_VIOLATION HOT 3
- AsyncIO Python клиент для работы с Quik Lua RPC
- Не работает сборка докер-образа с zeromq 4.3.4
- Ошибка при получении T на стороне сервера HOT 1
- python abrosimov.a.a/qlua getCandlesByIndex - возвращает итерации одной свечи HOT 1
- Сборка через docker падает на libsodium HOT 3
- Вызов datasource_T падает
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from quik-lua-rpc.