← 返回

Оставшиеся задачи до версии бета

  1. Нужно доделать потоки с заявками, сделками (собственными и тиковыми). Сейчас через потоки заполняются только инструменты, портфели, стаканы и позиции.
  2. PlazaStreamManager сейчас создает отдельные потоки для каждного стрима. Расточительно по ресурсам. Лучшем переделать на ThreadPool. И да, кто может мне объяснить в чем смысл всех этих ProcessMessage?
  3. Логику PlazaTableSerializer лучше перекинуть в PlazaSchemaParser. И да, можно ли построить логику PlazaSchemaParser на основе IniConfigParser?

Кто что сделает?

评论 (43)

登录创建账户, 登录或注册以发表评论

aspirant
aspirant

Mikhail Sukhov: PlazaStreamManager сейчас создает отдельные потоки для каждного стрима. Расточительно по ресурсам. Лучшем переделать на ThreadPool. Займусь.

Mikhail Sukhov: И да, кто может мне объяснить в чем смысл всех этих ProcessMessage? Это такой протокол. См. стр. 7 P2ClientFate.doc:

5.2. Принципы работы с соединениями в API Работа с соединениями производится по стандартному шаблону: • Создание объекта IP2Connection. • Вызов метода Connect — при его успешном завершении устанавливается локальное соединение с роутером. • Запуск бесконечного цикла, в котором происходит вызов функции ProcessMessage для соединения.

Mikhail Sukhov: Логику PlazaTableSerializer лучше перекинуть в PlazaSchemaParser. PlazaSchemaParser не используется вообще. Я его оставил, потому что уже сделал и жалко было выкидывать готовый, хотя и сырой, парсер ini-файлов потоков репликации. Может быть оставим PlazaTableSerializer и выкинем PlazaSchemaParser?

Mikhail Sukhov: И да, можно ли построить логику PlazaSchemaParser на основе IniConfigParser? Наверное, да. Но можем усложнить жизнь. Синтаксис в ini-файлов потоков репликации немного отличается (чуть сложнее). Может быть оставим, как есть?

Mikhail Sukhov: Кто что сделает? Таким образом беру 2 и 3.

aspirant
aspirant

aspirant:

Mikhail Sukhov: PlazaStreamManager сейчас создает отдельные потоки для каждного стрима. Расточительно по ресурсам. Лучшем переделать на ThreadPool. Займусь.

Готово

Mikhail Sukhov
Mikhail Sukhov 作者

aspirant: Это такой протокол. См. стр. 7 P2ClientFate.doc:

Прочитал. Не понял насчет интенсивности вызова этого метода. Я могу какое-то сообщение пропустить, если не успею вызвать метод ProcessMessage? Или они где-то копяться? С чем тогда прикол этого метода? Почему нельзя просто подписаться на событие и получать данные через него?

Меня еще смутил параметр PollInterval, который передавался в ProcessMessage. Прочитал доку, оказалось что это не PollInterval, а PollTimeout. Стало понятнее. Я так понял, это то время, на которое будет заблокирован метод ProcessMessage, если не будет нового сообщения?

Видел интерфейс IP2MessageReceiver? Я вот думаю, а это случайно не альтернатива ProcessMessage, только без вечного цикла?

aspirant: PlazaSchemaParser не используется вообще. Я его оставил, потому что уже сделал и жалко было выкидывать готовый, хотя и сырой, парсер ini-файлов потоков репликации. Может быть оставим PlazaTableSerializer и выкинем PlazaSchemaParser?

Как тебе будет виднее. Но R# говорит, что PlazaSchemaParser все же используется. И, судя по коду, PlazaTableSerializer пишет ini схемы, а PlazaSchemaParser читает. А нам вроде бы и то и другое нужно для работы.

aspirant: Наверное, да. Но можем усложнить жизнь. Синтаксис в ini-файлов потоков репликации немного отличается (чуть сложнее). Может быть оставим, как есть?

Давай оставим.

aspirant
aspirant

