15 gru 2025·7 min czytania

Zapobieganie przerywaniu eksportów: zadania asynchroniczne, postęp i strumieniowanie

Zapobiegaj timeoutom eksportu dzięki asynchronicznym zadaniom eksportu, wskaźnikom postępu, stronicowaniu i strumieniowym pobraniom dla dużych raportów CSV i PDF.

Zapobieganie przerywaniu eksportów: zadania asynchroniczne, postęp i strumieniowanie

Dlaczego eksporty się przerywają – prosto\n\nEksport przerywa się, gdy serwer nie kończy pracy przed wyznaczonym limitem. Ten limit może być ustawiony przez przeglądarkę, reverse proxy, serwer aplikacji lub połączenie z bazą danych. Dla użytkowników często wygląda to losowo, bo czasem eksport działa, a czasem pada.\n\nNa ekranie zwykle widzisz jedno z tych zachowań:\n\n- Spinner, który nigdy się nie kończy\n- Pobieranie, które zaczyna się, a potem kończy błędem "network error"\n- Strona błędu po długim oczekiwaniu\n- Plik, który się pobiera, ale jest pusty lub uszkodzony\n\nDuże eksporty są stresujące, bo jednocześnie obciążają wiele części systemu. Baza danych musi znaleźć i złożyć mnóstwo wierszy. Serwer aplikacji musi je sformatować do CSV lub wyrenderować jako PDF. Potem przeglądarka musi odebrać dużą odpowiedź bez zerwania połączenia.\n\nOgromne zestawy danych to oczywisty wyzwalacz, ale "małe" eksporty też potrafią być ciężkie. Kosztowne joiny, wiele pól obliczanych, zapytania per-wiersz i źle zaindeksowane filtry mogą zamienić normalny raport w timeout. PDF-y są szczególnie ryzykowne, bo wymagają layoutu, fontów, obrazów, podziału na strony i często dodatkowych zapytań po powiązane dane.\n\nPonawianie żądań zwykle pogarsza sprawę. Kiedy użytkownik odświeża stronę lub klika Eksport ponownie, system może zacząć tę samą pracę dwa razy. Teraz baza wykonuje zdublowane zapytania, serwer buduje duplikaty plików i masz skok obciążenia w momencie, gdy system już ledwo daje radę.\n\nJeśli chcesz zapobiegać przerwanym eksportom, traktuj eksport jako zadanie w tle, a nie zwykłe ładowanie strony. Nawet w narzędziu typu no-code jak AppMaster wzorzec ma większe znaczenie niż narzędzie: długa praca wymaga innego flow niż „kliknij przycisk, poczekaj na odpowiedź”.\n\n## Wybierz właściwy wzorzec eksportu dla swojej aplikacji\n\nWiększość awarii eksportów bierze się stąd, że aplikacja używa jednego wzorca do wszystkiego, nawet gdy rozmiar danych i czas przetwarzania bardzo się różnią.\n\nProsty, synchroniczny eksport (użytkownik klika, serwer generuje, rozpoczyna się pobieranie) jest w porządku, gdy eksport jest mały i przewidywalny. Myśl o kilku setkach wierszy, podstawowych kolumnach, bez ciężkiego formatowania i niezbyt wielu użytkownikach równocześnie. Jeśli zwykle kończy się w kilka sekund, prostota często jest najlepsza.\n\nDla wszystkiego, co długie lub nieprzewidywalne, użyj asynchronicznych zadań eksportu. To pasuje do dużych zestawów danych, złożonych obliczeń, pracy nad layoutem PDF i współdzielonych serwerów, gdzie jeden wolny eksport może blokować inne żądania.\n\nZadania asynchroniczne są lepszym wyborem, gdy:\n\n- Eksport regularnie trwa dłużej niż 10–15 sekund\n- Użytkownicy proszą o szerokie zakresy dat lub "all time"\n- Generujesz PDF-y z wykresami, obrazami lub wieloma stronami\n- Kilka zespołów eksportuje w godzinach szczytu\n- Potrzebujesz bezpiecznych retry po błędzie\n\nStrumieniowe pobieranie też pomaga, gdy eksport jest duży, ale można go produkować sekwencyjnie. Serwer zaczyna wysyłać bajty od razu, co daje wrażenie szybkości i unika budowania całego pliku w pamięci. To świetne dla długich CSV, ale mniej przydatne, jeśli musisz najpierw wszystko policzyć, zanim zapiszesz pierwszy wiersz.\n\nMożesz łączyć podejścia: uruchom zadanie asynchroniczne, które wygeneruje eksport (lub przygotuje snapshot), a potem strumieniuj pobieranie, gdy plik będzie gotowy. W AppMaster praktyczne podejście to utworzenie rekordu "Export Requested", wygenerowanie pliku w backendowym Business Process i pozwolenie użytkownikowi na pobranie gotowego wyniku bez trzymania otwartego żądania przeglądarki.\n\n## Krok po kroku: zbuduj asynchroniczne zadanie eksportu\n\nNajwiększa zmiana jest prosta: przestań generować plik w tym samym żądaniu, w którym użytkownik klika.\n\nZadanie asynchroniczne dzieli pracę na dwie części: szybkie żądanie tworzące zadanie oraz tło, które buduje plik, podczas gdy aplikacja pozostaje responsywna.\n\n### Praktyczny 5-etapowy flow\n\n1. Zbierz żądanie eksportu (kto prosi, filtry, wybrane kolumny, format wyjścia).\n2. Stwórz rekord zadania z statusami (queued, running, done, failed), znacznikami czasu i polem błędu.\n3. Uruchom ciężką pracę w tle przy użyciu kolejki, zaplanowanego workera lub dedykowanego procesu worker.\n4. Zapisz wynik w storage (object storage lub file store), a następnie zapisz referencję do pobrania w rekordzie zadania.\n5. Powiadom użytkownika, gdy będzie gotowe, przez powiadomienie w aplikacji, maila lub kanał komunikacji, którego zespół już używa.\n\nTrzymaj rekord zadania jako źródło prawdy. Jeśli użytkownik odświeży, zmieni urządzenie lub zamknie kartę, nadal możesz pokazać ten sam status zadania i ten sam przycisk pobierania.\n\nPrzykład: kierownik wsparcia eksportuje wszystkie tickety za ostatni kwartał. Zamiast czekać na wiszącą zakładkę, widzi jak wpis zadania przechodzi z queued do done, a potem pojawia się pobieranie. W AppMaster możesz wymodelować tabelę zadań w Data Designer, zbudować logikę w Business Process Editor i użyć pola statusu do sterowania stanem UI.\n\n## Wskaźniki postępu, którym użytkownicy naprawdę ufają\n\nDobry wskaźnik postępu zmniejsza niepokój i powstrzymuje ludzi od klikania Eksport pięć razy. Pośrednio pomaga też unikać timeoutów, bo użytkownicy chętniej poczekają, gdy aplikacja pokazuje realny postęp.\n\nPokaż postęp w kategoriach zrozumiałych dla ludzi. Sam procent bywa mylący, więc połącz go z czymś konkretnym:\n\n- Bieżący krok (Przygotowanie danych, Pobieranie wierszy, Budowanie pliku, Wgrywanie, Gotowe)\n- Liczba przetworzonych wierszy na tle całkowitej (lub przetworzonych stron)\n- Czas rozpoczęcia i ostatniej aktualizacji\n- Szacowany pozostały czas (tylko jeśli jest względnie stabilny)\n\nUnikaj fałszywej precyzji. Jeśli nie znasz jeszcze całkowitej ilości pracy, nie pokazuj 73%. Użyj kamieni milowych najpierw, a potem przejdź do procentów, gdy znasz mianownik. Prosty wzorzec: 0%–10% na konfigurację, 10%–90% na podstawie przetworzonych wierszy i 90%–100% na finalizację pliku. Dla PDF-ów z niestabilną liczbą stron śledź mniejsze prawdy, jak "wyrenderowane rekordy" lub "ukończone sekcje".\n\nAktualizuj wystarczająco często, by interfejs „żył”, ale nie tak często, żeby nadużywać bazy danych lub kolejki. Typowe podejście to zapisywanie postępu co 1–3 sekundy lub co N rekordów (np. co 500 lub 1 000 wierszy), w zależności co rzadziej. Dodatkowo zapisuj lekkie heartbeat timestamp, żeby UI mogło pokazać "Nadal pracuje", nawet gdy procent stoi.\n\nDaj użytkownikom kontrolę, gdy trwa za długo. Pozwól anulować działający eksport, uruchomić nowy bez utraty pierwszego i przeglądać historię eksportów ze statusami (Queued, Running, Failed, Ready) oraz krótkim komunikatem o błędzie.\n\nW AppMaster typowy rekord to ExportJob (status, processed_count, total_count, step, updated_at). UI pollingowo pobiera ten rekord i pokazuje uczciwy postęp, podczas gdy asynchroniczne zadanie generuje plik w tle.\n\n## Stronicowanie i filtrowanie, aby ograniczyć pracę\n\nWiększość timeoutów wynika z próby zrobienia wszystkiego naraz: za dużo wierszy, kolumn, joinów. Najszybsza poprawka to ograniczyć pracę, by użytkownicy eksportowali mniejszy, jasny wycinek danych.\n\nZacznij od celu użytkownika. Jeśli ktoś potrzebuje "faktury z ostatniego miesiąca, które nie przeszły", nie ustawiaj domyślnie "wszystkie faktury kiedykolwiek". Spraw, żeby filtry były normalne, nie uciążliwe. Prosty zakres dat plus kluczowy filtr statusu często zmniejszy zbiór danych o 90%.\n\nDobre pole żądania eksportu zwykle zawiera zakres dat (sensowne domyślne: ostatnie 7 lub 30 dni), jeden lub dwa kluczowe statusy, opcjonalne wyszukiwanie lub wybór klienta/zespołu oraz podgląd liczby wyników, jeśli to możliwe (nawet szacunkowy).\n\nPo stronie serwera czytaj dane kawałkami używając paginacji. To utrzymuje pamięć stabilną i daje naturalne checkpointy do raportowania postępu. Zawsze używaj stabilnego porządku przy stronicowaniu (np. sortuj po created_at, potem id). Bez tego nowe wiersze mogą wślizgnąć się do wcześniejszych stron i pominiesz lub zdublujesz rekordy.\n\nDane zmieniają się podczas długich eksportów, więc zdecyduj, co znaczy "spójne". Proste podejście to zapisać snapshot time przy starcie zadania i eksportować tylko wiersze do tego momentu. Jeśli potrzebujesz ścisłej spójności, użyj consistent read lub transakcji, jeśli baza to wspiera.\n\nW narzędziu no-code jak AppMaster mapuje się to czysto do Business Process: waliduj filtry, ustaw snapshot time, a potem iteruj przez strony, aż nie będzie nic do pobrania.\n\n## Strumieniowe pobieranie bez przeciążania serwera\n\nStrumieniowanie znaczy, że zaczynasz wysyłać plik do użytkownika, podczas gdy jeszcze go generujesz. Serwer nie musi budować całego CSV czy PDF w pamięci najpierw. To jedno z najbardziej niezawodnych rozwiązań zapobiegających timeoutom przy dużych plikach.\n\nStrumieniowanie nie sprawi, że wolne zapytania staną się szybkie. Jeśli praca w bazie zajmuje pięć minut zanim pojawi się pierwszy bajt, żądanie nadal może przekroczyć limit. Zwykle naprawa to połączenie strumieniowania ze stronicowaniem: pobierz kawałek, zapisz go, wypisz i kontynuuj.\n\nAby utrzymać niskie użycie pamięci, zapisuj w miarę postępu. Generuj jedną partię (np. 1 000 wierszy CSV lub jedną stronę PDF), zapisz ją do odpowiedzi, a potem flush, żeby klient dalej odbierał dane. Unikaj zbierania wierszy do dużej tablicy "żeby później posortować". Jeśli potrzebujesz stabilnego porządku, sortuj w bazie.\n\n### Nagłówki, nazwy i typy treści\n\nUstaw jasne nagłówki, żeby przeglądarki i aplikacje mobilne poprawnie traktowały plik. Ustaw właściwy content type (np. text/csv lub application/pdf) i bezpieczną nazwę pliku. Nazwy plików unikaj znaków specjalnych, trzymaj krótko i dodaj timestamp, jeśli użytkownicy eksportują ten sam raport wielokrotnie.\n\n### Wznawianie i częściowe pobierania\n\nZdecyduj wcześniej, czy wspierasz resume. Podstawowe strumieniowanie często nie obsługuje byte-range resume, szczególnie dla generowanych PDF-ów. Jeśli to wspierasz, musisz obsłużyć żądania Range i generować spójne wyjście dla tego samego zadania.\n\nZanim wdrożysz, upewnij się, że:\n\n- Wysyłasz nagłówki przed pisaniem body, potem zapisujesz kawałkami i flushujesz\n- Trzymasz stały rozmiar kawałków, by pamięć pozostała płaska pod obciążeniem\n- Używasz deterministycznego sortowania, by użytkownicy ufali wynikowi\n- Dokumentujesz, czy resume jest wspierane i co się dzieje, gdy połączenie padnie\n- Dodajesz limity po stronie serwera (max rows, max time) i zwracasz przyjazny błąd, gdy je przekroczysz\n\nJeśli budujesz eksporty w AppMaster, trzymaj logikę generacji w backendowym flow i strumieniuj po stronie serwera, nie z przeglądarki.\n\n## Duże eksporty CSV: praktyczne taktyki\n\nDla dużych CSV przestań traktować plik jak jeden blob. Buduj go w pętli: czytaj kawałek danych, zapisuj wiersze, powtarzaj. To utrzymuje pamięć na stałym poziomie i ułatwia retry.\n\nZapisuj wiersz CSV po wierszu. Nawet jeśli generujesz eksport w asynchronicznym zadaniu, unikaj "zbierz wszystkie wiersze, potem zstringify'uj". Trzymaj otwarty writer i dołączaj każdy wiersz, gdy tylko jest gotowy. Jeśli stos jest w stanie to obsłużyć, użyj kursora bazy danych lub stronicuj wyniki, żeby nigdy nie załadować milionów rekordów naraz.\n\nPoprawność CSV jest równie ważna jak szybkość. Plik może wyglądać dobrze, dopóki ktoś nie otworzy go w Excelu i połowa kolumn się nie przesunie.\n\n### Zasady CSV zapobiegające uszkodzeniom plików\n\n- Zawsze escapuj przecinki, cudzysłowy i nowe linie (opakuj pole w cudzysłów i podwajaj każdy cudzysłów wewnątrz)\n- Wyjście w UTF-8 i testuj nieanglojęzyczne imiona end-to-end\n- Utrzymuj stabilny wiersz nagłówka i stałą kolejność kolumn między uruchomieniami\n- Normalizuj daty i wartości dziesiętne (wybierz jeden format i trzymaj się go)\n- Unikaj formuł jeśli dane mogą zaczynać się od =, +, - lub @\n\nWydajność często umiera na dostępie do danych, nie na zapisywaniu. Uważaj na N+1 lookupy (np. ładowanie klienta w pętli). Pobierz powiązane dane jednym zapytaniem lub prefetchuj, czego potrzebujesz, a potem zapisuj wiersze.\n\nGdy eksporty są naprawdę ogromne, podziel je celowo. Praktyczne podejście to jeden plik na miesiąc, klienta lub typ encji. Eksport "5 lat zamówień" może stać się 60 miesięcznymi plikami, każdy generowany niezależnie, więc jeden wolny miesiąc nie blokuje wszystkiego.\n\nW AppMaster modeluj dataset w Data Designer i uruchamiaj eksport jako backendowy Business Process, zapisując wiersze podczas stronicowania rekordów.\n\n## Duże eksporty PDF: utrzymuj je przewidywalnymi\n\nGenerowanie PDF jest zwykle wolniejsze niż CSV, bo jest intensywne CPU. Nie tylko przesuwasz dane, lecz układasz strony, ustawiasz fonty, rysujesz tabele i często zmieniasz rozmiar obrazów. Traktuj PDF jako zadanie w tle z jasnymi limitami, a nie szybkie żądanie.\n\nWybór szablonu decyduje, czy eksport z 2 minut stanie się 20-minutowym. Proste layouty wygrywają: mniej kolumn, mniej zagnieżdżonych tabel i przewidywalne podziały stron. Obrazy szybko spowalniają wszystko, zwłaszcza jeśli są duże, w wysokiej rozdzielczości lub pobierane zdalnie podczas renderowania.\n\nDecyzje szablonowe, które zwykle poprawiają szybkość i niezawodność:\n\n- Używaj jednej lub dwóch czcionek i unikaj ciężkich łańcuchów fallback\n- Trzymaj nagłówki i stopki proste (unikaj dynamicznych wykresów na każdej stronie)\n- Wybieraj ikony wektorowe zamiast dużych rastrowych obrazów\n- Ogranicz układy "auto fit", które mierzą tekst wielokrotnie\n- Unikaj złożonej przezroczystości i cieni\n\nDla dużych eksportów renderuj partiami. Generuj jedną sekcję lub mały zakres stron na raz, zapisz do tymczasowego pliku, a potem dopiero sklej finalny PDF. To utrzymuje pamięć stabilną i ułatwia retry, jeśli worker padnie w połowie. Dobrze współgra to z asynchronicznymi zadaniami i postępem, który idzie w sensownych krokach (np. "Przygotowywanie danych", "Renderowanie stron 1–50", "Finalizacja pliku").\n\nZastanów się też, czy PDF jest faktycznie potrzebny. Jeśli użytkownicy głównie potrzebują wierszy i kolumn do analizy, zaoferuj CSV obok "Export PDF". Możesz też generować mniejszy PDF podsumowujący, a pełny zestaw danych trzymać w CSV.\n\nW AppMaster pasuje to naturalnie: uruchom generowanie PDF jako job w tle, raportuj postęp i dostarcz gotowy plik jako pobranie po zakończeniu zadania.\n\n## Najczęstsze błędy prowadzące do timeoutów\n\nAwarii eksportów zwykle nie trzeba długo szukać. Kilka decyzji działa z 200 wierszami, a przy 200 000 się rozsypuje.\n\nNajczęstsze błędy:\n\n- Uruchamianie całego eksportu w jednym żądaniu webowym. Przeglądarka czeka, worker serwera jest zajęty, i każde wolne zapytanie lub duży plik przekracza limity czasu.\n- Pokazywanie postępu opartego na czasie zamiast na wykonanej pracy. Timer, który pędzi do 90% i potem stoi, skłania użytkowników do odświeżania, anulowania lub ponownego uruchomienia eksportu.\n- Wczytywanie wszystkich wierszy do pamięci przed zapisem pliku. Proste do wdrożenia, a szybka droga do przekroczenia pamięci.\n- Trzymanie długich transakcji w bazie lub ignorowanie blokad. Zapytania eksportowe mogą blokować zapisy lub być blokowane przez zapisy, a spowolnienie rozlewa się na całą aplikację.\n- Pozwalanie na nieograniczone eksporty bez sprzątania. Powtarzane kliknięcia piętrzą zadania, zapełniają storage i zostawiają stare pliki na wieki.\n\nKonkretny przykład: kierownik wsparcia eksportuje wszystkie tickety z ostatnich dwóch lat i klika dwa razy, bo nic się nie dzieje. Teraz dwa identyczne eksporty konkurują o tę samą bazę, oba budują ogromne pliki w pamięci i oba kończą się timeoutem.\n\nJeśli budujesz to w narzędziu no-code jak AppMaster, te same zasady obowiązują: trzymaj eksporty poza ścieżką żądania, śledź postęp po przetworzonych wierszach, zapisuj output na bieżąco i wprowadź proste limity ile eksportów użytkownik może uruchomić jednocześnie.\n\n## Szybkie kontrole przed wdrożeniem\n\nZanim wydasz funkcję eksportu do produkcji, zrób szybką kontrolę z mindsetem "nie blokuj żądania". Długa praca poza żądaniem, użytkownicy widzą uczciwy postęp, a serwer nigdy nie próbuje zrobić wszystkiego naraz.\n\nKrótka lista kontrolna przed startem:\n\n- Duże eksporty działają jako background jobs (małe mogą być synchroniczne, jeśli zawsze kończą szybko)\n- Użytkownicy widzą jasne stany: queued, running, done lub failed, z znacznikami czasu\n- Dane czytane są w kawałkach ze stabilnym sortowaniem (np. created_at + id)\n- Gotowe pliki można pobrać później bez ponownego uruchamiania eksportu, nawet jeśli użytkownik zamknie kartę\n- Są limity i plan sprzątania starych plików i historii zadań (usuwanie według wieku, maks jobs na użytkownika, limity storage)\n\nDobry sanity check to zrobić najgorszy przypadek: eksportuj największy dopuszczalny zakres dat, gdy ktoś inny aktywnie dodaje rekordy. Jeśli widzisz duplikaty, brakujące wiersze lub zablokowany postęp, oznacza to, że sortowanie lub chunking nie jest stabilny.\n\nW AppMaster te kontrole mapują się na realne elementy: background process w Business Process Editor, rekord zadania w bazie i pole statusu, które UI czyta i odświeża.\n\nSpraw, by porażka była bezpieczna. Nieudane zadanie powinno zachować komunikat o błędzie, pozwalać na retry i unikać tworzenia częściowych plików, które wyglądają jak "gotowe", ale są niekompletne.\n\n## Przykład: eksport lat danych bez zamrażania aplikacji\n\nKierownik operacji potrzebuje dwa eksporty co miesiąc: CSV z ostatnich 2 lat zamówień do analizy oraz zestaw miesięcznych faktur w PDF dla księgowości. Jeśli aplikacja próbuje zbudować którykolwiek z nich w normalnym żądaniu webowym, prędzej czy później trafisz na limity czasu.\n\nZacznij od ograniczenia pracy. Ekran eksportu pyta o zakres dat (domyślnie: ostatnie 30 dni), opcjonalne filtry (status, region, opiekun sprzedaży) i jasny wybór kolumn. Ta jedna zmiana często zmienia problem 2 lat i 2 milionów wierszy w coś wykonalnego.\n\nGdy użytkownik klika Eksport, aplikacja tworzy rekord Export Job (type, filters, requested_by, status, progress, error_text) i wrzuca go do kolejki. W AppMaster to model w Data Designer i Business Process, który działa w tle.\n\nW trakcie działania zadania UI pokazuje status, któremu można ufać: queued, processing (np. 3 z 20 chunków), generating file, ready (przycisk pobierania) lub failed (krótki błąd i opcja retry).\n\nChunking to kluczowy detal. Zadanie CSV czyta zamówienia po stronach (np. 50 000 naraz), zapisuje każdą stronę do outputu i aktualizuje postęp po każdym kawałku. Zadanie PDF robi to samo per batch faktur (np. jeden miesiąc na raz), żeby jeden wolny miesiąc nie blokował wszystkiego.\n\nJeśli coś się wysypie (zły filtr, brak uprawnień, błąd storage), zadanie oznaczane jest jako Failed z krótkim komunikatem, który użytkownik może zrozumieć: "Nie udało się wygenerować faktur za marzec. Spróbuj ponownie lub skontaktuj się z support z Job ID 8F21." Retry używa tych samych filtrów, więc użytkownik nie musi zaczynać od zera.\n\n## Następne kroki: traktuj eksporty jak funkcję, nie jak alarm pożarowy\n\nNajszybsza droga, by długoterminowo zapobiegać timeoutom, to przestać traktować eksporty jak jednorazowy przycisk i uczynić je standardową funkcją z powtarzalnym wzorcem.\n\nWybierz domyślne podejście i stosuj je wszędzie: asynchroniczne zadanie generuje plik w tle, a użytkownik dostaje opcję pobrania, gdy będzie gotowe. Ta jedna decyzja eliminuje większość "działało w testach" niespodzianek, bo żądanie użytkownika nie musi czekać na cały plik.\n\nUłatw ludziom znalezienie tego, co już wygenerowali. Strona historii eksportów (dla użytkownika, workspace lub konta) zmniejsza powtórne eksporty, pomaga zespołom wsparcia odpowiadać "gdzie jest mój plik?" i daje naturalne miejsce na pokazanie statusu, błędów i wygaśnięć.\n\nJeśli budujesz ten wzorzec w AppMaster, pomaga fakt, że platforma generuje realny kod źródłowy i wspiera logikę backendu, modelowanie bazy i UI web/mobilne w jednym miejscu. Zespoły, które chcą szybko wdrożyć niezawodne asynchroniczne zadania eksportu, często używają appmaster.io do stworzenia tabeli zadań, procesu w tle i UI postępu bez ręcznego składania wszystkiego od zera.\n\nPotem mierz to, co naprawdę boli. Śledź wolne zapytania do bazy, czas generowania CSV i czas renderu PDF. Nie potrzebujesz perfekcyjnej obserwowalności na start: logowanie czasu trwania i liczby wierszy na eksport szybko pokaże, który raport lub kombinacja filtrów jest prawdziwym problemem.\n\nTraktuj eksporty jak każdą inną funkcję produktu: spójną, mierzalną i łatwą do wsparcia.

