code: def register_abort_callback(
      self, callback_function, execution_timeout, poll_freq
  ):
      if not self._task:
          return
  
      self._poll_freq = float(poll_freq) if poll_freq else None
      self._abort_cb = callback_function
      self._abort_cb_timeout = float(execution_timeout)
  
      if not callback_function:
          # noinspection PyProtectedMember
          self._task._set_runtime_properties(
              {DevWorker.property_abort_callback_timeout: float(-1)}
          )
          return
  
      # noinspection PyProtectedMember
      self._task._set_runtime_properties(
          {
              self.property_abort_callback_timeout: float(
                  execution_timeout
              ),
              self.property_abort_poll_freq: float(poll_freq),
              self.property_abort_callback_completed: "",
          }
      )
  
file_path: clearml/clearml/backend_interface/task/development/worker.py
imports: import attr
  from threading import Thread
  from time import time
  from ....config import deferred_config
  from ....backend_interface.task.development.stop_signal import TaskStopSignal
  from ....backend_api.services import tasks
  from ....utilities.lowlevel.threads import kill_thread
  from ....utilities.process.mp import SafeEvent
label_desc: Use image node_id 4 for calling the DevWorker obj's underlying member method code with example usage: obj.register_abort_callback(callback_function, execution_timeout, poll_freq) without return types