Mikhail Sukhov: Прочитал. Не понял насчет интенсивности вызова этого метода. Я могу какое-то сообщение пропустить, если не успею вызвать метод ProcessMessage? Или они где-то копяться? С чем тогда прикол этого метода? Почему нельзя просто подписаться на событие и получать данные через него?

Алгоритм подписки на потоки брал из примера плазовцев. Там этот метод вызывается в отдельном thread'е в непрерывном цикле. Во вторник попробую закомментить вызов этого метода и посмотреть, идут ли данные из потоков. Почему они так сделали, мне тоже непонятно.

Mikhail Sukhov: Меня еще смутил параметр PollInterval, который передавался в ProcessMessage. Прочитал доку, оказалось что это не PollInterval, а PollTimeout. PollInterval сейчас исправлю на PollTimeout. Я почему-то поменял название этого параметра🤨

Mikhail Sukhov: Я так понял, это то время, на которое будет заблокирован метод ProcessMessage, если не будет нового сообщения?

Да, это так.

Mikhail Sukhov: Видел интерфейс IP2MessageReceiver? Я вот думаю, а это случайно не альтернатива ProcessMessage, только без вечного цикла?

В доке как-то все размыто написано. У меня создалось впечатление, что этот интерфейс не относится к данным из потоков. Он нужен для отправки заявок и т.д., а я в это не влезал вообще.

Mikhail Sukhov:

aspirant: PlazaSchemaParser не используется вообще. Я его оставил, потому что уже сделал и жалко было выкидывать готовый, хотя и сырой, парсер ini-файлов потоков репликации. Может быть оставим PlazaTableSerializer и выкинем PlazaSchemaParser?

Как тебе будет виднее. Но R# говорит, что PlazaSchemaParser все же используется. И, судя по коду, PlazaTableSerializer пишет ini схемы, а PlazaSchemaParser читает. А нам вроде бы и то и другое нужно для работы.

Да, забыл. PlazaSchemaParser используется для десериализации данных из ini-файлов. Но эта фича нам пока не нужна, поэтому предлагаю вместо вызовов PlazaSchemaParser пока выкидывать NotImplementedException()?

Mikhail Sukhov
Mikhail Sukhov 作者

aspirant:

aspirant:

Mikhail Sukhov: PlazaStreamManager сейчас создает отдельные потоки для каждного стрима. Расточительно по ресурсам. Лучшем переделать на ThreadPool. Займусь.

Готово

Смотрел. Небольшой ликбез по работе пула потоков. В пул потоков мы помещаем небольшие действия, которых может быть очень много, но при этом отрабатывают они быстро. У тебя же помещается вечный цикл, что не является быстрой отработкой.

Идея работы пула в рамках PlazaStreamManager мне видется в заведении таймера (который Threading.Timer, потому что он основан на пуле потоков), в обработчике которого будут перебираться все соединения, и для них будет вызываться ProcessMessage. Тоесть, как только один "зависнет" в ожидании сообщения, таймер создаст еще один пуловый поток, который будет обрабатывать следующее свободное соединение (иначе все потоки будут ждать одно и то же соединение).

aspirant
aspirant

Mikhail Sukhov: Смотрел. Небольшой ликбез по работе пула потоков. В пул потоков мы помещаем небольшие действия, которых может быть очень много, но при этом отрабатывают они быстро. У тебя же помещается вечный цикл, что не является быстрой отработкой.

Насчет Threadpool'а знаю. Именно из-за этого изначально создавал полноценные Thread'ы.

Mikhail Sukhov: Идея работы пула в рамках PlazaStreamManager мне видется в заведении таймера (который Threading.Timer, потому что он основан на пуле потоков), в обработчике которого будут перебираться все соединения, и для них будет вызываться ProcessMessage. Тоесть, как только один "зависнет" в ожидании сообщения, таймер создаст еще один пуловый поток, который будет обрабатывать следующее свободное соединение (иначе все потоки будут ждать одно и то же соединение).