FAQ

Dlaczego eksporty przerywają się nawet gdy czasami działają?

Eksport przerywa się, gdy praca nie zakończy się przed limitem czasu ustawionym gdzieś na ścieżce żądania. Ten limit może pochodzić od przeglądarki, reverse proxy, serwera aplikacji lub połączenia z bazą danych, więc czasem wygląda to losowo, nawet gdy przyczyną są ciągłe obciążenia lub wolne zapytania.

Kiedy prosty „klik i pobierz” jest w porządku, a kiedy powinienem użyć zadań asynchronicznych?

Używaj prostego, synchronicznego eksportu tylko wtedy, gdy zawsze kończy się w kilka sekund i rozmiar danych jest przewidywalny. Jeśli eksporty często trwają dłużej niż 10–15 sekund, obejmują duże zakresy dat, ciężkie obliczenia lub PDF-y, przejdź na zadanie asynchroniczne, żeby żądanie przeglądarki nie musiało pozostawać otwarte.

Jaki jest najprostszy asynchroniczny flow eksportu, jaki mogę zaimplementować w AppMaster?

Najprostszy wzorzec to: najpierw utwórz rekord zadania, potem wykonaj ciężką pracę w tle, a na końcu pozwól użytkownikowi pobrać gotowy plik. W AppMaster typowa konfiguracja to model ExportJob w Data Designerze i backendowy Business Process, który aktualizuje status, pola postępu i referencję do zapisanego pliku podczas działania.

