Jak wyłapać przerwanie połączenia do API

Jak wyłapać przerwanie połączenia do API
AdamWox
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Jastrzębie-Zdrój
  • Postów: 2180
0

Witam.
Mam pewien problem u klienta z rozłączaniem się do API. Tak mi się wydaje, że to to może być problemem, ponieważ jest dość specyficzny.

OPIS SYTUACJI
Aplikacja we Flutterze. Co jakiś interwał wysyła zapisane w urządzeniu dokumenty na serwer (NET 5 WebAPI + Comarch Optima). Użytkownik tworzy dokument, zapisuje w cache (Hive) z odpowiednią flagą (confirmed) i usługa w tle wyłapuje takie dokumenty i wysyła.

PROBLEM
Aplikacja jest w stanie wysłać dane. API jest w stanie te dane zapisać, dokument widnieje w Optimie ale nie potrafi wysłać do aplikacji potwierdzenia i aplikacja twierdzi, że się nie powiodło zapisywanie i próbuje za jakiś czas znowu. Takim sposobem mam ten sam dokument dodany 27 razy (przykład z dzisiaj, były inne przypadki na mniejszą skalę).

PYTANIA
Czy i jak jestem w stanie wyłapać takie przypadki? Zrobienie ifa na sprawdzanie czy taki dokument już istnieje jest średnim rozwiązaniem, ponieważ aplikacja nie dostanie odpowiedzi, że istnieje i będzie cały czas próbować mimo iż duplikacji już nie będzie. Czy to jest kwestia neta? Udało mi się zasymulować to u siebie tylko wyłączając/włączając WiFi. Dokument już dawno jest w systemie ale nie wysłał info o poprawnym dodaniu więc aplikacja wyśle go jeszcze raz. Wygląda to tak jakby udało się zrobić request ale response już nie dochodzi.

PS
Drążę ten temat, ponieważ wydaje mi się, że to nie jest kwestia oprogramowania. Nie dzieje się tak cały czas. Jestem w stanie to pewnie jakoś oprogramowaniem obsłużyć ale chyba nie bardzo wiem jak stąd ten post.

cerrato
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Poznań
  • Postów: 9024
1

Czy to WebAPI to Twój produkt/możesz w tym grzebać, czy doczepiasz się do gotowego rozwiązania?

AdamWox
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Jastrzębie-Zdrój
  • Postów: 2180
0

Tak mój, mogę grzebać

cerrato
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Poznań
  • Postów: 9024
0

OK. Czy dobrze zrozumiałem:
wysyłka danych z aplikacji działa bezproblemowo, a jedynie kłopotem jest komunikacja zwrotna - czyli API nie umie odesłać do mobilki informacji, że dany wpis został już dodany, przez co apka bombarduje API w kółko tą samą fakturą/dokumentem?
Nie masz żadnego systemu wysyłania potwierdzeń?

Takim sposobem mam ten sam dokument dodany 27 razy (przykład z dzisiaj, były inne przypadki na mniejszą skalę).

A co się stało później, że na 27 się skończyło? Czemu w końcu apka przestała wysyłać ten dokument, a nie spamowała nim w nieskończoność? Chyba jednak jest jakaś komunikacja zwrotna.

AdamWox
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Jastrzębie-Zdrój
  • Postów: 2180
0

OK. Czy dobrze zrozumiałem:
wysyłka danych z aplikacji działa bezproblemowo, a jedynie kłopotem jest komunikacja zwrotna - czyli API nie umie odesłać do mobilki informacji, że dany wpis został już dodany, przez co apka bombarduje API w kółko tą samą fakturą/dokumentem?
Nie masz żadnego systemu wysyłania potwierdzeń?

Potwierdzeniem jest response z API, na podstawie którego mobilka wie, że ma ukryć/usunąć dokument z cache i pobrać już ten zapisany z systemu ERP. To wszystko się dzieje w tle, tego nie robi użytkownik. Mobilka jest w stanie wysłać dokument, API go jest w stanie zapisać, ale response już nie dociera.

A co się stało później, że na 27 się skończyło? Czemu w końcu apka przestała wysyłać ten dokument, a nie spamowała nim w nieskończoność? Chyba jednak jest jakaś komunikacja zwrotna.

W tym przypadku przerwało, ponieważ na szybko "wcisnąłem" tam ifa, który sprawdza po numerze obcym (numer nadany przez mobilkę) czy taki dokument jest już w ERP. To jest tymczasowe rozwiązanie. Zaznaczam, że działo się tak już wcześniej (jeszcze bez poprawki z ifem) i w którymś momencie przestał dublować i już nie było powtórek. Można założyć, że prędzej czy później przestanie i dojdzie do mobilki response z potwierdzeniem ale nie wiem kiedy i to właśnie chce jakoś obsłużyć, wyłapać.

