Workiva 指令碼自動監控每個指令碼執行時所使用的資源,包括記憶體、CPU、磁碟使用(量)及執行時間。當指令碼超出其配置的資源限制時,Scripting 會嘗試安全地停止該指令碼,同時維持平台的穩定性。此外,在完全停止之前,系統會給指令碼清理和離開的時間,以確保對使用者的干擾降到最低。
本文解釋 Scripting 如何處理終止情境、記錄中出現哪些詳細資訊,並包括參考 (資料) 螢幕擷取畫面。
有關所有系統限制的詳細資訊,請參閱Workiva Scripting 限制 。
情境
| 案例 | 行為 | 記錄詳細資訊 |
| 非常短的執行 | 成功執行(地) | 無資源使用(量)資料記錄 |
| 正常完成 | 成功執行(地) | 記錄完整的資源使用(量)摘要 (除非時間太短無法取樣) |
| 超出記憶體限制 | 優先終止 | 顯示超出記憶體臨界值,顯示平均和峰值使用量(量) |
| 超過磁碟限制 | 優先終止 | 顯示超過磁碟臨界值,並顯示平均和峰值使用(量) |
| 超過分配時間 | 優先終止 | 顯示超出的執行時間和已使用的總時間 |
| 手動取消 | 優先終止 | 完全釋放資源,記錄資源摘要 |
| 意外終止 | 意外終止 | 記錄部分或不完整的使用資料(量) |
透過自動執行資源限制並提供詳細記錄(如下螢幕擷取畫面所示),Workiva Scripting 可同時確保平臺的可靠性和透明度,方便開發者建立和優化自動化指令碼。
當執行成功(地)時終止
當指令碼正常完成而未超出限制時,記錄包括資源使用摘要 ,顯示記憶體、CPU、磁碟和執行時間的平均和峰值使用量。此資訊提供成功執行者效能特性的可視性。
附註: 如果指令碼執行得非常快 (例如,少於 1 秒),資源取樣可能不會發生。在這些情況下,記錄中不會報告任何資源使用(量)資料。
指令碼執行速度太快,無法取樣
如果指令碼結束得太快,監視器無法擷取使用(量) 資料。
指令碼正常離開
如果指令碼完成時沒有超出任何限制,資源使用統計資料會完整地顯示在記錄中。
超出限制時終止
如果執行的指令碼超過其組態限制(例如記憶體、磁碟使用量或分配時間),Scripting 會: 嘗試安全停止指令碼:
- 嘗試安全地停止指令碼-當超出限制時,Scripting 會先傳送終止信號 (SIGTERM),讓指令碼在 15 秒內清理並離開。
- 如果指令碼沒有在 15 秒內離開-Scripting 會傳送 SIGKILL 訊號,立即停止流程,不允許任何清理。這是強制終止,執行會以失敗狀態完成(在記錄中以紅色顯示)。此狀態表示指令碼系統出錯。
- 記錄停止的原因 - 記錄會顯示達到了哪個限制,並總結指令碼的資源使用(量)。
下一步/下一個區段 (UI)/章節提供了一些範例,說明在沒有程式碼處理這些訊號時,當腳本超出限制時會發生的情況。若要學習如何修改您的指令碼,以便對這些訊號作出優雅的回應,請參閱在指令碼中處理系統訊 號 。
超出記憶體限制
當指令碼超出配置的記憶體限制時,記錄包括終止原因和超出臨界值的詳細資訊。
超出磁碟使用(量) 限制
當指令碼超過設定的磁碟使用量限制時,記錄包括終止原因和達到限制時的磁碟使用量詳細資訊。
超過分配時間
當指令碼超過其配置的分配時間時,記錄包括終止原因和記錄的總執行時間。
使用者取消執行時終止
如果使用者手動取消執行,Scripting 會先傳送中斷訊號 (SIGINT) 讓指令碼知道它應該停止。指令碼在關機前有 15 秒的時間進行清理、另存新檔或回滾。在這 15 秒寬限期之後,會發生上述相同的順序:發送終止訊號 (SIGTERM),讓腳本再有 15 秒的時間完成清理,接著如果腳本仍未離開,則發送最終的 kill 訊號 (SIGKILL)。
下圖影像顯示當指令碼不包括處理中斷信號的程式碼時,指令碼記錄是如何顯示的。
要瞭解如何修改您的指令碼,以便對這些信號作出優雅的回應,請參閱在指令碼中處理系統信號 。
意外終止
在罕見的情況下,例如當指令碼的記憶體取用速度超過 Scripting 系統所能監控的消耗速度時,系統可能會在偵測到超出限制前終止指令碼。當發生這種情況時,指令碼會記錄一份不完整的使用(量)報告,只顯示終止前所收集的資料點。
在指令碼中處理系統信號
信號處理可讓您的指令碼在被系統取消或停止時乾淨地關閉。透過捕捉和回應系統信號,您的指令碼可以釋放資源、儲存新檔並優雅地離開(例如,當狀態報告為 「完成 」時),而不是被強制終止。
當指令碼因使用者取消或超出平台限制而停止時,Scripting 會發出中斷、終止和終止訊號。 若要進一步了解如何觸發中斷、終止和終止信號,請參閱前面的區段 (UI)/章節。
指令碼訊號及其處理方式
本區段 (UI)/章節提供您可以用來處理這些信號的程式碼區塊和完整範例。
您可以使用try/finally 區塊來保持較小的信號處理器,並在一個地方處理清理工作,該區塊總是在關機時執行。這可保持指令碼的可預期性且容易維護。
無論接收到的是哪個訊號,指令碼中處理訊號的整體結構都是相同的:
- 檔案頂端: 匯入模組並定義處理器
- 早期初始化: 在執行任何工作之前註冊處理器
- 圍繞您的工作: 將主程式碼包裝在
try/finally區塊中,因此清理工作總是會執行
使用者取消執行 (SIGINT)
當使用者隨選即用Cancel 取消指令碼執行時,就會發生這種情況。
# --- 檔案頂端 --- import signal, sys # 微小的處理程式:要求立即、優雅的離開 def _graceful_exit(signum, frame): print("SIGINT received: cancellation requested. 清理...") raise SystemExit(0) # --- 早期初始化 --- signal.signal(signal.SIGINT, _graceful_exit) 在您的工作(檔案後面)周圍:
try:# 您長時間執行的工作在這裡 ... 最終的:# 關閉檔案、刷新記錄等的中心位置 print("Final cleanup before exit") 下圖影像顯示處理中斷信號 (SIGINT) 時,指令碼記錄的顯示方式。
直接處理KeyboardInterrupt
當 SIGINT 傳送到主線程時,Workiva Scripting 也會產生KeyboardInterrupt 。您可以在try 區塊中捕捉此異常,並呼叫由_graceful_exit() 定義的相同清理路徑 。
try:# 您長時間執行的工作在這裡 ... except KeyboardInterrupt: print("KeyboardInterrupt received: cleaning up before exit...") _graceful_exit(None, None) finally:# 關閉檔案、刷新記錄等的中心位置 print("Final cleanup before exit") 下圖影像顯示透過鍵盤中斷處理中斷信號時,指令碼記錄的顯示方式。
指令碼終止信號在寬限期/週期後停止 (SIGTERM)
指令碼要求您的指令碼停止(例如:超出限制之後)。您的指令碼有一段短時間的寬限期來離開。
# --- 檔案頂端 --- def _graceful_term(signum, frame): print("SIGTERM received: platform requested termination. Finishing up...") raise SystemExit(0) # --- 早期初始化 --- signal.signal(signal.SIGTERM, _graceful_term) 下圖影像顯示處理終止信號 (SIGTERM) 時,指令碼記錄的顯示方式。
指令碼立即停止的終止信號 (SIGKILL)
如果您的指令碼沒有在寬限期期間離開,Scripting 會傳送 SIGKILL。 您無法捕捉 SIGKILL。在 SIGINT/SIGTERM 時迅速離開,以便您的finally 區塊能在 kill 發生前執行。
前面區段 (UI)/章節的螢幕擷取畫面顯示 kill 訊號執行後的記錄。
完整範例 (可複製上傳)
此範本註冊最小處理程式並將清理集中於最終的 。貼上到 Workiva Scripting 並用您的邏輯取代標記號的區域。
在哪裡新增您的程式碼:以您的實際任務取代# ===== YOUR CODE STARTS HERE ===== 下方的樣本循環。避免非常長的不間斷呼叫,以便指令碼可以在平台升級到 SIGKILL 之前打到最終的 區塊。
""「Workiva Scripting 範本:最小處理程式 + finally 中的清理 - 小處理程式在 SIGINT/SIGTERM 時會 raise SystemExit(0) - 無論腳本如何停止,都會執行單一 finally 區塊進行清理 - 保持程式碼小且可預測 」"「 import signal import time # --- 信號處理程式 (保持微小) --- def _graceful_exit(signum, frame): print(」SIGINT received: cancellation requested. 清理...") raise SystemExit(0) def _graceful_term(signum, frame): print("SIGTERM received: platform requested termination. 完成...「) raise SystemExit(0) # --- 在做任何繁重的工作之前註冊處理器 --- signal.signal(signal.SIGINT, _graceful_exit) signal.signal(signal.SIGTERM, _graceful_term) # --- 你的指令碼的主要工作 --- def main(): print(」Starting work...") # ===== 你的指令從這裡開始 ===== # 長時間執行循環的範例。取代為您的實際邏輯。 for i in range(1, 1_000_000):# 模擬一個工作單位 (取代真正的邏輯) print(f "Working on item{i}...") time.sleep(1) # ===== YOUR CODE ENDS HERE ===== if __name__ =="__main__": try: main() finally:# 已定稿的集中清理工作會一直執行 (包括 SIGINT/SIGTERM 時) print("Final cleanup before exit")