Jak pokazać postęp, któremu użytkownicy naprawdę zaufają?

Mierz prawdziwą pracę, a nie upływający czas. Praktyczne rozwiązanie to przechowywanie pól takich jak step, processed_count, total_count (gdy znane) oraz updated_at, a UI niech okresowo pobiera te wartości i pokazuje jasne zmiany stanu, żeby użytkownicy nie czuli się zablokowani i nie spamowali przycisku eksportu.

Jak powstrzymać użytkowników przed uruchamianiem tego samego eksportu wiele razy?

Zrób żądanie eksportu idempotentnym i traktuj rekord zadania jako źródło prawdy. Jeśli użytkownik kliknie ponownie, pokaż istniejące uruchomione zadanie (lub blokuj duplikaty dla tych samych filtrów) zamiast uruchamiać tę samą kosztowną pracę drugi raz.

Jaki jest najbezpieczniejszy sposób stronicowania danych przy dużych eksportach?

Czytaj i zapisuj w kawałkach, aby pamięć pozostała płaska i żeby mieć naturalne punkty kontrolne. Używaj stabilnej stronicacji z deterministycznym sortowaniem (np. created_at, a potem id), żeby nie pomijać i nie duplikować wierszy, gdy dane zmieniają się w trakcie długiego eksportu.

