def getOpenCircuit(self, stream):
        '''Return a deferred that will fire with an open circuit that can
        handle the stream's request.


        There are three general cases to handle when a new open circuit
        request comes in:

            1. An open circuit exists that can handle this request. In this
               case, choose a random circuit from the set of open circuits
               that can handle this request and immediately callback the
               deferred with the chosen open circuit.

            2. A pending circuit exists that, when open, can handle this
               request. In this case, add the request to a pool of pending
               requests. Whenever a circuit opens, circuit manager checks all
               pending requests and assigns any pending requests that the
               newly opened circuit can handle to that circuit. So when a
               pending circuit opens that can handle this stream, the
               stream's deferred will be called back with the fresly opened
               circuit.

            3. No open or pending circuits exist that can handle the request.
               In this case, begin building a new circuit that can. Add the
               request to a pending request pool and, when a circuit opens
               that can handle the request, callback this stream's deferred
               with the newly opened circuit.

        :param oppy.stream.stream.Stream stream: the stream that is
            requesting an open circuit
        :returns: **twisted.internet.defer.Deferred** which will fire when
            a circuit has opened that can handle this stream's request.
        '''
        logging.debug("Circuit manager got an open circuit request.")
        request = stream.request
        d = defer.Deferred()

        try:
            c = random.choice(self._getOpenCandidates(request))
            msg = "Assigning request to circuit {}.".format(c.circuit_id)
            logging.debug(msg)
            d.callback(c)
        except __HOLE__:
            if len(self._getPendingCandidates(request)) == 0:
                msg = "Building a new circuit to handle request."
                self._buildCircuit(request=request)
            else:
                msg = "A CircuitBuildTask can eventually handle request."

            logging.debug(msg)
            self._pending_stream_list.append(PendingStream(stream, d))

        return d
dataset/ETHPy150Open nskinkel/oppy/oppy/circuit/circuitmanager.py/CircuitManager.getOpenCircuit