Delphi.RobustServer.Упрощаем routing запросов. Базовый класс TRP

Дописал базовый класс TRP, от которого можно наследовать всю бизнес логику. Теперь можно обращаться, скажем по адресу Users/Create, сервер найдет класс TRPUsers и попытается найти у него метод Create. Реализация TRP включает в себя RTTI механизм. Чуть позже есть идея добавить атрибуты [HttpGet], [HttpPost] которые можно будет добавлять над методами.

Сам базовый класс выглядит так Continue reading

Posted in Delphi | Leave a comment

Delphi.RobustServer.Обработка POST запросов для основных MIME

Доработал обработку POST запросов для следующих MIME типов

  • application/json
  • application/x-www-form-urlencoded
  • multipart/form-data

Теперь сервер умеет работать с json, принимать файлы, пока ещё не оч. большие (poststream блоками читается в строку = оперативную память), поэтому по-хорошему, размер файлов надо ограничить, ну и одновременную закачку файлов тоже, чтобы не подвесить память. Конечно же, стандартный form-url-encoded поддерживается, хотя если в multipart не указывать файл, просто параметры тоже прочитаются с декодированием из urlEncoded

Ну и в качестве бонуса научил сервер отправлять письма. Управлением памятью теперь почти везде занимается класс ISP<>, который находится в модуле  uCommon.

Модуль декодирования POST запроса похудел и выглядит следующим образом Continue reading

Posted in Delphi | Leave a comment

Delphi.RobustServer. Логгер на GUI

Добавил логгер на GUI

Механизм такой – при добавлении сообщения в лог, автоматически обновляется GUI. Сообщения идут в обратном порядке. Ключевым моментом является функция WaitAndCreateLogFileStream класса TLDSLogger. Сначала сообщения пишутся в файл, затем из файла в GUI. Всей многопоточной логикой заведует класс TLDSLogger.

Continue reading

Posted in Delphi | Leave a comment

Delphi.RobustServer.Открытие соединения с БД.Простой случай.

Как и когда нужно создавать экземпляр соединения с бд в серверном приложении? Путем чтения книг,  опыта и ошибок я понял, что под каждый запрос, создается поток, под каждый поток нужно  создавать соединение отдельно, иначе начинается хаос…

Но это в случае, если у нас не 20 000 запросов в секунду, которые открывают соединение, в этом случае, наш сервер захлебнется, потому что не будет успевать это обрабатывать, соединения будут открываться быстрее, чем закрываться, и это будет расти как снежный ком, до того момента, пока  MySQL, например, не скажет, “у вас слишком много соединений, бай бай”.

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

На более конкретном примере это выглядело так. 20 000 потоков в сек. опрашивали сервер – а нет ли чего нового для меня в буфере? Дожидаясь своей очереди, они забирали информацию и изменяли буфер, удаляя унесенные данные и передавали квант следующему потоку.

Реализуем пока самый простой случай. Когда нагрузка у нас по данному запросу небольшая. А высоконагруженный вариант сделаем чуть позже.  Сделаем же нашу реадизацию красиво, то есть так… Continue reading

Posted in Delphi | Leave a comment

Delphi.RobustServer. Загрузка файлов на сервер

Сделал простую загрузку файлов на сервер, с возможностью создания уникального имени, если такое имя уже будет в директории сервера. Сама директория будет строиться как files/year/month/day

Результат кода выглядит так

Сам запрос идет через multipart следующим образом… Continue reading

Posted in Delphi | Leave a comment

Delphi.RobustServer. Совершенствуем CommandGet и тестовый класс TRPUsers

Немного отрефакторил код OnCommandGet, получилось так, довольно коротко…

Обработка запросов происходит в методах Process…, например ProcessUsers выглядит так Continue reading

Posted in Delphi | Leave a comment

Delphi.RobustServer.Обработка ошибок, интерфейсный класс TResponses и измерение оперативной памяти

Сделал обработку ошибок следующим образом

В модуле CommandGet сделал единый блок try / except

Теперь, если возникнет ошибка при обработке запроса, она не потеряется, а придет в понятном json формате, то есть вот так….

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

Возможно информация избыточная, над этим надо подумать, но в целом мне нравится.  Continue reading

Posted in Delphi | Leave a comment

Delphi. Измерение оперативной памяти

Модуль из проекта

Вот эти 2 процедуры измеряют текущую память и пиковую

Полный модуль

 

Posted in Delphi | Leave a comment

Delphi.RobustServer – первые шаги

Github

Первые несколько шагов. Текущую версию я делаю Visual Components Library App. Потом можно будет перевернуть это приложение в сервис, при желании.

Архитектура  следующая Continue reading

Posted in Delphi | Leave a comment

Delphi. Отправка строки из одного потока в другой

Простой пример, отправка из дополнительного потока в основной

Отправка…

Прием

Continue reading

Posted in Без рубрики | Leave a comment