class_docstr: Class for clusters following a master-worker architecture.
  
  Usually you want to inherit from this class and do not want to use it directly. It is recommended to treat this
  class as an abstract class or an interface.
  
  Examples:
      Create a cluster with all `Runtimes` detected by the `RuntimeManager`.
  
      ```python
      from lazycluster import RuntimeManager
      cluster = MyMasterWorkerClusterImpl(RuntimeManager().create_group())
      cluster.start()
      ```
  
      Use different strategies for launching the master and the worker instance as the default ones by providing
      custom implementation of `MasterLauncher` and `WorkerLauncher`.
  
      ```python
      cluster = MyMasterWorkerClusterImpl(RuntimeManager().create_group(),
                                          MyMasterLauncherImpl(),
                                          MyWorkerLauncherImpl()
      cluster.start()
      ```
class_docstr_tok: ["Class","for","clusters","following","a","master-worker","architecture",".","Usually","you","want","to","inherit","from","this","class","and","do","not","want","to","use","it","directly",".","It","is","recommended","to","treat","this","class","as","an","abstract","class","or","an","interface",".","Examples",":","Create","a","cluster","with","all","`","Runtimes","`","detected","by","the","`","RuntimeManager","`",".","``","`","python","from","lazycluster","import","RuntimeManager","cluster","=","MyMasterWorkerClusterImpl","(","RuntimeManager","(",")",".create_group","(",")",")","cluster.start","(",")","``","`","Use","different","strategies","for","launching","the","master","and","the","worker","instance","as","the","default","ones","by","providing","custom","implementation","of","`","MasterLauncher","`","and","`","WorkerLauncher","`",".","``","`","python","cluster","=","MyMasterWorkerClusterImpl","(","RuntimeManager","(",")",".create_group","(",")",",","MyMasterLauncherImpl","(",")",",","MyWorkerLauncherImpl","(",")","cluster.start","(",")","``","`"]
docstr: Print the execution log.
  
  Note:
      This method is a convenient wrapper for the equivalent method of the contained `RuntimeGroup`.
docstr_tok: ["Print","the","execution","log",".","Note",":","This","method","is","a","convenient","wrapper","for","the","equivalent","method","of","the","contained","`","RuntimeGroup","`","."]
code: def print_log(self) -> None:
      """Print the execution log.
  
      Note:
          This method is a convenient wrapper for the equivalent method of the contained `RuntimeGroup`.
  
      """
      self.runtime_group.print_log()
  
imports: import atexit
  import logging
  from subprocess import Popen
  from typing import Dict, List, Optional, Union
  from lazycluster.exceptions import LazyclusterError
  from lazycluster.runtime_mgmt import RuntimeGroup
label_desc: Use image node_id 8 for calling the MasterWorkerCluster obj's underlying member method code with example usage: obj.print_log() without return types