Workiva Scripting övervakar automatiskt de resurser som används av varje skriptkörning, inklusive minne, CPU, diskanvändning och körtid. När ett skript överskrider sina konfigurerade resursgränser försöker skriptet stoppa det på ett säkert sätt samtidigt som plattformens stabilitet bibehålls. Dessutom ger systemet skript tid att rensa upp och avslutas innan de stoppas helt, vilket säkerställer minimala störningar för användarna.
Den här artikeln förklarar hur skript hanterar avslutningsscenarier, vilka detaljer som visas i loggarna och innehåller referensskärmdumpar.
För mer information om alla systembegränsningar, se Workiva Scripting limits .
Scenarier
| Scenario | Beteende | Loggdetaljer |
| Mycket kort sikt | Lyckad körning | Ingen resursanvändningsdata registrerad |
| Normal slutförande | Lyckad körning | Fullständig resursanvändningssammanfattning loggad (om den inte är för kort för att samplas) |
| Överskrider minnesgränsen | Graciös uppsägning | Visar överskridet minneströskel, visar genomsnittlig och maximal användning |
| Överskrider diskgränsen | Graciös uppsägning | Visar överskriden disktröskel, visar genomsnittlig och maximal användning |
| Överskridande av tilldelad tid | Graciös uppsägning | Visar överskriden körtid och total använd tid |
| Manuell avbokning | Graciös uppsägning | Fullständig resursutgåva, resurssammanfattning loggad |
| Oväntad uppsägning | Obehaglig uppsägning | Delvis eller ofullständig användningsdata registrerad |
Genom att automatiskt tillämpa resursgränser och tillhandahålla detaljerade loggar (som visas på skärmdumparna nedan) säkerställer Workiva Scripting både plattformens tillförlitlighet och transparens för utvecklare som bygger och optimerar automatiseringsskript.
Avslutning när en körning slutförs utan problem
När ett skript slutförs normalt utan att överskrida gränser, innehåller loggen en sammanfattning av resursanvändning som visar genomsnittlig och maximal användning över minne, processor, disk och körningstid. Denna information ger insyn i prestandaegenskaper för framgångsrikt genomförda körningar.
Obs! Om ett skript körs mycket snabbt (till exempel mindre än en sekund) kanske resurssampling inte sker. I dessa fall kommer ingen resursanvändningsdata att rapporteras i loggen.
Skriptet körs för snabbt för att sampla
Om ett skript slutförs för snabbt kan övervakaren inte samla in användningsdata.
Skriptet har en normal utgång
Om ett skript slutförs utan att överskrida några gränser visas statistik över resursanvändning i sin helhet i loggen.
Uppsägning när gränser överskrids
Om en skriptkörning överskrider de konfigurerade gränserna (till exempel minne, diskanvändning eller allokerad tid) kommer skriptning att göra följande:
- Försök att stoppa skriptet på ett säkert sätt – När gränserna överskrids skickar skriptet först en avslutningssignal (SIGTERM) så att skriptet kan rensas och avslutas inom 15 sekunder.
- Om skriptet inte avslutas inom 15 sekunder skickar skriptet en SIGKILL-signal, som omedelbart stoppar processen utan att tillåta någon rensning. Detta är en tvångsmässig avslutning, och körningen kommer att slutföras med statusen misslyckad (visas i rött i loggen). Denna status indikerar att skriptet överskred en konfigurerad resursgräns och avslutades med tvång.
- Registrera orsaken till stopp – loggen visar vilken gräns som uppnåddes och sammanfattar skriptets resursanvändning.
Nästa avsnitt ger exempel på vad som händer när ett skript överskrider gränser utan kod för att hantera dessa signaler. Om du vill veta hur du modifierar dina skript så att de reagerar korrekt på dessa signaler kan du läsa Hantera systemsignaler i skript .
Minnesgränsen har överskridits
När ett skript överskrider den konfigurerade minnesgränsen innehåller loggen orsaken till avslutningen och information om det överskridna tröskelvärdet.
Diskanvändningsgränsen har överskridits
När ett skript överskrider den konfigurerade gränsen för diskanvändning innehåller loggen orsaken till avslutningen och information om diskanvändningen när gränsen nåddes.
Tilldelad tid överskriden
När ett skript överskrider sin konfigurerade tilldelade tid innehåller loggen orsaken till avslutningen och den totala registrerade körtiden.
Avslut när användaren avbryter en körning
Om en användare manuellt avbryter en körning skickar skriptet först en avbrottssignal (SIGINT) för att meddela skriptet att det ska stoppas. Skriptet har 15 sekunder på sig att rensa upp, spara förlopp eller återställa innan det stängs av. Efter denna 15-sekunders respitperiod sker samma sekvens som beskrivs ovan: en avslutningssignal (SIGTERM) skickas för att ge skriptet ytterligare 15 sekunder att slutföra rensningen, följt av en slutlig avstängningssignal (SIGKILL) om skriptet fortfarande inte har avslutats.
Bilden nedan visar hur skriptloggarna ser ut när ett skript inte innehåller kod för att hantera avbrottssignalen.
Om du vill veta hur du modifierar dina skript så att de reagerar korrekt på dessa signaler kan du läsa Hantera systemsignaler i skript .
Oplanerade uppsägningar
I sällsynta fall, till exempel när ett skript förbrukar minne snabbare än skriptsystemet kan övervaka förbrukningen, kan systemet avsluta ett skript innan det upptäcker att en gräns har överskridits. När detta händer loggar skriptet en ofullständig användningsrapport som endast visar de datapunkter som samlats in före avslutningen.
Hantera systemsignaler i skript
Signalhantering gör att ditt skript stängs snyggt när det avbryts eller stoppas av systemet. Genom att fånga upp och svara på systemsignaler kan ditt skript frigöra resurser, spara arbete och avslutas smidigt (till exempel när statusen rapporteras som "klar") istället för att avslutas med kraft.
När ett skript stoppas på grund av att en användare avbryter det eller överskrider plattformsgränserna, levererar skriptning avbrotts-, avslutande- och avstängningssignaler.Se de tidigare avsnitten för att lära dig mer om hur avbrotts-, avslutnings- och avstängningssignaler utlöses.
Skriptsignaler och hur man hanterar dem
Det här avsnittet innehåller kodblock och ett komplett exempel som du kan använda för att hantera dessa signaler.
Du kan hålla dina signalhanterare små och hantera rensningen på ett ställe med hjälp av ett try/finally -block som alltid körs vid avstängning. Detta gör skripten förutsägbara och enkla att underhålla.
Den övergripande strukturen för hantering av signaler i ditt skript är densamma oavsett vilken signal som tas emot:
- Överst i filen: importera moduler och definiera hanteraren
- Tidig initialisering: registrera hanteraren innan något arbete utförs
- Runt ditt arbete: linda in huvudkoden i ett
try/finally-block så att rensningen alltid körs
Användaren avbryter körningen (SIGINT)
Detta inträffar när en användare klickar på Avbryt för att avbryta skriptkörningen.
# --- Överst i filen --- importsignal, sys # Liten hanterare: begär omedelbar, elegant avslutning def _graceful_exit(signum, frame): print("SIGINT mottagen: avbrytning begärd. Rensar upp…") höjer SystemExit(0) # --- Tidig initialisering --- signal.signal(signal.SIGINT, _graceful_exit)
Runt ditt arbete (senare i filen):
try: # ditt långvariga arbete här ... finally: # central plats för att stänga filer, rensa loggar etc. print("Slutlig rengöring före avslutning")
Bilden nedan visar hur skriptloggarna ser ut när avbrottssignalen (SIGINT) hanteras.
Hantera KeyboardInterrupt direkt
Workiva Scripting utlöser också KeyboardInterrupt när SIGINT levereras till huvudtråden. Du kan upptäcka detta undantag i ditt try- block och anropa samma rensningssökväg som definieras av _graceful_exit() .
try: # ditt långvariga arbete här ... except KeyboardInterrupt: print("KeyboardInterrupt mottaget: rensning före avslutning…") _graceful_exit(None, None) finally: # central plats för att stänga filer, rensa loggar etc. print("Slutlig rensning före avslutning")
Bilden nedan visar hur skriptloggarna ser ut när avbrottssignalen hanteras via tangentbordsavbrott.
Skriptavslutningssignal för att stoppa efter en respitperiod (SIGTERM)
Skripting ber ditt skript att stoppa (t.ex. efter att gränser har överskridits). Ditt skript har en kort respitperiod för att avslutas.
# --- Överst i filen --- importsignal def _graceful_term(signum, frame): print("SIGTERM mottagen: plattform begärde avslutning. Avslutar…") höja SystemExit(0) # --- Tidig initialisering --- signal.signal(signal.SIGTERM, _graceful_term)
Bilden nedan visar hur skriptloggarna ser ut när avslutningssignalen (SIGTERM) hanteras.
Skriptar kill-signal för att stoppa omedelbart (SIGKILL)
Om ditt skript inte avslutas under respitperioden skickar skriptet SIGKILL.Du kan inte fånga SIGKILL. Avsluta omedelbart på SIGINT/SIGTERM så att ditt finally- block kan köras innan en kill sker.
Skärmdumparna i de tidigare avsnitten visar hur loggarna skulle se ut som ett resultat av kill-signalen.
Komplett exempel (färdigt att kopiera och klistra in)
Den här mallen registrerar minimala hanterare och centraliserar rensning i finally . Klistra in i Workiva Scripting och ersätt det markerade området med din logik.
Var du ska lägga till din kod: Ersätt exempelloopen under # ===== DIN KOD BÖRJAR HÄR ===== med dina faktiska uppgifter. Undvik mycket långa avbrottsfria anrop så att skriptet kan nå finally -blocket innan plattformen eskalerar till SIGKILL.
"""Workiva skriptmall: minimala hanterare + rensning i finally - Små hanterare höjer SystemExit(0) på SIGINT/SIGTERM - Enstaka finally-block körs för rensning oavsett hur skriptet stoppas - Håller koden liten och förutsägbar """ importsignal importtid # --- Signalhanterare (keep tiny) --- def _graceful_exit(signum, frame): print("SIGINT mottagen: avbokning begärd. Städar upp…") höja SystemExit(0) def _graceful_term(signum, frame): print("SIGTERM mottagen: plattform begärde avslutning. Slutför…") höj SystemExit(0) # --- Registrera hanterare INNAN du utför något tungt arbete --- signal.signal(signal.SIGINT, _graceful_exit) signal.signal(signal.SIGTERM, _graceful_term) # --- Ditt skripts huvudsakliga arbete --- def main(): print("Börjar arbeta…") # ===== DIN KOD BÖRJAR HÄR ===== # Exempel på långvarig loop. Ersätt med din faktiska logik. for i in range(1, 1_000_000): # Simulera en arbetsenhet (ersätt med verklig logik) print(f"Arbetar med objekt {i}…") time.sleep(1) # ===== DIN KOD SLUTAR HÄR ===== if __name__ == "__main__": try: main() finally: # Centraliserad rensning som alltid körs (inklusive på SIGINT/SIGTERM) print("Slutlig rensning före avslutning")