Mikhail Sukhov
|
Дата: 04.10.2011
FiNick  пока не переполнится стек.
Что за стек?
|
|
|
|
FiNick
|
Дата: 04.10.2011
Mikhail Sukhov  FiNick  пока не переполнится стек.
Что за стек? Ну как, стек программы, который переполняется если, например, бесконечно рекурсивно вызывать какую-либо функцию. У меня на экране быстро появляются десятки окошек с ошибкой (см прикрепленную ошибку), все подвисает, пока не вылетит StackOverflow Exception. Попробуйте запустить SimpleGUI в промклиринг.
|
Автор топика
|
|
|
Alexander
|
Дата: 04.10.2011
Форум ртсНасколько я понял - exception выкидывать не надо. просто делать Sleep если для всех стримов обломилась проверка. какие ещё идеи?
|
|
|
|
Mikhail Sukhov
|
Дата: 04.10.2011
FiNick  Ну как, стек программы, который переполняется если, например, бесконечно рекурсивно вызывать какую-либо функцию. Рекурсии не увидел. FiNick  У меня на экране быстро появляются десятки окошек с ошибкой (см прикрепленную ошибку), все подвисает, пока не вылетит StackOverflow Exception. Попробуйте запустить SimpleGUI в промклиринг. Пример на то и пример, что показывает основное. Гидра прекрасно и пром и основной клиринг переживает. Видимо окошки не нужно выбрасывать.
|
|
|
|
Alexander
|
Дата: 04.10.2011
|
|
|
|
Mikhail Sukhov  Видимо окошки не нужно выбрасывать. Я думаю данный exception вообще лишний для ProcessDataError - т.к. это стандартная ситуация. Потому предлагаю чтоб pollAction возвращал bool флаг - success или нет (чтоб не грузили ProcessMessage). Соответственно предлагаю изменить его на: Code
if (Streams.Count == 0 && _streamsToRemove.Count == 0)
_sleepInterval.Sleep();
var checkSuccess = true;
Streams.SyncDo(c =>
{
foreach (var stream in Streams)
{
try
{
stream.CheckConnection(_connection);
}
catch (COMException e)
{
System.Diagnostics.Trace.WriteLine("stream.CheckConnection(_connection) - COMException " + e.ErrorCode.ToString());
checkSuccess = false;
return;
}
}
});
if (!checkSuccess)
{
_sleepInterval.Sleep();
return false;
}
_streamsToRemove.SyncDo(c =>
{
foreach (var stream in _streamsToRemove)
{
try
{
stream.Close();
}
catch (COMException e)
{
System.Diagnostics.Trace.WriteLine("stream.Close() - COMException " + e.ErrorCode.ToString());
Error.SafeInvoke(new PlazaException("Ошибка закрытия потока репликации.", e));
}
}
_streamsToRemove.Clear();
});
return true;
Ну и в PlazaConnection соответственно: Code
if (pollAction != null && !pollAction())
return;
Мысли \ возражения?
|
|
|
|
FiNick
|
Дата: 04.10.2011
Мне кажется, или такой код должен грузить проц под 100%? Там же нигде Sleep нету. Надо как-то сделать, чтобы если !pollAction() то поспать: Code
if (pollAction != null && !pollAction())
{
PollTimeOut.Sleep();
return;
}
|
Автор топика
|
|
|
Alexander
|
Дата: 05.10.2011
да, верно. подправил вариант ваше.
|
|
|
|
Alexander
|
Дата: 05.10.2011
Положил. Хотя бы 1 поток должен быть открыт, так правильнее. В этом случае ProcessMessage имеет смысл делать.
|
|
|
|
FiNick
|
Дата: 05.10.2011
Code
var success = true;
if (Streams.Count == 0 && _streamsToRemove.Count == 0)
success = false;
Streams.SyncDo(c =>
{
var anySuccess = false;
foreach (var stream in Streams)
{
try
{
stream.CheckConnection(_connection);
anySuccess = true;
}
catch (COMException e)
{
System.Diagnostics.Trace.WriteLine("Ошибка проверки потока репликации - stream.CheckConnection(_connection) - COMException " + e.ErrorCode.ToString());
}
}
success = anySuccess;
});
anySuccess лишняя переменная имхо, почему бы сразу везде не использовать success? Сегодня на клиринге протестирую, вроде должно работать. Кстати, после этих изменений у меня не коннектится. И проблема именно в PlazaStreamManager, потому что со старым вариантом все норм
|
Автор топика
|
|
|
Alexander
|
Дата: 05.10.2011
FiNick  Code
var success = true;
if (Streams.Count == 0 && _streamsToRemove.Count == 0)
success = false;
Streams.SyncDo(c =>
{
var anySuccess = false;
foreach (var stream in Streams)
{
try
{
stream.CheckConnection(_connection);
anySuccess = true;
}
catch (COMException e)
{
System.Diagnostics.Trace.WriteLine("Ошибка проверки потока репликации - stream.CheckConnection(_connection) - COMException " + e.ErrorCode.ToString());
}
}
success = anySuccess;
});
anySuccess лишняя переменная имхо, почему бы сразу везде не использовать success? Сегодня на клиринге протестирую, вроде должно работать. Кстати, после этих изменений у меня не коннектится. И проблема именно в PlazaStreamManager, потому что со старым вариантом все норм Исправил. По ночам лучше спать :) Мы должны дёргать ProcessMessage чтоб знать подключились или нет
|
|
|
|
FiNick
|
Дата: 05.10.2011
Alexander Mukhanchikov  По ночам лучше спать :) Вот именно!=) Все равно не работает, верни return, либо поменяй Func на Action
|
Автор топика
|
|
|
Alexander
|
Дата: 05.10.2011
FiNick  Alexander Mukhanchikov  По ночам лучше спать :) Вот именно!=) Все равно не работает, верни return, либо поменяй Func на Action недокоммитил. у себя проверял - работает.
|
|
|
|
FiNick
|
Дата: 05.10.2011
Протестил. В клиринг приложение не падает, но вот после клиринга перестал обновляться стакан, пришлось переконнектиться
|
Автор топика
|
|
|
Alexander
|
Дата: 05.10.2011
FiNick  Протестил. В клиринг приложение не падает, но вот после клиринга перестал обновляться стакан, пришлось переконнектиться Тоже самое и после торгов. Пока хз в чём дело. Если будут идеи после анализа исходников PlazaTrader - пишите.
|
|
|
|
FiNick
|
Дата: 05.10.2011
Похоже ошибку будет сложно отследить, т.к. клиринг просто так посреди дня несколько раз не воспроизвести.
Я смотрел логи, в начале клиринга по потоку FORTS_FUTAGGR5_REPL вылетает 'SERV:NO_SERVICE', затем через несколько секунд Stream opening started;stream 0x53183F0,type 1,name 'FORTS_FUTAGGR5_REPL'. То есть поток переоткрывается похоже, наверное в методе CheckConnection, если я ничего не путаю. Потом в логах он больше не фигурирует весь клиринг и после клиринга тоже
Кстати, замечание в РТС сделали, надо исправить: Закрывать потоки надо до закрытия соединения, а не пытаться сделать это после: 2011-10-05 19:03:13.921;p2repl-cli;;CLOSE message posted;stream 0x5415360 2011-10-05 19:03:13.921;p2repl-cli;error;p2err 24579=0x6003 - 'MQ:NOT_CONNECTED_YET';Couldn't post CLOSE message;stream 0x5415360
|
Автор топика
|
|
|
Alexander
|
Дата: 05.10.2011
|
|
|
|
FiNick  Похоже ошибку будет сложно отследить, т.к. клиринг просто так посреди дня несколько раз не воспроизвести.
Я смотрел логи, в начале клиринга по потоку FORTS_FUTAGGR5_REPL вылетает 'SERV:NO_SERVICE', затем через несколько секунд Stream opening started;stream 0x53183F0,type 1,name 'FORTS_FUTAGGR5_REPL'. То есть поток переоткрывается похоже, наверное в методе CheckConnection, если я ничего не путаю. Потом в логах он больше не фигурирует весь клиринг и после клиринга тоже
Кстати, замечание в РТС сделали, надо исправить: Закрывать потоки надо до закрытия соединения, а не пытаться сделать это после: 2011-10-05 19:03:13.921;p2repl-cli;;CLOSE message posted;stream 0x5415360 2011-10-05 19:03:13.921;p2repl-cli;error;p2err 24579=0x6003 - 'MQ:NOT_CONNECTED_YET';Couldn't post CLOSE message;stream 0x5415360 Так и делается, разве нет? Code
protected override void OnDisconnect()
{
// Иначе при выгрузке в StopStream будет срабатывать исключение.
if (IsExportRunning)
StopExport();
_connectionPool.Disconnect();
System.Diagnostics.Trace.WriteLine("OnDisconnect");
}
По поводу стаканов - в клиринг они присылают StreamDatumDeleted, надо как-то его обработать правильно. P.S. Я так пару багов с инициализацией инструмента подправил
|
|
|
|
FiNick
|
Дата: 05.10.2011
Alexander Mukhanchikov  Так и делается, разве нет? Code
protected override void OnDisconnect()
{
// Иначе при выгрузке в StopStream будет срабатывать исключение.
if (IsExportRunning)
StopExport();
_connectionPool.Disconnect();
System.Diagnostics.Trace.WriteLine("OnDisconnect");
}
А StopExport() здесь останавливает выполенение и дожидается пока все потоки будут закрыты? Я так понимаю закрытие потоков непосредственно выполняется в pollAction, может так получается, что дисконнект и закрытие потоков происходит параллельно. На счет стаканов РТС написали: "Как я понял, по вашему времени клиринг с 17-45 до 18-30 ? После него оба агреггированных потока приходили успешно вплоть до самого закрытия приложения." что собственно я и видел в логах. Возможно это у нас косяк
|
Автор топика
|
|
|
Alexander
|
Дата: 05.10.2011
FiNick  Alexander Mukhanchikov  Так и делается, разве нет? Code
protected override void OnDisconnect()
{
// Иначе при выгрузке в StopStream будет срабатывать исключение.
if (IsExportRunning)
StopExport();
_connectionPool.Disconnect();
System.Diagnostics.Trace.WriteLine("OnDisconnect");
}
А StopExport() здесь останавливает выполенение и дожидается пока все потоки будут закрыты? Я так понимаю закрытие потоков непосредственно выполняется в pollAction, может так получается, что дисконнект и закрытие потоков происходит параллельно. На счет стаканов РТС написали: "Как я понял, по вашему времени клиринг с 17-45 до 18-30 ? После него оба агреггированных потока приходили успешно вплоть до самого закрытия приложения." что собственно я и видел в логах. Возможно это у нас косяк Это точно наш косяк. Надо удалять записи с ревизиями < пришедшей по событию StreamDatumDeleted. Мы этого не делаем.
|
|
|
|
FiNick
|
Дата: 05.10.2011
Специальное уведомление StreamDatumDeleted присылается сервером по каждой таблице в начале синхронизации. Это уведомление означает «данных с ревиженами меньше указанного, на сервере нет». «Безбазовый» клиент должен удалить все данные с ревиженами, меньшими указанного в уведомлении из своего хранилища.
У нас же «базовый» клиент, там вроде само все делается, или я не прав? Плюс у нас в коде OnStreamDatumDeleted есть, там что-то делается
|
Автор топика
|
|
|
FiNick
|
Дата: 05.10.2011
Протрассировал дисконнект: Code
protected override void OnDisconnect()
{
// Иначе при выгрузке в StopStream будет срабатывать исключение.
if (IsExportRunning)
StopExport();
_connectionPool.Disconnect();
System.Diagnostics.Trace.WriteLine("OnDisconnect");
}
Там получается, что StopExport() никого не дожидается. _connectionPool.Disconnect() и Close всех потоков происходит параллельно, понятно, что Disconnect раньше происходит, и в лог ошибки сыплются. Поставил после StopExport() слип на пару секунд, все норм стало, но это грубо и некрасиво. Нужно AutoResetEvent какой-нибудь прикрутить или что-то подбное
|
Автор топика
|
|
|
Alexander
|
Дата: 06.10.2011
FiNick  Специальное уведомление StreamDatumDeleted присылается сервером по каждой таблице в начале синхронизации. Это уведомление означает «данных с ревиженами меньше указанного, на сервере нет». «Безбазовый» клиент должен удалить все данные с ревиженами, меньшими указанного в уведомлении из своего хранилища.
У нас же «базовый» клиент, там вроде само все делается, или я не прав? Плюс у нас в коде OnStreamDatumDeleted есть, там что-то делается У нас безбазовый клиент. И это как раз не делается.
|
|
|
|
FiNick
|
Дата: 06.10.2011
|
|
|
|
Например сделать так: В PlazaTrader'e Code
public override void StopExport()
{
lock (_stopExportLock)
{
_streamManager._stopStreamLock.Reset();
if (!IsExportRunning)
return;
StopStream();
base.StopExport();
_streamManager._stopStreamLock.WaitOne();
System.Diagnostics.Trace.WriteLine("Export stopped");
}
}
В PlazaStreamManager'e Code
internal readonly AutoResetEvent _stopStreamLock = new AutoResetEvent(false);
_streamsToRemove.SyncDo(c =>
{
foreach (var stream in _streamsToRemove)
{
try
{
stream.Close();
}
catch (COMException e)
{
System.Diagnostics.Trace.WriteLine("stream.Close() - COMException " + e.ErrorCode.ToString());
Error.SafeInvoke(new PlazaException("Ошибка закрытия потока репликации.", e));
}
}
_streamsToRemove.Clear();
_stopStreamLock.Set();
});
Или еще избавиться от _stopExportLock и написать так: Code
public override void StopExport()
{
_streamManager._stopStreamLock.WaitOne();
_streamManager._stopStreamLock.Reset();
if (!IsExportRunning)
return;
StopStream();
base.StopExport();
_streamManager._stopStreamLock.WaitOne();
System.Diagnostics.Trace.WriteLine("Export stopped");
}
|
Автор топика
|
|
|
FiNick
|
Дата: 06.10.2011
Alexander Mukhanchikov  У нас безбазовый клиент. И это как раз не делается. А как дела с другими фичами, StreamLifeNumChanged например?
|
Автор топика
|
|
|
Alexander
|
Дата: 06.10.2011
FiNick  Alexander Mukhanchikov  У нас безбазовый клиент. И это как раз не делается. А как дела с другими фичами, StreamLifeNumChanged например? см. private void OnStreamLifeNumChanged(CP2DataStream stream, int lifeNum) в PlazaStream.cs
|
|
|
|
Alexander
|
Дата: 06.10.2011
Стаканы после клиринга поправил вроде. Если есть возможность - протестируйте сегодня в клиринг, у меня не факт что удастся.
|
|
|