Jak ustawić timeout w żądaniu REST?

0

Cześć,

walczył ktoś z Was z timeoutem przy komunikacji REST?

Mam aplikację której jedna z funkcjonalności to klient REST. Serwer REST też jest mój. Wszystko działa dobrze.
Jednak zdarzyć się może (rzadko ale jednak) że tam gdzie jest serwer może nie być np. internetu.

Jako że łącza są szybkie a ilość danych mała do przesłania to pomyślałem że ustawie w kliencie niski timeout i nawet gdy nie będzie tej komunikacji to przecież można tą sekundę czy dwie poczekać (takie wyjątki mam oprogramowane).
No jednak jest chyba jakiś problem z ustawieniem tego czasu.

Gdy czas ustawiony jest np. na 10 sekund to próba połączenia trwa od 10,5 do 13,5 sekundy, za każdym razem różny czas.

Gdy ustawię 5 sekund to otrzymuję wyniki między 5,5 a 8,5 sekundy.

Gdy ustawię 2 sekundy (to by mi pasowało) to połączenie trwa od 2,5 do 5 sekund. Najczęściej około 3,5 sekundy.

Dlaczego tak się dzieje? Najlepsze że gdy robię testy wbudowanym RESTDebuggerem i tam ustawiam limit czasu to też jest to niestabilne?

Da się jakoś to naprawić?

3

Nawet nie sprawdzałem czy u mnie też tak jest ale wydaje mi się to możliwe,a nawet mam na to w miarę logiczne wytłumaczenie. Wg. mnie tak się dzieje, bo przed rozpoczęciem połączenia (a dopiero od tego czasu liczy się ConnectTimeout a w przypadku powodzenia później ReadTimeout) trzeba pobrać adres IP serwera (domyślam się że łączysz się po nazwie domeny) jeżeli jest internet to z serwera DNS lub z cache ale jak nie ma internetu to możliwe tylko i wyłącznie z cache a zarówno w przypadku pobrania go z DNS jak z cache zawsze to trochę zajmuje i ten czas przecież nie musi zawsze być jednakowy ale raczej to powinny być czasy < 1s. Jak to mierzysz? Do mierzenia wykorzystujesz TStopwatch? No chyba, że łączysz się po adresie IP?

0

Nie dość że łączę się po IP to dodatkowo było to nawet w tej samej sieci lub w ostateczności przez vpn-a. Ale zgadzam się z tym że jest coś na rzeczy bo pierwsze połączenie zawsze trwa dłużej.
Co do czasu, użyłem metody manualnej czyli zwykłego stopera w telefonie :)

1

To tak po pierwsze do zmierzenia czasu użyj TStopwatch po drugie łączysz się z wątku głównego czy tworzysz poboczny, bo jeżeli z głównego, który na czas łączenia przecież zostanie zamrożony to później apka musi przetworzyć całą kolejkę komunikatów, które się uzbierały i dopiero wtedy wyświetlić info, że nie udało się połączyć.

0

wiesz co, zrobiłem to tak na szybko dlatego te pomiary wykonałem w sposób tak mało profesjonalny.
Co do wątków, zastanawiałem się nawet nad wrzuceniem tej komunikacji do wątku pobocznego, tylko zawsze potem mam jakieś problemy, nie jestem w tym za dobry. Mam pytanie do znawców, zrobić to jednak normalnym wątkiem czy może wystarczy klasa TTask z biblioteki PPL?

A tak pobocznie, jestem trochę zdziwiony że taka funkcja jak RESTClient nie działa jednak sama z siebie w osobnym wątku, chyba takie komunikacje powinny tak działać? A może się mylę?

2

Co do wątku tu masz bardzo prosty przykład użycia https://gist.github.com/njmube/f61621e9a160e423996196217ce53b3b

0

Kiedyś miałem podobny problem z TFPHttpClient w Lazarusie, gdy użyłem ConnectTimeout. Po zmianie na IOTimeout wszystko działa jak należy.
Nie wiem czy jest odpowiednik z Delphi.

1 użytkowników online, w tym zalogowanych: 0, gości: 1