Конференция "Сети" » Использование TWSocketThrdServer из набора ICS
 
  • Nouser © (07.02.16 03:02) [20]
    > Eraser ©   (06.02.16 16:17) [14]
    Отправил на мыло эхо-демо.
  • Eraser © (07.02.16 12:49) [21]

    > Nouser ©   (07.02.16 03:02) [20]

    получил, спасибо!
  • NoUser © (10.02.16 02:24) [22]
    > чем меньше задержки, тем лучше.

    Открыл Рихтера - увидел
    SetFileCompletionNotificationModes

    ,
    прикрутил - таки да, можно несколько сэкономить на переключениях потоков.

    Еще есть
    SetFileIoOverlappedRange

    , видимо для того чтобы дать возможность драйверу работать напрямую (без лишнего копирования) с пользовательским буфером. Пока не крутил, но заманчиво.
  • Eraser © (10.02.16 19:15) [23]

    > Nouser ©   (07.02.16 03:02) [20]
    > > Eraser ©   (06.02.16 16:17) [14]
    > Отправил на мыло эхо-демо.

    видимо вещь очень узко заточенная под конкретную задачу, в целом, много полезного, думаю применение найдется.


    > DVM ©   (06.02.16 16:42) [15]


    > Наверное ты вот это видел, но приведу ссылку на всяк случай
    > https://github.com/bamlan/delphi-iocp-framework
    >
    > я его проверял, оно быстро работает.

    по началу обрадовался, прикрутить удалось на место ICS буквально за час. Работает быстро, все то что надо. НО всплыла проблема, с которой я сталкивался и раньше. Здесь она не решена вообще никак. На хорошо загруженном сервер (около 500 нагруженных соединений, причем они коннектятся и отваливаются десятками в секунду, так надо) начинает происходить простая и очень удручающая вещь. А именно - не на каждый WSASend приходит соответствующее событие завершения в порт. В итоге получаем серьезную утечку ресурсов. Буквально за 5-10 минут работы легко может съесть 1 Гб памяти. Причем сам фреймворк отображает где именно. Да и провел простой эксперимент, посчитав количество WSASend и его завершений - все именно так.

    Еще больше удручает то, что в сети нет упоминаний о данной проблеме. Код вызова WSASend и обработка завершения в компоненте выглядят корректно, да и видно, что фреймоворк не школьник писал и для работы. Вот и думаю, то ли лыжи не едут, то ли я..
  • Eraser © (10.02.16 23:08) [24]

    > А именно - не на каждый WSASend приходит соответствующее
    > событие завершения в порт.

    дело, конечно же, оказалось не в IOCP, а во фреймворке, автор не до конца освобождал блоки память.
  • DVM © (12.02.16 21:34) [25]

    > Eraser ©   (10.02.16 23:08) [24]


    > автор не до конца освобождал блоки память.

    так может ты напишешь где он не освобождал? или еще лучше автору написать.
  • Eraser © (13.02.16 21:35) [26]

    > DVM ©   (12.02.16 21:34) [25]

    в procedure TIocpIoThread.Execute; модуля Iocp.TcpSocket

    есть такой участок:
         if not IocpStatusOk then
         begin
           if (PerIoData = nil) and (Connection = nil) then
           begin
             LastErr := GetLastError;
             //if (LastErr <> ERROR_ABANDONED_WAIT_0) then
               AppendLog('%s IoThread %d ERROR %d=%s', [FOwner.ClassName, ThreadID, LastErr, SysErrorMessage(LastErr)], ltError);
             Break;
           end;

           if (PerIoData <> nil) then
           begin
             if PerIoData.Operation = iotWrite then
             begin
               FOwner.IoCachePool.FreeMemory(PerIoData.Buffer.DataBuf.Buf);
             end;

             FOwner.FreeIoData(PerIoData);
           end;

           if (Connection <> nil) then
           begin
             Connection.Release; // 对应PostRead/PostWrite中的AddRef
             Connection.Disconnect; // 对应连接创建时的FRefCount := 1
           end;

           Continue;
         end;


    собственно, вот этой строки не хватало


             if PerIoData.Operation = iotWrite then
             begin
               FOwner.IoCachePool.FreeMemory(PerIoData.Buffer.DataBuf.Buf);
             end;

    т.к. в MSDN есть такой текст

    If *lpOverlapped is not NULL and the function dequeues a completion packet for a failed I/O operation from the completion port, the function stores information about the failed operation in the variables pointed to by lpNumberOfBytes, lpCompletionKey, and lpOverlapped. To get extended error information, call GetLastError.

    https://msdn.microsoft.com/ru-ru/library/windows/desktop/aa364986(v=vs.85).aspx

    Собственно, дальше PerIoData освобождалась, а вот PerIoData.Buffer.DataBuf.Buf - нет, данные повисали в воздухе, точнее в пулле, помеченные как занятые.

    В целом, вот уже неделю занят отладкой и ковырянием данного фреймворка и кода, связанного с ним, но там проблемы скорее из-за специфики моего функционала. Если правильно настроить кэши, то производительности для моих нужд хватает.

    вообще удивительно, почему нет ни одного приличного и полностью отлаженного инструмента. во всех таких проектах главная проблема - переоптимизация, авторы боятся потратить лишний мегабайт памяти или лишний такт процессора, в итоге, страдает архитектура, причем сильно. а что памяти пустой полно, что процессор не загружен, только AV сыпаться, а так ничего )
  • Eraser © (13.02.16 21:46) [27]
    кстати, пришлось еще добавить в пулл объектов еще одну очередь удаленных объектов, из которой они уже окончательно освобождаются строго, после указанного интервала. Некий примитивный GC. Того подхода, который был изначально не хватало, приводило к AV.

    Вообще беда таких проектов - отсутствие инфраструктуры для отладки. Естественно на 10 или 100 соединениях все будет работать нормально, а вот под нагрузкой мельчайшие недоработки рано или поздно вылезают, классика. Приходится заниматься отладкой на боевом сервере, к сожалению.
 
Конференция "Сети" » Использование TWSocketThrdServer из набора ICS
Есть новые Нет новых   [118608   +45][b:0][p:0.001]