-
Aristarh © (06.11.08 16:40) [0]В самом общем случае подключение к БД происходит так:
procedure TDataModule1.DataModuleCreate(Sender: TObject);
begin
with TIniFile.Create('ini file') do
try
pFIBDatabase1.DBName := ReadString('DB', 'path', '');
pFIBDatabase1.ConnectParams.UserName := ReadString('DB', 'username', '');
pFIBDatabase1.ConnectParams.Password := ReadString('DB', 'password', '');
finally
Free;
end; // try
try
pFIBDatabase1.Open;
except
...
end;
end;
Проблема или правильнее сказать "неудобство" возникает тогда, когда не удается по сети подключиться к удаленной машине-серверу. В этом случае программа висит на строчке pFIBDatabase1.Open секунд 45 и только после истечения этого промежутка генерирует исключение и входит в обработчик except.
Для себя я не вижу необходимости ждать аж 45 сек., когда с головой достаточно, например, 5-ти сек., чтобы понять доступна ли удаленная БД.
Вопрос. Как правильно обрабатывать ситуацию, чтобы долго не ждать подключения в случае недоступности удаленного сервера. -
Anatoly Podgoretsky © (06.11.08 16:41) [1]> Aristarh (06.11.2008 16:40:00) [0]
Поток с таймаутом ожидания 5 секунд -
Виталий Панасенко (07.11.08 09:30) [2]firebird.conf
# ----------------------------
# Client Connection Settings (Basic)
#
# Seconds to wait before concluding an attempt to connect has failed.
#
# Type: integer
#
#ConnectionTimeout = 180 -
DSKalugin (07.11.08 09:59) [3]>Виталий Панасенко
firebird сервер недоступен, а клиентское ПО не хочет ждать ответа недоступен 45 сек
Т.е. бесполезно что-либо править в конфиге выключенного сервера -
clickmaker © (07.11.08 10:17) [4]а у самого pFIBDatabase1 нет каких-либо свойств, управляющих таймаутом?
-
Aristarh (07.11.08 12:18) [5]>Виталий Панасенко (07.11.08 09:30) [2]
Это совсем не то, хоть на первый взгляд и кажется настройками клиента.
>clickmaker © (07.11.08 10:17) [4]
Если такой параметр и есть, то мне он неизвестен. Если же открыть исходник TpFIBDatabase1 и найти место непосредственного вызова функции подключения FirebirdAPI, то в этом месте ничего не говорит о каком-либо механизме ограничения времени ожидания:
(*
* Attach to the database, and raise an IB error if
* the statement doesn't execute correctly.
*)
SV:=StatusVector;
isc_res:=Call(FClientLibrary.isc_attach_database(SV, Length(FDBName),
PChar(FDBName), @FHandle,
FDPBLength, FDPB), False);
if isc_res > 0 then
begin
FHandle := nil;
IbError(Self,Self);
end;
>Anatoly Podgoretsky © (06.11.08 16:41) [1]
>Поток с таймаутом ожидания 5 секунд
Не совсем понимаю как это может помочь... Ну вызовем мы в теле потока ту же самую команду pFIBDatabase1.Open; и что? Поток точно также будет ждать 45 секунд на этой строчке. -
clickmaker © (07.11.08 12:41) [6]> Не совсем понимаю как это может помочь
что-то типа
Thread.Resume;
WaitForSingleObject(Thread.Handle, 5000); -
Aristarh (07.11.08 16:56) [7]Решил задачу следующим простым способом. Предварительно подключаюсь телнетом к серверу БД. Если соединение прошло успешно, тогда можно подключаться и компонентой pFIBDatabase.
(IdTelnet - из набора Indy)
try
IdTelnet.Connect(2000);
if IdTelnet.Connected then begin
IdTelnet.Disconnect;
pFIBDatabase1.Open;
end;
except
.....
end;
Насколько корректен такой способ и какие могут быть подводные камни?
>clickmaker © (07.11.08 12:41) [6]
>что-то типа
>Thread.Resume;
>WaitForSingleObject(Thread.Handle, 5000);
А каким образом убивать поток, в котором происходит попытка подключения и который мертво висит 45 секунд? -
DSKalugin (07.11.08 17:05) [8]а порт в телнете какой указан? 23????
почему не IdTCPClient? -
Aristarh (07.11.08 17:14) [9]>DSKalugin (07.11.08 17:05) [8]
Ну разумеется порт не 23))
IdTCPClient может и лучше, его пожалуй и оставлю. -
45, 45...
Магическое число от белкина...
:))) -
clickmaker © (10.11.08 12:29) [11]> А каким образом убивать поток
вот это - WaitForSingleObject - его само убьет