#EDIT
Oczywiście nie dzieje się to zawsze. Jest czterech przedstawicieli, a po numerach widzę, że na tę chwilę ten problem występuje tylko u dwóch. Parę dni działa dobrze, jeden dzień kilka zdublowanych, kilka "normalnych". Nie ma to w ogóle sensu.

cerrato
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Poznań
  • Postów: 9024
3

response już nie dociera.

A jakby mobilka nie czekała pasywnie na odpowiedź (bo tutaj jest ryzyko, że API wyśle odpowiedź, która gdzieś przepadnie i mamy problem), tylko miała jakąś listę dokumentów wysłanych, a co jakiś czas odpytywała serwer o ich stan? (pisząc serwer mam na myśli API czy to coś, z czym mobilka się bezpośrednio komunikuje)

prędzej czy później przestanie i dojdzie do mobilki response z potwierdzeniem ale nie wiem kiedy i to właśnie chce jakoś obsłużyć, wyłapać.

Dodatkowo dałbym do każdego wysyłanego dokumentu z mobilki jakieś UID. I nawet jak mobilka nie załapie, że dany dokument został dodany i będzie 1000 razy wysyłać tą samą informację, to nie będziesz miał duplikatów - bo serwer zobaczy, że żądanie dodania dokumentu o określonym ID (ID żądania, a nie dokumentu) już zostało obsłużone, więc kolejne żądania z takim ID będą ignorowane.

Nawet jak komunikacja chwilowo się zamuli, to mobilka będzie sobie spamować API takimi samymi żądaniami, ale serwer je zignoruje i nie powstaną duplikaty.

Ponadto - niech mobilka odpytuje co kilka/kilkanaście sekund API z pytaniem, czy ID które ma na liście zostało obsłużone. Jeśli dostanie odpowiedź, że ten ID został przetworzony to wywala go ze swojej kolejki i więcej nie przesyła do serwera. A jeśli nie dostanie takiej odpowiedzi, to niech wysyła ponownie, do skutku.

AdamWox
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Jastrzębie-Zdrój
  • Postów: 2180
0

Jest to rozwiązanie i teoretycznie powinno tak działać od razu request ==> response, wtedy nie trzeba się bawić w takie sprawdzanie. Tylko jaką mogę mieć pewność, że odpytując API o listę wysłanych dokumentów dostane odpowiedź? Nie będzie się to tak samo zachowywało? Wtedy będzie bardzo dużo razy odpytywał czy już takie dokumenty wysłał i nigdy ich nie wyśle, bo nie dostanie odpowiedzi.

Czy tylko dla mnie wydaje się to dziwne? Mam nawet bibliotekę do sprawdzania stanu połączenia z netem i jakby go nie było to by nie przeszedł dalej z dodawaniem dokumentu. A to wygląda tak, jakby mobilka mogła wysłać ale blokowane jest odbieranie i to też nie występuje u każdego.

Wcześniej takiego problemu nie udało się wyłapać, ponieważ ustalone było z klientem, aby jak najwięcej rzeczy było "offline". Kontrahenci, towary i dokumenty są cache'owane podczas pierwszego logowania i później już tylko jest wysyłka dokumentów online, a tak to wszystko jest brane z cache, aby taki przedstawiciel mógł zrobić zamówienie w "bunkrze" gdzie nie ma neta.

GH
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 811
1

Co to znaczy, że "aplikacja twierdzi"? Timeout - nie przyszła odpowiedź? Serwer zwrócił błąd? A co w logach serwera jest? Odesłał odpowiedź?

Taka sytuacja nie powinna występować, raczej problemu bym szukał na serwerze.

AdamWox
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Jastrzębie-Zdrój
  • Postów: 2180
0

Wszystko by wskazywało na to, że mimo iż po stronie mobilki mam try/catch to wali wyjątkiem, a dokument zostaje poprawnie zapisany w systemie ERP.

Kopiuj
        var response = await apiService.post("insertnewdocument", document);
        if (response.statusCode == 200) {
          // Oznacz dokument jako wysłany w cache
        } else {
          // Próbuj aż do skutku = generuje duplikaty, bo API wykonało swoje zdanie, ale nie zwróciło response albo zwróciło z błędem
          // To jest tutaj jakby API rzuciło jakiś błąd. Wtedy reagujemy na to co ma w logach i poprawiamy jeśli trzeba.
        }

Taka sytuacja nie powinna występować, raczej problemu bym szukał na serwerze.

Logi nic nie mówią, bo przecież tam się nic nie "psuje". Dokument dodany poprawnie do systemu ERP. Przykładem jest 27 razy te same zamówienia z dzisiaj. Z jakiś powodów API odebrało dane, wykonało swoje zadanie, ale nie poinformowało o tym mobilki i dokument (w mobilce) dalej widnieje z flagą "do zrealizowania" i wysyła tak w kółko.

