class_docstr: Object for conducting search experiments.
      
docstr: block_until_done  means that the process blocks until ALL jobs in
  trials are not in running or new state
docstr_tok: ["block_until_done","means","that","the","process","blocks","until","ALL","jobs","in","trials","are","not","in","running","or","new","state"]
code: def run(self, N, block_until_done=True):
      """
      block_until_done  means that the process blocks until ALL jobs in
      trials are not in running or new state
  
      """
      trials = self.trials
      algo = self.algo
      n_queued = 0
  
      def get_queue_len():
          return self.trials.count_by_state_unsynced(base.JOB_STATE_NEW)
  
      stopped = False
      while n_queued < N:
          qlen = get_queue_len()
          while qlen < self.max_queue_len and n_queued < N:
              n_to_enqueue = min(
                  self.max_queue_len - qlen, N - n_queued
              )
              new_ids = trials.new_trial_ids(n_to_enqueue)
              self.trials.refresh()
              if 0:
                  for d in self.trials.trials:
                      print(
                          "trial %i %s %s"
                          % (
                              d["tid"],
                              d["state"],
                              d["result"].get("status"),
                          )
                      )
              new_trials = algo(
                  new_ids,
                  self.domain,
                  trials,
                  self.rstate.randint(2**31 - 1),
              )
              assert len(new_ids) >= len(new_trials)
              if len(new_trials):
                  self.trials.insert_trial_docs(new_trials)
                  self.trials.refresh()
                  n_queued += len(new_trials)
                  qlen = get_queue_len()
              else:
                  stopped = True
                  break
  
          if self.asynchronous:
              # -- wait for workers to fill in the trials
              time.sleep(self.poll_interval_secs)
          else:
              # -- loop over trials and do the jobs directly
              self.serial_evaluate()
  
          if stopped:
              break
  
      if block_until_done:
          self.block_until_done()
          self.trials.refresh()
          logger.info("Queue empty, exiting run.")
      else:
          qlen = get_queue_len()
          if qlen:
              msg = "Exiting run, not waiting for %d jobs." % qlen
              logger.info(msg)
  
imports: from __future__ import print_function
  from __future__ import absolute_import
  from future import standard_library
  from builtins import str
  from builtins import object
  import functools
  import logging
  import os
  import sys
  import time
  import numpy
  from .None import pyll
  from .utils import coarse_utcnow
  from .None import base
label_desc: Use image node_id 4 for calling the FMinIter obj's underlying member method code with example usage: obj.run(N, block_until_done) and returns: self