Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Datasnap client / 11 сообщений из 11, страница 1 из 1
12.02.2020, 15:42
    #39925776
RuslanSharipov
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Datasnap client
Добрый день. На нескольких хостах развернут сервер реализованный через datasnap. На клиенте мне нужно параллельно обращаться к каждому из серверов. Но складывается ощущение что в один момент времени клиент может открыть только одно соединение, и не важно что подключения создаются и осуществляются каждый в своем потоке, потому что как только один из хостов недоступен остальные потоки(TTask) "зависают" и в них просто ничего не происходит пока неработающий хост не прервется по таймауту. Вопрос:
действительно ли это так?возможно нужно выставить какой-то параметр у SQLConnection?или такой проблемы вообще нет и видимо ошибка где то в коде?
...
Рейтинг: 0 / 0
12.02.2020, 16:00
    #39925796
Sinemurius
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Datasnap client
Я предполагаю, что Ваш клиент уже в значительной степени написан, там много кода и его сложно использовать для отладки. Это так ?
...
Рейтинг: 0 / 0
12.02.2020, 16:23
    #39925827
RuslanSharipov
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Datasnap client
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
12.02.2020, 18:20
    #39925933
Sinemurius
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Datasnap client
А не используете Synchronize или что-то в этом роде ?

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

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


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