У меня здесь вот какое предложение. Сейчас мы для каждого стрима создаем отдельный Connection. А что если мы пойдем по более простому пути, как в примере у плазовцев: все стримы используют один Connection. В этом случае создается только один Thread, внутри которого в бесконечном цикле вызвается ProcessMessage. Если будут тормоза, тогда уже будем делать, как ты предлагаешь. Напиши, что думаешь.

Mikhail Sukhov
Mikhail Sukhov 作者

aspirant: У меня здесь вот какое предложение. Сейчас мы для каждого стрима создаем отдельный Connection. А что если мы пойдем по более простому пути, как в примере у плазовцев: все стримы используют один Connection. В этом случае создается только один Thread, внутри которого в бесконечном цикле вызвается ProcessMessage. Если будут тормоза, тогда уже будем делать, как ты предлагаешь. Напиши, что думаешь.

С этого и нужно было начать.🙂

aspirant
aspirant

Mikhail Sukhov: С этого и нужно было начать.🙂

Залил, на неделе нужно тестировать.

Mikhail Sukhov
Mikhail Sukhov 作者

aspirant:

Mikhail Sukhov: С этого и нужно было начать.🙂

Залил, на неделе нужно тестировать.

Исправил код. У тебя там хитрая логика с остановкой и перезапуском потока была, которая по сути не нужно вообще. Ну что это за робот, которому потоки не нужно?🙂 Поток пуская живет все время и закрывается при закрытие PlazaTrader. Меньше сложностей, меньша багов.

aspirant
aspirant

Mikhail Sukhov: Ну что это за робот, которому потоки не нужно?🙂

Вообще да. Как минимум, системные всегда будут.

aspirant
aspirant

aspirant: Да, забыл. PlazaSchemaParser используется для десериализации данных из ini-файлов. Но эта фича нам пока не нужна, поэтому предлагаю вместо вызовов PlazaSchemaParser пока выкидывать NotImplementedException()?

Залил

Mikhail Sukhov
Mikhail Sukhov 作者

aspirant:

aspirant: Да, забыл. PlazaSchemaParser используется для десериализации данных из ini-файлов. Но эта фича нам пока не нужна, поэтому предлагаю вместо вызовов PlazaSchemaParser пока выкидывать NotImplementedException()?

Залил

Можешь первый таск добить?

aspirant
aspirant

aspirant:

Mikhail Sukhov: С этого и нужно было начать.🙂

Залил, на неделе нужно тестировать.

Тестировал, потоки идут, стаканы есть. Без ProcessMessage, кстати, не работает.

aspirant
aspirant

Mikhail Sukhov:

aspirant:

aspirant: Да, забыл. PlazaSchemaParser используется для десериализации данных из ini-файлов. Но эта фича нам пока не нужна, поэтому предлагаю вместо вызовов PlazaSchemaParser пока выкидывать NotImplementedException()?

Залил

Можешь первый таск добить?

Постараюсь завтра-послезавтра

Bell
Bell

как же вы 4 месяца занимались Плазой и только теперь выясняете, что такое ProcessMessage? судя по техническому форуму РТС, без ясного понимания, как это работает, легко получить тормозящий код. проконсультируйтесь с Кукушкиным, который вроде хорошо разобрался. Или с ртс-овцами. Дока там ужасная.

aspirant
aspirant

Mikhail Sukhov: И да, кто может мне объяснить в чем смысл всех этих ProcessMessage?

Вот, кстати, интересная ветка.

Mikhail Sukhov
Mikhail Sukhov 作者

aspirant:

Mikhail Sukhov: И да, кто может мне объяснить в чем смысл всех этих ProcessMessage?

Вот, кстати, интересная ветка.

Или я не понимаю схему работы сообщений от Плазы, или там обсуждается какая-то ерунда. Таймаут надо ставить по максимуму, так как он дает возможность не вызывать в холостую метод ProcessMessage. Ставить 1 милилсекунду нет никакого смысла, так как данные от Плазы накапливаются (это я так думаю), и все равно ничего не пропустится.

