powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Datasnap client
11 сообщений из 11, страница 1 из 1
Datasnap client
    #39925776
RuslanSharipov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день. На нескольких хостах развернут сервер реализованный через datasnap. На клиенте мне нужно параллельно обращаться к каждому из серверов. Но складывается ощущение что в один момент времени клиент может открыть только одно соединение, и не важно что подключения создаются и осуществляются каждый в своем потоке, потому что как только один из хостов недоступен остальные потоки(TTask) "зависают" и в них просто ничего не происходит пока неработающий хост не прервется по таймауту. Вопрос:
действительно ли это так?возможно нужно выставить какой-то параметр у SQLConnection?или такой проблемы вообще нет и видимо ошибка где то в коде?
...
Рейтинг: 0 / 0
Datasnap client
    #39925796
Sinemurius
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я предполагаю, что Ваш клиент уже в значительной степени написан, там много кода и его сложно использовать для отладки. Это так ?
...
Рейтинг: 0 / 0
Datasnap client
    #39925827
RuslanSharipov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Sinemurius, да клиент написан, но при отладке я ничего не нахожу. судя по логам второй поток просто не стартует из-за того что в этот момент в другом потоке висит конекшн к другому серверу.
в основном потоке примерно:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
procedure TProcessListenerController.AddListener(ANode: string; AAutoStart: Boolean = True; AAutoStop: Boolean = False);
begin
  ....
  ANodeListener := TNodeListener.Create(Self, ANode, FOnLog);  
  if AAutoStart then begin
    ANodeListener.Run(AAutoStop); //здесь TTask.Create, затем старт
  end;
end;

.........

for I := Low(AHosts) to High(AHosts) do begin
    FController.AddListener(AHosts[I], False);
end;



таким образом создаются например 2 потока(первым тот у которого хост отключен), task стартует(у второго тоже успевает вызваться метод старт), и потом второй таск просто не запускается как будто, "скажем так пул потоков лочится" пока первый таск не отвиснет.

Логи:

первый:
Код: pascal
1.
2.
3.
12.02.2020 16:09:51.489 ~dbg~ Created
12.02.2020 16:09:51.490 ~dbg~ TryConnect
12.02.2020 16:10:14.755 ~dbg~ connection timeout



второй:
Код: pascal
1.
2.
12.02.2020 16:10:12.572 ~dbg~ Created
12.02.2020 16:10:12.572 ~dbg~ TryConnect



Если будет пять хостов и неработающий в списке посередине, первые два запускаются, начинают работать а потом просто виснут пока третий(с неработащим хостом) не вывалится с таймаутом.
...
Рейтинг: 0 / 0
Datasnap client
    #39925933
Sinemurius
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А не используете Synchronize или что-то в этом роде ?

Я обычно в таких случаях трачу минут 40, чтобы написать крайне упрощенный вариант клиента для отладки.
...
Рейтинг: 0 / 0
Datasnap client
    #39925935
RuslanSharipov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Sinemurius, нет не использую
...
Рейтинг: 0 / 0
Datasnap client
    #39926276
RuslanSharipov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Переписал с использованием TThread вместо TTask такой проблемы нет..причина не понятна
...
Рейтинг: 0 / 0
Datasnap client
    #39926287
AlexeyM123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Может быть это связано с

There's a nasty bug in the System.Threading code that was introduced in Delphi 10.2
Tokyo. I certainly hope that it will be fixed in the next release, as it makes the Parallel
Programming Library hard to use. It sometimes causes new threads not to be created when
you start a task. That forces your tasks to execute one by one, not in parallel.

как это описано у Primož Gabrijelčič
в Delphi High Performance
...
Рейтинг: 0 / 0
Datasnap client
    #39926574
RuslanSharipov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
AlexeyM123, нет. Нашел причину. Как оказалось потоки не при чем(просто повезло). Зачем-то в технологии datasnap они открывают конекшн в момент его создания:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
function TDBXConnectionFactory.GetConnection(const DBXContext: TDBXContext;
  const ConnectionProperties: TDBXProperties): TDBXConnection;
var
  ConnectionBuilder:  TDBXConnectionBuilder;
  DelegatePath:       TDBXDelegateItem;
  CombinedProperties: TDBXProperties;
begin
  CombinedProperties := CombineDriverProperties(ConnectionProperties);
  DelegatePath := CreateDelegatePath('', CombinedProperties);
  ConnectionBuilder := TDBXConnectionBuilder.Create;
  try
    ConnectionBuilder.FDelegatePath               := DelegatePath;
    ConnectionBuilder.FConnectionFactory          := Self;
    ConnectionBuilder.FDBXContext                 := TDBXContext.Create(DBXContext);
    ConnectionBuilder.FInputConnectionName        := CombinedProperties[TDBXPropertyNames.ConnectionName];
    ConnectionBuilder.FInputConnectionProperties  := ConnectionProperties;
    ConnectionBuilder.FInputUserName              := CombinedProperties[TDBXPropertyNames.UserName];
    ConnectionBuilder.FInputPassword              := CombinedProperties[TDBXPropertyNames.Password];
    Result := ConnectionBuilder.CreateConnection;
    try
      Result.Open;
    except
      Result.Free;
      raise;
    end;
  finally
    ConnectionBuilder.Free;
  end;
end;


где TDBXConnectionFactory - singleton.
А выше в DoConnect:
Код: pascal
1.
2.
3.
4.
5.
6.
    ConnectionFactory.Lock;
    try
      FDBXConnection := ConnectionFactory.GetConnection(ConnectionProps);
    finally
      ConnectionFactory.Unlock;
    end;


не понимаю к чему такая реализация, почему бы не пытаться открывать конекшн отдельно от лока, ведь экземпляр уже создан и на фабрику открытие никак не должно влиять. Буду смотреть дальше
...
Рейтинг: 0 / 0
Datasnap client
    #39926860
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
RuslanSharipov
почему бы не пытаться открывать конекшн отдельно от лока
Я больше скажу, из приведенного участка кода лок нужен (если нужен) только для первых двух строк
...
Рейтинг: 0 / 0
Datasnap client
    #39926883
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если вы используете датаснапом автогенерируемые датамодули, ну или что-то подобное делаете сами, то...
Один экземпляр модуля = 1 подключение = 1 поток.
Если надо 10 потоков, то придется создавать 10 экземпляров дата модуля/коннекшенов и.т.п.
...
Рейтинг: 0 / 0
Datasnap client
    #39927288
RuslanSharipov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
X-Cite, без датамодулей. А так всё верно на каждый поток - свои экземпляры. Проблема именно в реализации создания datasnap connection, и обойти ее нет возможности. Еще и таймаутом подключения нельзя управлять, приходится вначале через TIdTcpClient пробовать открывать коннекшн со своим таймаутом, и если все ок уже переходить к созданию datasnap connection, чтобы избежать длительного лока. Лучше решения не придумал
...
Рейтинг: 0 / 0
11 сообщений из 11, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Datasnap client
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]