<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def run(components=None, broker=None):
 """ Executes components in an order that satisfies their dependency relationships. Keyword Args: components: Can be one of a dependency graph, a single component, a component group, or a component type. If it's anything other than a dependency graph, the appropriate graph is built for you and before evaluation. broker (Broker):
 Optionally pass a broker to use for evaluation. One is created by default, but it's often useful to seed a broker with an initial dependency. Returns: Broker: The broker after evaluation. """

    components = components or COMPONENTS[GROUPS.single]
    components = _determine_components(components)
    broker = broker or Broker()

    for component in run_order(components):
        start = time.time()
        try:
            if component not in broker and component in DELEGATES and is_enabled(component):
                log.info("Trying %s" % get_name(component))
                result = DELEGATES[component].process(broker)
                broker[component] = result
        except MissingRequirements as mr:
            if log.isEnabledFor(logging.DEBUG):
                name = get_name(component)
                reqs = stringify_requirements(mr.requirements)
                log.debug("%s missing requirements %s" % (name, reqs))
            broker.add_exception(component, mr)
        except SkipComponent:
            pass
        except Exception as ex:
            tb = traceback.format_exc()
            log.warn(tb)
            broker.add_exception(component, ex, tb)
        finally:
            broker.exec_times[component] = time.time() - start
            broker.fire_observers(component)

    return broker