aspirant
aspirant

Mikhail Sukhov: Или я не понимаю схему работы сообщений от Плазы, или там обсуждается какая-то ерунда. Таймаут надо ставить по максимуму, так как он дает возможность не вызывать в холостую метод ProcessMessage. Ставить 1 милилсекунду нет никакого смысла, так как данные от Плазы накапливаются (это я так думаю), и все равно ничего не пропустится. Вот механизм работы: Таймаут - это сколько висеть на сокете в ожидании пакета данных, если пакет уже есть, то метод вернется сразу как только обработаются все события получения данных. Остальное, да, вода. Поток используется только под этот метод, поэтому ставить маленькие периоды смысла нет.

Mikhail Sukhov
Mikhail Sukhov 作者

Mikhail Sukhov: Или я не понимаю схему работы сообщений от Плазы, или там обсуждается какая-то ерунда. Таймаут надо ставить по максимуму, так как он дает возможность не вызывать в холостую метод ProcessMessage. Ставить 1 милилсекунду нет никакого смысла, так как данные от Плазы накапливаются (это я так думаю), и все равно ничего не пропустится. Вот механизм работы: Таймаут - это сколько висеть на сокете в ожидании пакета данных, если пакет уже есть, то метод вернется сразу как только обработаются все события получения данных. Остальное, да, вода. Поток используется только под этот метод, поэтому ставить маленькие периоды смысла нет.

Вот и возник вопрос. Есть сообщения копяться от Плазы, зачем тогда вообще вызывать ProcessMessage? Почему не сделали просто вызов события?

aspirant
aspirant

Mikhail Sukhov: Вот и возник вопрос. Есть сообщения копяться от Плазы, зачем тогда вообще вызывать ProcessMessage? Почему не сделали просто вызов события?

Не знаю, но без вызова точно не работает. Только что еще раз проверил.

Mikhail Sukhov
Mikhail Sukhov 作者

aspirant:

Mikhail Sukhov: Вот и возник вопрос. Есть сообщения копяться от Плазы, зачем тогда вообще вызывать ProcessMessage? Почему не сделали просто вызов события?

Не знаю, но без вызова точно не работает. Только что еще раз проверил.

=) Я верю что не работает. С первого раза поверил. Но думаю тут не спроста. Или косяк в архитектуре Плазы (не удивлюсь) или мы что-то упустили.

aspirant
aspirant

Mikhail Sukhov: =) Я верю что не работает. С первого раза поверил. Это я сам себя проверял. Порой кажется, что все сделал правильно, а упустишь какую-то мелочь и приходится есть свой галстук. Образно, конечно🙂

Mikhail Sukhov: Но думаю тут не спроста. Или косяк в архитектуре Плазы (не удивлюсь) или мы что-то упустили.

Мне все-таки кажется, что первое. Повторюсь: алгоритм взят из их примера BaselessClient.

Bell
Bell

ProcessMessage это прокачка очереди сообщений на сокете "вручную". Почему сделано так, а не иначе хз. Для совместимости чего-то с чем-то. Без понимания всех нюансов (а их там много) может быть плохо, потому что внутри есть критические секции, при работе с одним объектом из разных тредов может происходить маршаллинг. Общее правило кажется(!) один поток - один объект коннекшн.

Mikhail Sukhov
Mikhail Sukhov 作者

Bell: ProcessMessage это прокачка очереди сообщений на сокете "вручную". Почему сделано так, а не иначе хз. Для совместимости чего-то с чем-то. Без понимания всех нюансов (а их там много) может быть плохо, потому что внутри есть критические секции, при работе с одним объектом из разных тредов может происходить маршаллинг. Общее правило кажется(!) один поток - один объект коннекшн.

Это как бы правило МТА. Только все равно не понятно насчет ProcessMessage.

Bell
Bell

