Workiva Scripting automatycznie monitoruje zasoby wykorzystywane przez każde uruchomienie skryptu, w tym pamięć, procesor, użycie dysku i czas działania. Gdy skrypt przekroczy skonfigurowane limity zasobów, Scripting próbuje go bezpiecznie zatrzymać, zachowując stabilność platformy. Ponadto, system daje skryptom czas na wyczyszczenie i zamknięcie przed ich całkowitym zatrzymaniem, zapewniając minimalne zakłócenia dla użytkowników.
W tym artykule wyjaśniono, w jaki sposób Scripting obsługuje scenariusze zakończenia, jakie szczegóły pojawiają się w dziennikach i zawiera referencyjne zrzuty ekranu.
Aby uzyskać szczegółowe informacje na temat wszystkich limitów systemowych, zobacz Workiva Scripting limits.
Scenariusze
| Scenariusz | Zachowanie | Szczegóły dziennika |
| Bardzo krótki czas trwania | Udany bieg | Brak zarejestrowanych danych dotyczących wykorzystania zasobów |
| Normalne zakończenie | Udany bieg | Rejestrowane jest pełne podsumowanie wykorzystania zasobów (chyba że jest zbyt krótkie, aby pobrać próbkę) |
| Przekroczenie limitu pamięci | Łaskawe zakończenie | Wyświetla przekroczony próg pamięci, pokazuje średnie i szczytowe użycie |
| Przekroczenie limitu dysku | Łaskawe zakończenie | Wyświetla przekroczony próg dysku, pokazuje średnie i szczytowe użycie |
| Przekroczenie przydzielonego czasu | Łaskawe zakończenie | Wyświetla przekroczony czas działania i całkowity wykorzystany czas |
| Ręczne anulowanie | Łaskawe zakończenie | Pełne zwolnienie zasobów, podsumowanie zasobów zarejestrowane |
| Nieoczekiwane zakończenie | Niewdzięczne zakończenie | Zarejestrowane częściowe lub niekompletne dane użytkowania |
Poprzez automatyczne egzekwowanie limitów zasobów i dostarczanie szczegółowych dzienników (jak pokazano na poniższych zrzutach ekranu), Workiva Scripting zapewnia zarówno niezawodność platformy, jak i przejrzystość dla programistów tworzących i optymalizujących skrypty automatyzacji.
Zakończenie, gdy uruchomienie zakończy się pomyślnie
Gdy skrypt zakończy się normalnie bez przekroczenia limitów, dziennik zawiera podsumowanie wykorzystania zasobów pokazujące średnie i szczytowe wykorzystanie pamięci, procesora, dysku i czasu wykonania. Informacje te zapewniają wgląd w charakterystykę wydajności dla pomyślnie ukończonych przebiegów.
Uwaga: Jeśli skrypt działa bardzo szybko (na przykład krócej niż 1 sekundę), próbkowanie zasobów może nie zostać przeprowadzone. W takich przypadkach w dzienniku nie będą zgłaszane żadne dane dotyczące wykorzystania zasobów.
Skrypt działa zbyt szybko, aby pobrać próbkę
Jeśli skrypt kończy się zbyt szybko, monitor nie może przechwycić danych użytkowania.
Skrypt ma normalne wyjście
Jeśli skrypt zostanie ukończony bez przekroczenia jakichkolwiek limitów, statystyki wykorzystania zasobów są w pełni wyświetlane w dzienniku.
Zakończenie po przekroczeniu limitów
Jeśli uruchomiony skrypt przekroczy skonfigurowane limity (na przykład pamięci, użycia dysku lub przydzielonego czasu), funkcja Scripting to zrobi:
- Próba bezpiecznego zatrzymania skryptu - gdy limity zostaną przekroczone, Scripting najpierw wysyła sygnał zakończenia (SIGTERM), aby umożliwić skryptowi wyczyszczenie i wyjście w ciągu 15 sekund.
- Jeśli skrypt nie zakończy działania w ciągu 15 sekund, funkcja Scripting wysyła sygnał SIGKILL, który natychmiast zatrzymuje proces, nie pozwalając na jego wyczyszczenie. Jest to wymuszone zakończenie, a uruchomienie zakończy się niepowodzeniem (wyświetlanym na czerwono w dzienniku). Ten status wskazuje na błąd systemu skryptów.
- Zapisz powód zatrzymania - dziennik pokaże, który limit został osiągnięty i podsumuje wykorzystanie zasobów skryptu.
Następne sekcje zawierają przykłady tego, co dzieje się, gdy skrypt przekracza limity bez kodu do obsługi tych sygnałów. Aby dowiedzieć się, jak zmodyfikować skrypty, aby reagowały na te sygnały z wdziękiem, zobacz Obsługa sygnałów systemowych w skryptach.
Przekroczono limit pamięci
Gdy skrypt przekroczy skonfigurowany limit pamięci, dziennik zawiera przyczynę zakończenia i szczegóły dotyczące przekroczonego progu.
Przekroczono limit użycia dysku
Gdy skrypt przekroczy skonfigurowany limit użycia dysku, dziennik zawiera powód zakończenia i szczegóły dotyczące użycia dysku w momencie osiągnięcia limitu.
Przydzielony czas został przekroczony
Gdy skrypt przekroczy skonfigurowany przydzielony czas, dziennik zawiera przyczynę zakończenia i całkowity zarejestrowany czas działania.
Zakończenie, gdy użytkownik anuluje uruchomienie
Jeśli użytkownik ręcznie anuluje uruchomienie, Scripting najpierw wysyła sygnał przerwania (SIGINT), aby poinformować skrypt, że powinien się zatrzymać. Skrypt ma 15 sekund na wyczyszczenie, zapisanie postępu lub wycofanie się przed zamknięciem. Po tym 15-sekundowym okresie karencji następuje ta sama sekwencja opisana powyżej: wysyłany jest sygnał zakończenia (SIGTERM), aby umożliwić skryptowi zakończenie czyszczenia przez kolejne 15 sekund, a następnie ostateczny sygnał zabicia (SIGKILL), jeśli skrypt nadal nie zakończył działania.
Poniższy obrazek pokazuje, jak wyglądają dzienniki skryptu, gdy skrypt nie zawiera kodu do obsługi sygnału przerwania.
Aby dowiedzieć się, jak zmodyfikować skrypty, aby reagowały na te sygnały z wdziękiem, zobacz Obsługa sygnałów systemowych w skryptach.
Nieplanowane zakończenia
W rzadkich przypadkach, takich jak gdy skrypt zużywa pamięć szybciej niż system skryptowy może monitorować zużycie, system może zakończyć skrypt przed wykryciem przekroczenia limitu. W takim przypadku Scripting rejestruje niekompletny raport użycia, pokazujący tylko punkty danych zebrane przed zakończeniem.
Obsługa sygnałów systemowych w skryptach
Obsługa sygnałów umożliwia czyste zamknięcie skryptu, gdy zostanie on anulowany lub zatrzymany przez system. Dzięki wychwytywaniu sygnałów systemowych i reagowaniu na nie, twój skrypt może zwolnić zasoby, zapisać pracę i wyjść z wdziękiem (na przykład, gdy status zostanie zgłoszony jako "kompletny") zamiast zostać przymusowo zakończony.
Gdy skrypt zostanie zatrzymany z powodu anulowania go przez użytkownika lub przekroczenia limitów platformy, Scripting dostarcza sygnały przerwania, zakończenia i zabicia. Zobacz wcześniejsze sekcje, aby dowiedzieć się więcej o tym, jak wyzwalane są sygnały przerwania, zakończenia i zabicia.
Sygnały skryptowe i sposób ich obsługi
Ta sekcja zawiera bloki kodu i kompletny przykład, których możesz użyć do obsługi tych sygnałów.
Możesz zachować małe programy obsługi sygnałów i obsługiwać czyszczenie w jednym miejscu za pomocą bloku try/finally, który zawsze działa podczas zamykania. Dzięki temu skrypty są przewidywalne i łatwe w utrzymaniu.
Ogólna struktura obsługi sygnałów w twoim skrypcie jest taka sama, niezależnie od tego, który sygnał jest odbierany:
- Na początku pliku: zaimportuj moduły i zdefiniuj obsługę
- Wczesna inicjalizacja: zarejestruj obsługę przed wykonaniem jakiejkolwiek pracy
- Wokół twojej pracy: zawiń główny kod w blok
try/finally, aby czyszczenie zawsze działało
Użytkownik anuluje uruchomienie (SIGINT)
Dzieje się tak, gdy użytkownik kliknie Cancel, aby anulować uruchamianie skryptu.
# --- Top of file --- import signal, sys # Tiny handler: request immediate, graceful exit def _graceful_exit(signum, frame): print("SIGINT received: cancellation requested. Czyszczenie...") raise SystemExit(0) # --- Wczesna inicjalizacja --- signal.signal(signal.SIGINT, _graceful_exit) Otocz swoją pracę (w dalszej części pliku):
spróbuj: # Twoja długotrwała praca tutaj ... w końcu: # centralne miejsce do zamykania plików, opróżniania logów itp. print("Końcowe czyszczenie przed wyjściem") Poniższy obrazek pokazuje, jak wyglądają dzienniki skryptu, gdy obsługiwany jest sygnał przerwania (SIGINT).
Bezpośrednia obsługa KeyboardInterrupt
Workiva Scripting podnosi również KeyboardInterrupt, gdy SIGINT jest dostarczany do głównego wątku. Możesz wychwycić ten wyjątek w bloku try i wywołać tę samą ścieżkę czyszczenia zdefiniowaną przez _graceful_exit().
try: # twoja długotrwała praca tutaj ... except KeyboardInterrupt: print("KeyboardInterrupt received: cleaning up before exit...") _graceful_exit(None, None) finally: # centralne miejsce do zamykania plików, opróżniania logów itp. print("Końcowe czyszczenie przed wyjściem") Poniższy obrazek pokazuje, jak wyglądają logi skryptu, gdy sygnał przerwania jest obsługiwany przez przerwanie klawiatury.
Sygnał zakończenia skryptu do zatrzymania po okresie karencji (SIGTERM)
Skrypty proszą o zatrzymanie skryptu (np. po przekroczeniu limitów). Twój skrypt ma krótki okres karencji na wyjście.
# --- Top of file --- def _graceful_term(signum, frame): print("SIGTERM received: platform requested termination. Finishing up...") raise SystemExit(0) # --- Wczesna inicjalizacja --- signal.signal(signal.SIGTERM, _graceful_term) Poniższy obrazek pokazuje, jak wyglądają logi skryptu, gdy obsługiwany jest sygnał zakończenia (SIGTERM).
Sygnał zabicia skryptu do natychmiastowego zatrzymania (SIGKILL)
Jeśli twój skrypt nie zakończy działania w okresie karencji, Scripting wyśle SIGKILL. Nie możesz złapać SIGKILL. Wyjdź szybko na SIGINT/SIGTERM, aby twój blok finally mógł zostać uruchomiony przed wystąpieniem zabójstwa.
Zrzuty ekranu we wcześniejszych sekcjach pokazują, jak wyglądałyby dzienniki w wyniku sygnału zabicia.
Kompletny przykład (gotowy do kopiuj-wklej)
Szablon ten rejestruje minimalne programy obsługi i centralizuje czyszczenie w finally. Wklej do Workiva Scripting i zastąp zaznaczony obszar swoją logiką.
Gdzie dodać swój kod: Zastąp przykładową pętlę pod # ===== TWÓJ KOD ZACZYNA SIĘ TUTAJ ===== swoimi rzeczywistymi zadaniami. Unikaj bardzo długich nieprzerwanych wywołań, aby skrypt mógł trafić do bloku finally, zanim platforma eskaluje do SIGKILL.
"""Szablon skryptu Workiva: minimalna obsługa + czyszczenie w finally - Malutkie obsługi podnoszą SystemExit(0) na SIGINT/SIGTERM - Pojedynczy blok finally działa do czyszczenia niezależnie od tego, jak skrypt się zatrzymuje - Utrzymuje kod mały i przewidywalny """ import signal import time # --- Obsługa sygnałów (zachowaj malutkie) --- def _graceful_exit(signum, frame): print("Otrzymano SIGINT: zażądano anulowania. Czyszczenie...") raise SystemExit(0) def _graceful_term(signum, frame): print("Otrzymano SIGTERM: platforma zażądała zakończenia. Finishing up...") raise SystemExit(0) # --- Register handlers BEFORE doing any heavy work --- signal.signal(signal.SIGINT, _graceful_exit) signal.signal(signal.SIGTERM, _graceful_term) # --- Your script's main work --- def main(): print("Starting work...") # ===== YOUR CODE STARTS HERE ===== # Example long-running loop. Zastąp swoją rzeczywistą logiką. for i in range(1, 1_000_000): # Simulate a unit of work (replace with real logic) print(f "Working on item {i}...") time.sleep(1) # ===== YOUR CODE ENDS HERE ===== if __name__ == "__main__": try: main() finally: # scentralizowane czyszczenie, które zawsze działa (w tym na SIGINT/SIGTERM) print("Końcowe czyszczenie przed wyjściem")