Jak utrzymać spójność eksportów, jeśli dane zmieniają się podczas działania zadania?

Zapisz czas snapshotu przy starcie zadania i eksportuj tylko wiersze do tego znacznika czasu, aby wynik nie „ruszał się” w trakcie pracy. Jeśli potrzebujesz silniejszej spójności, użyj spójnych odczytów lub transakcji, które wspiera twoja baza, ale na początek prosta reguła snapshotu jest najbardziej praktyczna.

Czy strumieniowe pobieranie samo w sobie zapobiega timeoutom?

Strumieniowanie pomaga, gdy możesz produkować wyjście w kolejności i zacząć wysyłać bajty wcześnie, szczególnie dla dużych CSV. Nie naprawi to jednak wolnych zapytań, które trwają minuty zanim pojawi się pierwszy bajt — w takim przypadku może nadal wystąpić timeout. Najlepiej łączyć strumieniowanie ze stronicowaniem, które na bieżąco zapisuje kawałki.

Jakie są najczęstsze przyczyny uszkodzonych lub wolnych eksportów CSV?

Zapisuj wiersze na bieżąco i stosuj ścisłe escapowanie CSV, aby plik nie rozpadł się w Excelu czy innych narzędziach. Utrzymuj spójne kodowanie (zwykle UTF-8), stały nagłówek i kolejność kolumn oraz unikaj zapytań typu N+1, które zamieniają jeden eksport w tysiące dodatkowych zapytań.

Dlaczego eksporty PDF częściej się nie udają niż CSV i jak je uczynić bardziej niezawodnymi?

Generowanie PDF jest cięższe, bo obejmuje layout, fonty, obrazy i dzielenie na strony — dlatego częściej się nie udaje. Traktuj PDF jako zadanie w tle z jasno określonymi limitami. Upraszczaj szablony, unikaj dużych zdalnych obrazów w czasie renderowania i raportuj postęp w sensownych krokach, żeby użytkownik wiedział, że praca postępuje.

Łatwy do uruchomienia
Stworzyć coś niesamowitego

Eksperymentuj z AppMaster z darmowym planem.
Kiedy będziesz gotowy, możesz wybrać odpowiednią subskrypcję.

Rozpocznij
Zapobieganie przerywaniu eksportów: zadania asynchroniczne, postęp i strumieniowanie | AppMaster