Mikhail Sukhov: Только все равно не понятно насчет ProcessMessage. Почему так сделано? Это надо спрашивать у разработчиков. Они это где-то объясняли, но я не понял. У меня на Плазу вообще идиосинкразия. Вот всё надеялся, что вы сделаете нормально...

Mikhail Sukhov
Mikhail Sukhov 作者

Bell:

Mikhail Sukhov: Только все равно не понятно насчет ProcessMessage. Почему так сделано? Это надо спрашивать у разработчиков. Они это где-то объясняли, но я не понял. У меня на Плазу вообще идиосинкразия. Вот всё надеялся, что вы сделаете нормально...

Почему в прошедшем времени?🙂

Bell
Bell

Mikhail Sukhov: Почему в прошедшем времени?🙂 ок, буду ждать 🙂 но еще раз посоветую проконсультироваться по разным таким нюансам с теми, кто разобрался. Вот Кукушкин на техфоруме РТС очень доброжелательный чел.

Mikhail Sukhov
Mikhail Sukhov 作者

Bell:

Mikhail Sukhov: Почему в прошедшем времени?🙂 ок, буду ждать 🙂 но еще раз посоветую проконсультироваться по разным таким нюансам с теми, кто разобрался. Вот Кукушкин на техфоруме РТС очень доброжелательный чел.

Хорошо, перед сертификацией PlazaTrader обязательно пройдем сертификацию Кукушкина.🙂

aspirant
aspirant

Mikhail Sukhov: Нужно доделать потоки с заявками, сделками (собственными и тиковыми).

Залил заявки. Посмотри в PlazaTrader OnDealFutureStreamInserted / OnDealOptionStreamInserted. В GUI клиенте идут.

Mikhail Sukhov
Mikhail Sukhov 作者

aspirant:

Mikhail Sukhov: Нужно доделать потоки с заявками, сделками (собственными и тиковыми).

Залил заявки. Посмотри в PlazaTrader OnDealFutureStreamInserted / OnDealOptionStreamInserted. В GUI клиенте идут.

По-моему это не заявки.🙂

aspirant
aspirant

Mikhail Sukhov: По-моему это не заявки.🙂

Это были сделки (deal - Журнал сделок), спешил в ночи😢

Mikhail Sukhov
Mikhail Sukhov 作者

aspirant:

Mikhail Sukhov: По-моему это не заявки.🙂

Это были сделки (deal - Журнал сделок), спешил в ночи😢

Там код получился один в один для фьючей и опцов. Может имеет смысл вынести в общий метод, как я с инструментами сделал? Или как со стаканами.

aspirant
aspirant

Mikhail Sukhov: Там код получился один в один для фьючей и опцов. Может имеет смысл вынести в общий метод, как я с инструментами сделал? Или как со стаканами. Сделал + залил заявки. В заявках по многим свойствам вопросы. Посмотришь исходник? Может быть нужно мапить из еще одной таблицы (OrdersLogFutureStream / OrdersLogOptionStream)🤨 Но это уже завтра. Elvis has left the building...

Mikhail Sukhov
Mikhail Sukhov 作者

aspirant:

Mikhail Sukhov: Там код получился один в один для фьючей и опцов. Может имеет смысл вынести в общий метод, как я с инструментами сделал? Или как со стаканами. Сделал + залил заявки. В заявках по многим свойствам вопросы. Посмотришь исходник? Может быть нужно мапить из еще одной таблицы (OrdersLogFutureStream / OrdersLogOptionStream)🤨 Но это уже завтра. Elvis has left the building...

Удалил это, так как это неправильно.

static PlazaColumnRegistry()
{
	// Без этого конструктора клиенту нельзя добавить колонки.
}

Статический конструктор есть всегда. Он или нами явно определяется, или его компилятор "дописывает".

Посмотрел и поправил код. Но у меня почему то заявки не идут с Плазы. Выставил по рынку - ни одного уведомления. Перезапустил прогу, опять ничего по заявкам.

aspirant
aspirant

Mikhail Sukhov: Удалил это, так как это неправильно.

