В приложении ASP.NET, которое я пишу, мне нужно использовать подключения к определенному серверу (что-то вроде БД, но ... другое). Установление соединений довольно дорогое (буквально несколько секунд), поэтому я пытаюсь написать пул для улучшения масштабируемости.
Все довольно просто, вплоть до одного - утилизации старых соединений. Под старым я подразумеваю «соединения, которые были в пуле неиспользованными более, чем, скажем, 5 минут». Их очистка также освободит ресурсы на сервере, к которому они подключаются.
Мне понадобится какой-то поток, который просыпается каждые 5 минут, проверяет старые неиспользуемые соединения в пуле и закрывает их. Однако, как я понял из Google, ASP.NET и длительные потоки несовместимы.
Я не боюсь завершения всего процесса, потому что тогда мой пул тоже очистится (деструкторы и все такое). Я боюсь, что мой поток очистки может быть завершен до завершения работы моего приложения (и мой пул останется без очистителя). Или наоборот - мой поток очистки блокирует закрытие моего приложения.
Как это правильно реализовать?
«Таинственный сервис» - это гигантское приложение, написанное моей компанией более 10 лет. Это бухгалтерское приложение Delphi, которое использует MSSQL или Oracle для своих данных. Другого сервера нет.
Недавно (как и несколько лет назад) он также приобрел интерфейс, который внешние приложения могут использовать для связи с ним. Это консольное приложение Windows, которое по сути является тем же приложением, за исключением того, что вместо графического интерфейса пользователя оно слушает сокет и использует некую сериализацию Delphi для передачи данных туда и обратно.
На стороне клиента есть .DLL (написанная на Java, позже модифицированная для компиляции под J #), которая анализирует этот поток двоичных данных и имитирует бизнес-уровень в .NET. То есть - получаю все те же бизнес-классы (700+), что и в оригинальном приложении на Delphi. Или что-то очень близкое к этому (я думаю, что само приложение имеет> 3000 классов). И я должен использовать их для выполнения любой бизнес-логики, которую я хочу. Все мои звонки перенаправляются в реальное приложение, которое затем выполняет работу.
Я не могу подключиться напрямую к базе данных MSSQL / Oracle, потому что на сервере есть много причудливой бизнес-логики, которую мне затем придется реплицировать и не отставать (приложение постоянно разрабатывается). Я не могу воссоздать клиентский .DLL, потому что это займет слишком много времени, и протокол в любом случае будет диктовать почти такой же результат. Я не могу написать обертку вокруг него, так как мне пришлось бы обернуть все 700+ классов, которые там есть.
Другими словами, я не контролирую бизнес-уровень. Это так, как есть (и на самом деле несколько человек ушли, а не продолжили работать с этим). Я просто стараюсь делать все возможное.
Код для использования этого материала выглядит примерно так:
ConnectionType con = new ConnectionType;
con.OpenConnection("server", "port", "username", "password");
BLObjectNumber234 obj = (BLObjectNumber234)con.GetBLObject("BLObjectNumber234");
obj.GetByPK(123);
// Do some stuff with obj's properties and methods
// that are different for each BLObject type
Эти объекты BL довольно случайны. Все они одиночные - вызов con.GetBLObject всегда возвращает один и тот же экземпляр. Большая часть данных получается как DataTable путем вызова специального метода, но довольно много данных также находится в свойствах; некоторые требуют вызова специальных методов с причудливыми недокументированными константами; есть также свойства, которые являются другими экземплярами объекта BL (я не уверен, являются ли они одиночными, я думаю, что нет), и они требуют специального кода для заполнения и т. д.
В общем, я бы назвал систему «patchware» - поскольку кажется, что она была сделана с помощью миллиона исправлений и обходных путей, склеенных вместе тем способом, который был наиболее удобен в то время.





Вы можете написать службу WCF, которая обертывает службу, которую вы пытаетесь вызвать, а затем связываться с этой загадочной службой только через приложение службы WCF.
WCF имеет различные модели для обработки пула и очистки.
Вам не нужно будет обертывать каждый класс и функцию, а только действия, которые вам нужно выполнить. Таким образом, вам может потребоваться метод для получения некоторых данных и метод для обновления некоторых данных, это будет преобразовываться в сервисе как последовательность вызовов различных функций по мере необходимости. Логика внешнего интерфейса будет упрощена, и, следовательно, это упростит будущие выпуски веб-сайта.
Хорошо, просто чтобы ответить на ваше собственное дополнение к этому вопросу - я думаю, вы слишком зацикливаетесь на значении «обертка». Я надеюсь, что вы все равно делаете какую-то упаковку, или, возможно, мне нужно перестать предполагать это и задать вам вопрос напрямую: вызываете ли вы эту службу непосредственно из кода, стоящего за страницами asp.net, или вы создали отдельные классы для обработки связи между клиентской частью и службой? Как только мы создадим архитектуру, которая у вас есть в настоящее время, мы посмотрим, возможно ли переместить эту логику в отдельный сервис (а затем воспользоваться преимуществами, которые может предложить WCF).
Я согласен с Крисом, было бы гораздо уместнее иметь всю вашу бизнес-логику (код, который взаимодействует со всеми таинственными бизнес-объектами) на отдельном слое, чем на веб-слое (уровне представления).
Это сделало бы дизайн вашего приложения намного более масштабируемым, и вы могли бы намного проще выполнять такие вещи, как объединение в пулы, потоки и другие задачи, связанные с масштабируемостью.
Если вы решите использовать WCF для связи между сетью и бизнес-уровнем (используйте каналы имен, если они находятся на одном компьютере), вы получите чистую, масштабируемую и производительную архитектуру.