X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/6346a7c4c0cb5d7e8c5f01392b6cc64d329b68ec..ab3afbb684bc1b32577c2696e13882123bfff7d2:/services/nodemanager/arvnodeman/computenode/dispatch/__init__.py diff --git a/services/nodemanager/arvnodeman/computenode/dispatch/__init__.py b/services/nodemanager/arvnodeman/computenode/dispatch/__init__.py index 37d7088b7a..bb83a193fa 100644 --- a/services/nodemanager/arvnodeman/computenode/dispatch/__init__.py +++ b/services/nodemanager/arvnodeman/computenode/dispatch/__init__.py @@ -20,6 +20,7 @@ from .. import \ arvados_node_missing, RetryMixin from ...clientactor import _notify_subscribers from ... import config +from ... import status from .transitions import transitions QuotaExceeded = "QuotaExceeded" @@ -242,12 +243,15 @@ class ComputeNodeShutdownActor(ComputeNodeStateChangeBase): return super(ComputeNodeShutdownActor, self)._finished() def cancel_shutdown(self, reason, **kwargs): + if not self.cancellable: + return False if self.cancel_reason is not None: # already cancelled - return + return False self.cancel_reason = reason self._logger.info("Shutdown cancelled: %s.", reason) self._finished(success_flag=False) + return True def _cancel_on_exception(orig_func): @functools.wraps(orig_func) @@ -272,12 +276,16 @@ class ComputeNodeShutdownActor(ComputeNodeStateChangeBase): self.cancel_shutdown("No longer eligible for shut down because %s" % reason, try_resume=True) return + # If boot failed, count the event + if self._monitor.get_state().get() == 'unpaired': + status.tracker.counter_add('boot_failures') self._destroy_node() def _destroy_node(self): self._logger.info("Starting shutdown") arv_node = self._arvados_node() if self._cloud.destroy_node(self.cloud_node): + self.cancellable = False self._logger.info("Shutdown success") if arv_node: self._later.clean_arvados_node(arv_node) @@ -346,6 +354,7 @@ class ComputeNodeMonitorActor(config.actor_class): self.boot_fail_after = boot_fail_after self.subscribers = set() self.arvados_node = None + self.consecutive_idle = 0 self._later.update_arvados_node(arvados_node) self.last_shutdown_opening = None self._later.consider_shutdown() @@ -409,6 +418,12 @@ class ComputeNodeMonitorActor(config.actor_class): #if state == 'idle' and self.arvados_node['job_uuid']: # state = 'busy' + # Update idle node times tracker + if state == 'idle': + status.tracker.idle_in(self.arvados_node['hostname']) + else: + status.tracker.idle_out(self.arvados_node['hostname']) + return state def in_state(self, *states): @@ -441,8 +456,14 @@ class ComputeNodeMonitorActor(config.actor_class): else: boot_grace = "boot exceeded" - # API server side not implemented yet. - idle_grace = 'idle exceeded' + if crunch_worker_state == "idle": + # Must report as "idle" at least two consecutive times + if self.consecutive_idle < 2: + idle_grace = 'idle wait' + else: + idle_grace = 'idle exceeded' + else: + idle_grace = 'not idle' node_state = (crunch_worker_state, window, boot_grace, idle_grace) t = transitions[node_state] @@ -502,4 +523,8 @@ class ComputeNodeMonitorActor(config.actor_class): if arvados_node is not None: self.arvados_node = arvados_node self._update.sync_node(self.cloud_node, self.arvados_node) + if self.arvados_node['crunch_worker_state'] == "idle": + self.consecutive_idle += 1 + else: + self.consecutive_idle = 0 self._later.consider_shutdown()