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 Scripting stoppa det på ett säkert sätt samtidigt som plattformens stabilitet bibehålls. Dessutom ger systemet skripten tid att rensa upp och avsluta innan de stoppas helt, vilket ger minimala störningar för användarna.
Den här artikeln förklarar hur Scripting hanterar avslutningsscenarier, vilka detaljer som visas i loggarna och innehåller referensskärmdumpar.
För mer information om alla systemgränser, se Workiva Scripting-gränser.
Scenarier
| Scenario | Beteende | Loggdetaljer |
| Mycket kort löptid | Framgångsrik körning | Inga uppgifter om resursanvändning registreras |
| Normal avslutning | Framgångsrik körning | Fullständig sammanfattning av resursanvändningen loggas (om den inte är för kort för att provas) |
| Överskrider minnesgräns | Skicklig avslutning | Visar tröskelvärde för minne som överskridits, visar genomsnittlig och maximal användning |
| Diskgränsen överskrids | Skicklig avslutning | Visar överskridna disktrösklar, visar genomsnittlig och maximal användning |
| Överskridande av tilldelad tid | Skicklig avslutning | Visar överskriden körtid och total använd tid |
| Manuell avbokning | Skicklig avslutning | Fullständigt resursmeddelande, resurssammanfattning loggas |
| Oväntad uppsägning | Oförskämd uppsägning | Partiella eller ofullständiga användningsdata registrerade |
Genom att upprätthålla resursgränser automatiskt och tillhandahålla detaljerade loggar (som visas i 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 har slutförts framgångsrikt
När ett skript slutförs normalt utan att överskrida gränserna innehåller loggen en sammanfattning av resursanvändning som visar genomsnittlig och maximal användning av minne, processor, disk och exekveringstid. Denna information ger insyn i prestandaegenskaperna för framgångsrikt genomförda körningar.
Obs: Om ett skript körs mycket snabbt (t.ex. mindre än 1 sekund) kanske inte resursuttag sker. I dessa fall kommer inga uppgifter om resursanvändning att rapporteras i loggen.
Skriptet körs för snabbt för att provas
Om ett skript avslutas för snabbt kan monitorn 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ändningen i loggen.
Uppsägning när limiterna överskrids
Om en skriptkörning överskrider sina konfigurerade gränser (t.ex. minne, diskanvändning eller tilldelad tid) kommer Scripting:
- Försök att stoppa skriptet på ett säkert sätt - När gränserna överskrids skickar Scripting först en avslutningssignal (SIGTERM) för att låta skriptet rensa upp och avsluta inom 15 sekunder.
- Om skriptet inte avslutas inom 15 sekunder skickar Scripting en SIGKILL-signal, som omedelbart stoppar processen utan att tillåta någon upprensning. Detta är en kraftfull avslutning och körningen avslutas med statusen misslyckad (visas i rött i loggen). Denna status indikerar ett fel i Scripting System.
- Anteckna orsaken till stoppet - loggen visar vilken gräns som nåddes och sammanfattar skriptets resursanvändning.
I nästa avsnitt ges exempel på vad som händer när ett skript överskrider gränserna utan kod för att hantera dessa signaler. Om du vill veta hur du ändrar dina skript så att de reagerar på ett elegant sätt på dessa signaler, se Hantera systemsignaler i skript.
Minnesgränsen har överskridits
När ett skript överskrider den konfigurerade minnesgränsen innehåller loggen orsaken till att skriptet avslutas och information om det överskridna tröskelvärdet.
Gränsen för diskanvändning 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 vid den tidpunkt då gränsen nåddes.
Tilldelad tid överskreds
När ett skript överskrider sin konfigurerade tilldelade tid innehåller loggen orsaken till avslutningen och den totala registrerade körtiden.
Uppsägning när användaren avbryter en körning
Om en användare manuellt avbryter en körning skickar Scripting först en avbrottssignal (SIGINT) för att tala om för skriptet att det ska stoppas. Skriptet har 15 sekunder på sig att städa upp, spara framsteg eller rulla tillbaka innan det stängs av. Efter denna 15-sekundersfrist sker samma sekvens som beskrivs ovan: en avslutningssignal (SIGTERM) skickas för att ge skriptet ytterligare 15 sekunder att slutföra upprensningen, följt av en sista dödssignal (SIGKILL) om skriptet fortfarande inte har avslutats.
Bilden nedan visar hur skriptloggarna ser ut när ett skript som inte innehåller kod för att hantera avbrottssignalen.
Om du vill veta hur du ändrar dina skript så att de reagerar på ett elegant sätt på dessa signaler, se Hantera systemsignaler i skript.
Oplanerade uppsägningar
I sällsynta fall, t.ex. när ett skript förbrukar minne snabbare än Scripting-systemet 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 Scripting en ofullständig användningsrapport som endast visar de datapunkter som samlats in före avslutningen.
Hantering av systemsignaler i skript
Signalhantering gör att ditt skript avslutas snyggt när det avbryts eller stoppas av systemet. Genom att fånga upp och reagera på systemsignaler kan ditt skript frigöra resurser, spara arbete och avsluta på ett elegant sätt (t.ex. när statusen rapporteras som "komplett") i stället för att avslutas med våld.
När ett skript stoppas för att en användare avbryter det eller för att det överskrider plattformens gränser, levererar Scripting avbrotts-, avslutnings- och dödssignaler. I de tidigare avsnitten finns mer information om hur avbrotts-, avslutnings- och dödssignaler utlöses.
Scripting-signaler och hur man hanterar dem
I detta avsnitt finns 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 städningen på ett ställe med hjälp av ett try/finally block som alltid körs vid avstängning. Detta gör att skripten är förutsägbara och lätta att underhålla.
Den övergripande strukturen för att hantera signaler i ditt skript är densamma oavsett vilken signal som tas emot:
- Överst i filen: importera moduler och definiera hanteraren
- Tidig initialisering: registrerar hanteraren innan något arbete utförs
- Runt ditt arbete: linda in huvudkoden i ett
try/finallyblock så att rensningen alltid körs
Användaren avbryter körningen (SIGINT)
Detta inträffar när en användare klickar på Cancel för att avbryta skriptkörningen.
# --- Högst upp i filen --- import signal, sys # Tiny handler: begär omedelbar, elegant avslutning def _graceful_exit(signum, frame): print("SIGINT received: cancellation requested. Cleaning up...") raise SystemExit(0) # --- Tidig initialisering --- signal.signal(signal.SIGINT, _graceful_exit) Runt ditt arbete (längre fram i filen):
prova: # ditt långvariga arbete här ... slutligen: # central plats för att stänga filer, spola loggar etc. print("Slutlig rengöring före avslut") Bilden nedan visar hur skriptloggarna ser ut när avbrottssignalen (SIGINT) hanteras.
Hantering KeyboardInterrupt direkt
Workiva Scripting skickar också KeyboardInterrupt när SIGINT levereras till huvudtråden. Du kan fånga detta undantag i ditt try -block och anropa samma upprensningssökväg som definieras av _graceful_exit().
try: # ditt långvariga arbete här ... except KeyboardInterrupt: print("KeyboardInterrupt received: cleaning up before exit...") _graceful_exit(None, None) finally: # central plats för att stänga filer, spola loggar etc. print("Slutlig städning före avslut") Bilden nedan visar hur skriptloggarna ser ut när avbrottssignalen hanteras via keyboard interrupt.
Skriptning av termineringssignal för att stoppa efter en respitperiod (SIGTERM)
Scripting ber ditt script att sluta (t.ex. efter att gränser har överskridits). Ditt skript har en kort tidsfrist för att avslutas.
# --- Högst upp i filen --- def _graceful_term(signum, frame): print("SIGTERM mottagen: plattformen begärde avslutning. Finishing up...") raise SystemExit(0) # --- Tidig initialisering --- signal.signal(signal.SIGTERM, _graceful_term) Bilden nedan visar hur skriptloggarna ser ut när avslutningssignalen (SIGTERM) hanteras.
Skriptad dödssignal för att stoppa omedelbart (SIGKILL)
Om ditt skript inte avslutas under respitperioden kommer Scripting att skicka SIGKILL. Du kan inte fånga SIGKILL. Avsluta snabbt på SIGINT/SIGTERM så att ditt slutligen block kan köras innan en kill inträffar.
Skärmbilderna i de tidigare avsnitten visar hur loggarna skulle se ut som ett resultat av dödssignalen.
Komplett exempel (redo för copy-paste)
Denna mall registrerar minimala hanterare och centraliserar städningen till och slutligen. 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 exempelslingan under # ===== DIN KOD STARTER HÄR ===== med dina faktiska uppgifter. Undvik mycket långa oavbrutna anrop så att skriptet kan nå blocket och slutligen innan plattformen eskalerar till SIGKILL.
"""Workiva Scripting template: minimal handlers + cleanup in finally - Tiny handlers raise SystemExit(0) on SIGINT/SIGTERM - Single finally block runs for cleanup regardless of how the script stops - Keeps code small and predictable """ import signal import time # --- Signal handlers (keep tiny) --- def _graceful_exit(signum, frame): print("SIGINT received: cancellation requested. Cleaning up...") raise SystemExit(0) def _graceful_term(signum, frame): print("SIGTERM mottagen: plattformen begärde avslutning. Finishing up...") raise SystemExit(0) # --- Registrera handlers INNAN du gör något tungt arbete --- signal.signal(signal.SIGINT, _graceful_exit) signal.signal(signal.SIGTERM, _graceful_term) # --- Ditt skripts huvudarbete --- def main(): print("Starting work...") # ===== DIN KOD STARTER HÄR ===== # Exempel på en lång 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 på objekt {i}...") time.sleep(1) # ===== DIN KOD SLUTAR HÄR ===== if __name__ == "__main__": try: main() finally: # Centraliserad rensning som alltid körs (även vid SIGINT/SIGTERM) print("Slutlig rensning före avslutning")