Конференция "Базы" » Обработка подключения когда недоступен удаленный сервер БД. [D7, FIB+FB2.0]
 
  • 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 может и лучше, его пожалуй и оставлю.
  • Johnmen © (09.11.08 02:45) [10]
    45, 45...
    Магическое число от белкина...
    :)))
  • clickmaker © (10.11.08 12:29) [11]
    > А каким образом убивать поток

    вот это - WaitForSingleObject - его само убьет
 
Конференция "Базы" » Обработка подключения когда недоступен удаленный сервер БД. [D7, FIB+FB2.0]
Есть новые Нет новых   [134477   +39][b:0][p:0.001]