Dzisiaj cały dzień robiłem "crash testy", aby chociaż raz wywołać taką sytuacje. Miałem odpaloną apkę na swoim tel, na emulatorze i na tablecie. Klepałem różnego rodzaju dokumenty nawet takie z dużą ilością pozycji i nic. Fakt faktem testowałem to w laboratoryjnych warunkach, miałem stały i pewny dostęp do internetu. Dopiero jak zacząłem się bawić gwałceniem guzika WiFi to byłem w stanie zreplikować "błędne" zachowanie.

Mój błąd logiczny? Może. Chce to naprawić ale nie bardzo wiem jak, a już tym bardziej gdzie szukać problemu.

GH
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 811
2

No ale zaraz. Wali wyjątkiem. Jakim? Najpierw to ustal co się dzieje. Jakiego klienta http używasz? Dio czy domyślnego?

Masz try/catch i nie przechwycił wyjątku? To jakoś dziwnie brzmi. Najpierw zobacz co to za wyjątek/stacktrace. Jakieś crashlytics by się przydało, ale najlepiej powtórzyć to u siebie.

AdamWox
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Jastrzębie-Zdrój
  • Postów: 2180
0

Ale to nie ma znaczenia. Przecież napisałem, że wyłączam internet, bo tylko wtedy dzieje się tak jak klient opisuje. Więc wyjątkiem jest timeout, connection lost, jakkolwiek to się zowie, nie pamiętam, nie mam tego przed sobą. Nie mam wyjątku z tableta przedstawiciela. Nie wiem co się u niego dzieje. Serwer (API) też nie ma żadnych błędów. Jedyny punkt zaczepienia to zrywanie połączenia z internetem, albo blokowanie response z jakiegoś powodu.

Używam Dio.

GH
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 811
3

Ja bym jednak starał się dociec, co dokładnie dzieje się u klienta, jakie wyjątki lecą, a jednocześnie bym podwyższył poziom logowania na serwerze, żeby dokładnie widzieć co serwer odesłał i czy na pewno odesłał. Równie dobrze możesz mieć jakiś bug w api i raz na 100 000 razy nie odsyłasz statusu klientowi, a dokument dodajesz. Albo odsyłasz, tylko z jakimś lagiem, bo gdzieś coś się zakleszczyło albo baza danych zamuliła.

Ale tak naprawdę w przypadku, gdyby to było rzeczywiście kwestią zrywania połączenia rozwiązanie jest proste. Aplikacja niech sobie ponawia do czasu, aż dostanie prawidłowy status, ale serwer powinien zauważyć, że dostaje duplikat i zamiast go dodawać kolejny raz, zwrócić ponownie status, że dokument dodano.

Tutaj wystarczy, żeby klient generował losowy guid dla każdego nowego dokumentu, który by się nie zmieniał w przypadku ponawiania próby, a tylko w przypadku całkiem nowego żądania. Wtedy serwer będzie wiedział, że aplikacja ponawia wysyłanie i nie będzie wrzucał duplikatów, tylko ponownie zwracał status, który w końcu by dotarł i aplikacja przestałaby ponawiać próby.

AdamWox
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Jastrzębie-Zdrój
  • Postów: 2180
0

Czyli podobnie co @cerrato pisał. Twoja propozycja wydaje się być szybsza do zrealizowania. Raczej nie chciałbym się bawić w guid i trzymanie tego gdzieś dodatkowo w tel i jeszcze dopisywanie obsługi po stronie API. Sprawdzę w API czy dokument istnieje po jego numerze "obcym" i zwrócę odpowiedź w takiej samej postaci jakbym dodał (nowy) dokument. Na tę chwilę chce to zrobić po linii najmniejszego oporu.

PS.
Nie mam niczego po stronie klienta, ponieważ, szczerze mówiąc, mnie nie interesuje dlaczego nie wysłał. Wstępnie są dwie opcje - nie ma neta, nie oflagował dokumentu "do zrealizowania" - i żadnej innej opcji nie brałem pod uwagę. Najważniejsze dla mnie było czy dokument się dodał do ERP i tutaj mam logi i jak najwięcej kroków staram się śledzić. Ale w tym przypadku to nie jest kwestia serwera.

GH
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 811
1

Ale po co masz coś trzymać w mobilce? Generuj losowy guid tylko, za każdym razem inny. Guid zapisze się na serwerze. Chyba, że obawiasz się kolizji, tj że guid nie będzie losowy. Ale to raczej się nie zdarzy, a dodatkowo możesz sprawdzać cały zestaw, czyli czy powtarza się guid i wartości pozostałych pól, jeżeli tak, to jest kolejna próba.