static PlazaColumnRegistry() { // Без этого конструктора клиенту нельзя добавить колонки. }

> 
> Статический конструктор есть всегда. Он или нами явно определяется, или его компилятор "дописывает".

Добавь у себя в Connect_Click GUI клиента сразу после инициализации Trader вот этот кусок кода:

PlazaTableRegistry.DealFuture.Columns.Add(PlazaColumnRegistry.DealFuture.BuyRtsCode);

И запусти GUI клиент.  У меня при попытке подключения срабатывает ArgumentNullException.  С явным статическим конструктором PlazaColumnRegistry() исключения нет.  Меняется порядок инициализации статических классов?  Шаманство🤨 Вчера уже не успевал влезть в суть.


> **[Mikhail Sukhov](@message(8071)):**
> Но у меня почему то заявки не идут с Плазы. Выставил по рынку - ни одного уведомления. Перезапустил прогу, опять ничего по заявкам.

Нужно копать. А как выставить заявку в GUI-примере?
lkor
lkor

aspirant: Нужно копать. А как выставить заявку в GUI-примере?

инструменты - выбрать инструмент - новая заявка.

Mikhail Sukhov
Mikhail Sukhov 作者

aspirant: Добавь у себя в Connect_Click GUI клиента сразу после инициализации Trader вот этот кусок кода:

PlazaTableRegistry.DealFuture.Columns.Add(PlazaColumnRegistry.DealFuture.BuyRtsCode);

> И запусти GUI клиент.  У меня при попытке подключения срабатывает ArgumentNullException.  С явным статическим конструктором PlazaColumnRegistry() исключения нет.  Меняется порядок инициализации статических классов?  Шаманство🤨 Вчера уже не успевал влезть в суть.

Действительно, чудеса.
aspirant
aspirant

lkor:

aspirant: А как выставить заявку в GUI-примере? инструменты - выбрать инструмент - новая заявка.

У меня проблема: при попытке выставить заявку в асинхронном режиме выкидывается InvalidCastException в строчке``` plazaMessage.SendAsync2(_connection, timeOut, _messageDispatcher, transaction.Id);

метода PlazaTrader.SendTransaction.  Кто-нибудь сталкивался?  В синхронном режиме приходит сообшение, что не хватает средств на счете, который действительно пуст.  Его нужно пополнять?  Если да, то каким образом?
Mikhail Sukhov
Mikhail Sukhov 作者

aspirant:

lkor:

aspirant: А как выставить заявку в GUI-примере? инструменты - выбрать инструмент - новая заявка.

У меня проблема: при попытке выставить заявку в асинхронном режиме выкидывается InvalidCastException в строчке``` plazaMessage.SendAsync2(_connection, timeOut, _messageDispatcher, transaction.Id);

> метода PlazaTrader.SendTransaction.  Кто-нибудь сталкивался?  В синхронном режиме приходит сообшение, что не хватает средств на счете, который действительно пуст.  Его нужно пополнять?  Если да, то каким образом?

Кстати да, надо не забыть разобраться с тем, как получать вменяемые ошибки в асинхронном режиме.

Залил изменения, чтобы получать инфу по заявкам. Вкратце, использовали не те потоки.

Может уже пора бету выкладывать?
aspirant
aspirant

Mikhail Sukhov: Может уже пора бету выкладывать? OK, тогда я переключаюсь на документацию. И ждем пламенный привет бета-тестеров🙂

Bell
Bell

еще добавлю, что со сборкой стакана тоже есть ряд тонких моментов. Они вроде описаны в топике

aspirant
aspirant

Bell: еще добавлю, что со сборкой стакана тоже есть ряд тонких моментов. Они вроде описаны в топике

Да, я писал реализацию на основе этого топика.

Bell
Bell

aspirant:

Bell: еще добавлю, что со сборкой стакана тоже есть ряд тонких моментов. Они вроде описаны в топике

Да, я писал реализацию на основе этого топика. Снимаю шляпу. Я начинал, но плюнул, так мне это не понравилось.