11import os
22import sys
3+ import time
34import typing
4- from typing import Any , Dict , List , Optional , Set
5+ from typing import Any , Callable , Dict , List , Optional , Set
56
67from hpc .autoscale import hpclogging as logging
78from hpc .autoscale .job import demandcalculator as dcalclib
89from hpc .autoscale .job import demandprinter
910from hpc .autoscale .job .demand import DemandResult
1011from hpc .autoscale .job .demandcalculator import DemandCalculator
12+ from hpc .autoscale .node .node import Node
1113from hpc .autoscale .node .nodehistory import NodeHistory , SQLiteNodeHistory
1214from hpc .autoscale .node .nodemanager import new_node_manager
1315from hpc .autoscale .results import DefaultContextHandler
@@ -30,6 +32,7 @@ def autoscale_grid_engine(
3032 ctx_handler : Optional [DefaultContextHandler ] = None ,
3133 node_history : Optional [NodeHistory ] = None ,
3234 dry_run : bool = False ,
35+ clock : Callable [[], float ] = time .time ,
3336) -> DemandResult :
3437 global _exit_code
3538
@@ -75,8 +78,11 @@ def autoscale_grid_engine(
7578 if not ccnodeid or ccnodeid == cc_node .delayed_node_id .node_id :
7679 if cc_node .state in ["Preparing" , "Acquiring" ]:
7780 continue
81+
82+ # Sometimes a node will be fully converged but will still be shown as 'au' = alarm, unresponsive
83+ # We will ignore this unless the node has been given its full boot_timeout.
7884 if "a" in state and "u" in state :
79- invalid_nodes . append ( node )
85+ _handle_alarm_node ( config , clock , node , invalid_nodes )
8086
8187 # nodes in error state must also be deleted
8288 nodes_to_delete = ge_driver .clean_hosts (invalid_nodes )
@@ -168,6 +174,25 @@ def autoscale_grid_engine(
168174 return demand_result
169175
170176
177+ def _handle_alarm_node (
178+ config : Dict ,
179+ clock : Callable [[], float ],
180+ node : "Node" ,
181+ invalid_nodes_out : List ["Node" ],
182+ ) -> None :
183+ now = clock ()
184+ omega = config ["boot_timeout" ] + node .create_time_unix
185+ if now > omega :
186+ invalid_nodes_out .append (node )
187+ else :
188+ logging .warning (
189+ f"Node { node .name } is in an alarm state ('au') but it has not been up longer than its boot_timeout."
190+ )
191+ logging .warning (
192+ f"If { node .name } is still in an alarm state in { omega - now } seconds, it will be removed and shutdown."
193+ )
194+
195+
171196def new_demand_calculator (
172197 config : Dict ,
173198 ge_env : Optional [GridEngineEnvironment ] = None ,
0 commit comments