code: def schedule(self):
          
          assert self.collection_is_completed
  
          # Initial distribution already happened, reschedule on all nodes
          if self.collection is not None:
              for node in self.nodes:
                  self.check_schedule(node)
              return
  
          # XXX allow nodes to have different collections
          if not self._check_nodes_have_same_collection():
              self.log("**Different tests collected, aborting run**")
              return
  
          # Collections are identical, create the index of pending items.
          self.collection = list(self.node2collection.values())[0]
          self.pending[:] = range(len(self.collection))
          if not self.collection:
              return
  
          # Send a batch of tests to run. If we don't have at least two
          # tests per node, we have to send them all so that we can send
          # shutdown signals and get all nodes working.
          initial_batch = max(len(self.pending) // 4, 2 * len(self.nodes))
  
          # distribute tests round-robin up to the batch size
          # (or until we run out)
          nodes = cycle(self.nodes)
          for i in range(initial_batch):
              self._send_tests(next(nodes), 1)
  
          if not self.pending:
              # initial distribution sent all tests, start node shutdown
              for node in self.nodes:
                  node.shutdown()
docs: Initiate distribution of the test collection
  
          Initiate scheduling of the items across the nodes.  If this
          gets called again later it behaves the same as calling
          ``.check_schedule()`` on all nodes so that newly added nodes
          will start to be used.
  
          This is called by the ``DSession.worker_collectionfinish`` hook
          if ``.collection_is_completed`` is True.