Albo klient może ustawiać flagę, czy ponawia czy przesyła pierwszy raz. Jeżeli ponawia to sprawdzasz na serwerze, czy dokument już jest (dodał się jednak) i zwracasz status, a jak się nie dodał to dodajesz i zwracasz status.

siloam
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 99
0

Jedyny punkt zaczepienia to zrywanie połączenia z internetem, albo blokowanie response z jakiegoś powodu

Znaczy plik się przesyła i apka zrywa połączenie, że nie dostaje odpowiedzi? To bardzo mało prawdopodobne.
Osobiście bym to odrzucił na starcie.

Więc wyjątkiem jest timeout, connection lost, jakkolwiek to się zowie

Masz timeout? Czyli Twój serwer odpowiada zbyt wolno. Rozwiązaniem jest tak jak pisali koledzy - sprawdzanie osobnym requestem czy plik zapisał się poprawnie.

Ps. Logi na kliencie i serwerze to podstawa.

GH
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 811
3

Wydaje mi się, że kolega nie chce poświęcać za dużo czasu na rozwiązanie problemu u źródła i że nieco na wyrost założył, że problemem nie jest serwer.

Pewnie głupie bombardowanie żądaniami i ponawianie do skutku ukryje ten problem, ale pewnie to tylko do czasu. Też uważam, że blokowanie response jest bardzo mało prawdopodobne. W przypadku problemów z jakością sieci w ogóle by nie dotarł request

AdamWox
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Jastrzębie-Zdrój
  • Postów: 2180
0

A co jeśli operacja wykonuje się na tyle "długo", że request wyjdzie, a response już nie? Ja sobie zdaje właśnie sprawę z tego, że to mało prawdopodobne dlatego tutaj napisałem żeby się upewnić. To co się dzieje na mobilkach i to co się dzieje na serwerze wskazuje, że to jest to "mało prawdopodobne".

@siloam

Ps. Logi na kliencie i serwerze to podstawa.

Czy podstawa, czy nie to na kliencie logi mi nie są potrzebne. Musiałbym pisać cały system powiadamiania, zapisywania, wysyłania do mnie tej treści, a ona nie jest mi potrzebna. A użytkownika powiadomić o błędzie w tle nie mogę, bo zaraz będą telefony - "nie działa", "co mam z tym zrobić", "po co to jest"... Tak jak pisałem wyżej, mam tylko dwie opcje - nie wysłał, bo brak neta, nie wysłał, bo nie oflagował dokumentu "do zrealizowania". To co się teraz dzieje jest dziwne i nie powinno mieć miejsca.

GH
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 811
2
AdamWox napisał(a):

A co jeśli operacja wykonuje się na tyle "długo", że request wyjdzie, a response już nie?

To znaczy, że masz problem na serwerze, chociaż twierdziłeś że na pewno nie. To w takim razie loguj na serwerze po jakim czasie odsyłasz response.

AdamWox napisał(a):

Czy podstawa, czy nie to na kliencie logi mi nie są potrzebne.

No właśnie widać jak niepotrzebne.

AdamWox napisał(a):

Musiałbym pisać cały system powiadamiania, zapisywania, wysyłania do mnie tej treści, a ona nie jest mi potrzebna.

Nieprawda, są na to gotowe rozwiązania jak np Crashlytics. Jeśli coś u klienta się wywaliło, to stacktrace powinien być zawsze u ciebie.

JP
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 1065
1

Ja w podobnym problemie (nie na mobilach) dodaję jakiś GUID wygenerowany przez klienta (u Ciebie Mobile) i zapisuję ten GUID w atrybucie dokumentu w Optimie.
Jeśli coś spowoduje ponowne wysłanie dokumentu to API sprawdzi czy nie ma już dokumentu z takim atrybutem GUID. U mnie powody były zupełnie inne ale wydaje mi się to dość proste i działa tylko. To obejście, ale działa :)

Jeśli API przetwarza długo i dostaniesz na mobilu timeout to chyba nic z tym nie zrobisz bo API w końcu to skończy przetwarzać i zechce cos odesłać ale już nie ma komu.
Miałem tak z XL API (jeśli można tę bibliotekę XL-a nazwać API). Timeout na 60 sekund i czasem nie wystarcza.

AdamWox
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Jastrzębie-Zdrój
  • Postów: 2180
0

Ha! Mówiłem, że to nie powinno mieć miejsca? 😎
HttpException: Connection closed while receiving data

JP
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 1065
0

:) IMO i tak trzeba kontrolować w API jakimś GUID-em czy taki dokument już nie istnieje.

HE
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 2
0

Niby kontrolować wGuidem ale to nie takie proste...

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.