code: def control_flow(self, abort_signal: Signal, fl_ctx: FLContext):
      self.log_info(fl_ctx, "XGBoost training control flow started.")
      if abort_signal.triggered:
          return
      task = Task(name=SupportedTasks.TRAIN, data=Shareable())
      self.broadcast_and_wait(
          task=task,
          min_responses=self._world_size,
          fl_ctx=fl_ctx,
          wait_time_after_min_received=1,
          abort_signal=abort_signal,
      )
      if abort_signal.triggered:
          return
  
      self.log_info(fl_ctx, "XGBoost training control flow finished.")
  
file_path: xgboost/demo/nvflare/horizontal/custom/controller.py
imports: import multiprocessing
  from nvflare.apis.client import Client
  from nvflare.apis.fl_context import FLContext
  from nvflare.apis.impl.controller import Controller, Task
  from nvflare.apis.shareable import Shareable
  from nvflare.apis.signal import Signal
  from trainer import SupportedTasks
  import xgboost.federated
label_desc: Use image node_id 5 for calling the XGBoostController obj's underlying member method code with example usage: obj.control_flow(abort_signal, fl_ctx) without return types