<s> '''<STR_LIT>''' <EOL> import logging <EOL> import random <EOL> from collections import namedtuple <EOL> from twisted . internet import defer <EOL> from oppy . circuit . circuitbuildtask import CircuitBuildTask <EOL> from oppy . circuit . definitions import ( <EOL> CircuitType , <EOL> DEFAULT_OPEN_IPv4 , <EOL> DEFAULT_OPEN_IPv6 , <EOL> MAX_STREAMS_V3 , <EOL> ) <EOL> from oppy . history . guards import GuardManager <EOL> from oppy . util . tools import ctr <EOL> PendingStream = namedtuple ( "<STR_LIT>" , ( <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> ) ) <EOL> class CircuitManager ( object ) : <EOL> '''<STR_LIT>''' <EOL> def __init__ ( self , connection_manager , netstatus , autobuild = True ) : <EOL> logging . debug ( "<STR_LIT>" ) <EOL> self . _netstatus = netstatus <EOL> self . _guard_manager = GuardManager ( netstatus ) <EOL> self . _connection_manager = connection_manager <EOL> self . _ctr = ctr ( MAX_STREAMS_V3 ) <EOL> self . _open_circuit_dict = { } <EOL> self . _circuit_build_task_dict = { } <EOL> self . _pending_stream_list = [ ] <EOL> self . _min_IPv4_count = DEFAULT_OPEN_IPv4 <EOL> self . _min_IPv6_count = DEFAULT_OPEN_IPv6 <EOL> self . _sent_open_message = False <EOL> if autobuild is True : <EOL> self . _buildCircuits ( self . _min_IPv4_count , <EOL> circuit_type = CircuitType . IPv4 ) <EOL> self . _buildCircuits ( self . _min_IPv6_count , <EOL> circuit_type = CircuitType . IPv6 ) <EOL> def getOpenCircuit ( self , stream ) : <EOL> '''<STR_LIT>''' <EOL> logging . debug ( "<STR_LIT>" ) <EOL> request = stream . request <EOL> d = defer . Deferred ( ) <EOL> try : <EOL> c = random . choice ( self . _getOpenCandidates ( request ) ) <EOL> msg = "<STR_LIT>" . format ( c . circuit_id ) <EOL> logging . debug ( msg ) <EOL> d . callback ( c ) <EOL> except IndexError : <EOL> if len ( self . _getPendingCandidates ( request ) ) == <NUM_LIT:0> : <EOL> msg = "<STR_LIT>" <EOL> self . _buildCircuit ( request = request ) <EOL> else : <EOL> msg = "<STR_LIT>" <EOL> logging . debug ( msg ) <EOL> self . _pending_stream_list . append ( PendingStream ( stream , d ) ) <EOL> return d <EOL> def shouldDestroyCircuit ( self , circuit ) : <EOL> '''<STR_LIT>''' <EOL> if circuit . circuit_type == CircuitType . IPv4 : <EOL> return self . _totalIPv4Count ( ) - <NUM_LIT:1> > self . _min_IPv4_count <EOL> else : <EOL> return self . _totalIPv6Count ( ) - <NUM_LIT:1> > self . _min_IPv6_count <EOL> def circuitDestroyed ( self , circuit ) : <EOL> '''<STR_LIT>''' <EOL> cid = circuit . circuit_id <EOL> try : <EOL> del self . _circuit_build_task_dict [ cid ] <EOL> msg = "<STR_LIT>" . format ( cid ) <EOL> logging . debug ( msg ) <EOL> except KeyError : <EOL> try : <EOL> del self . _open_circuit_dict [ cid ] <EOL> msg = "<STR_LIT>" . format ( cid ) <EOL> logging . debug ( msg ) <EOL> except KeyError : <EOL> msg = ( "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" . format ( cid ) ) <EOL> logging . debug ( msg ) <EOL> return <EOL> self . _assignAllPossiblePendingRequests ( ) <EOL> self . _buildCircuitsForOrphanedPendingRequests ( ) <EOL> self . _replenishCircuits ( ) <EOL> def circuitOpened ( self , circuit ) : <EOL> '''<STR_LIT>''' <EOL> msg = ( "<STR_LIT>" <EOL> . format ( circuit . circuit_id ) ) <EOL> logging . debug ( msg ) <EOL> try : <EOL> del self . _circuit_build_task_dict [ circuit . circuit_id ] <EOL> except KeyError : <EOL> msg = ( "<STR_LIT>" <EOL> . format ( circuit . circuit_id ) ) <EOL> logging . debug ( msg ) <EOL> return <EOL> self . _open_circuit_dict [ circuit . circuit_id ] = circuit <EOL> self . _assignPossiblePendingRequestsToCircuit ( circuit ) <EOL> self . _notifyUserCircuitOpened ( ) <EOL> def destroyAllCircuits ( self , destroy_pending_streams = True ) : <EOL> '''<STR_LIT>''' <EOL> msg = "<STR_LIT>" <EOL> msg += "<STR_LIT>" <EOL> logging . debug ( msg ) <EOL> if destroy_pending_streams is True : <EOL> self . _pending_stream_list = [ ] <EOL> for circuit in self . _open_circuit_dict . values ( ) : <EOL> circuit . destroyCircuitFromManager ( ) <EOL> for circuit in self . _circuit_build_task_dict . values ( ) : <EOL> circuit . destroyCircuitFromManager ( ) <EOL> def _buildCircuitsForOrphanedPendingRequests ( self ) : <EOL> orphaned_streams = [ s for s in self . _pending_stream_list <EOL> if len ( self . _getPendingCandidates ( s . request ) ) == <NUM_LIT:0> ] <EOL> self . _buildCircuitsForPendingStreams ( orphaned_streams ) <EOL> def _notifyUserCircuitOpened ( self ) : <EOL> if self . _sent_open_message is False : <EOL> msg = "<STR_LIT>" <EOL> msg += "<STR_LIT>" <EOL> logging . info ( msg ) <EOL> self . _sent_open_message = True <EOL> def _assignAllPossiblePendingRequests ( self ) : <EOL> for circuit in self . _open_circuit_dict . values ( ) : <EOL> self . _assignPossiblePendingRequestsToCircuit ( circuit ) <EOL> def _buildCircuit ( self , circuit_type = CircuitType . IPv4 , request = None , <EOL> autobuild = True ) : <EOL> _id = next ( self . _ctr ) <EOL> task = CircuitBuildTask ( self . _connection_manager , self , self . _netstatus , <EOL> self . _guard_manager , _id , <EOL> circuit_type = circuit_type , request = request , <EOL> autobuild = autobuild ) <EOL> self . _circuit_build_task_dict [ _id ] = task <EOL> def _buildCircuits ( self , count , circuit_type = CircuitType . IPv4 , <EOL> request = None , autobuild = True ) : <EOL> for _ in xrange ( count ) : <EOL> self . _buildCircuit ( circuit_type = circuit_type , request = request , <EOL> autobuild = autobuild ) <EOL> def _buildCircuitsForPendingStreams ( self , pending_streams ) : <EOL> for p in pending_streams : <EOL> self . _buildCircuit ( request = p . request ) <EOL> def _assignPossiblePendingRequestsToCircuit ( self , circuit ) : <EOL> '''<STR_LIT>''' <EOL> for pending_stream in self . _pending_stream_list [ : ] : <EOL> request = pending_stream . stream . request <EOL> if circuit . canHandleRequest ( request ) : <EOL> msg = ( "<STR_LIT>" <EOL> . format ( circuit . circuit_id ) ) <EOL> logging . debug ( msg ) <EOL> pending_stream . deferred . callback ( circuit ) <EOL> self . _pending_stream_list . remove ( pending_stream ) <EOL> def _replenishCircuits ( self ) : <EOL> '''<STR_LIT>''' <EOL> if self . _totalIPv4Count ( ) < self . _min_IPv4_count : <EOL> msg = "<STR_LIT>" <EOL> logging . debug ( msg ) <EOL> self . _buildCircuit ( circuit_type = CircuitType . IPv4 ) <EOL> if self . _totalIPv6Count ( ) < self . _min_IPv6_count : <EOL> msg = "<STR_LIT>" <EOL> logging . debug ( msg ) <EOL> self . _buildCircuit ( circuit_type = CircuitType . IPv6 ) <EOL> def _openIPv4Count ( self ) : <EOL> '''<STR_LIT>''' <EOL> return len ( [ i for i in self . _open_circuit_dict . values ( ) <EOL> if i . circuit_type == CircuitType . IPv4 ] ) <EOL> def _openIPv6Count ( self ) : <EOL> '''<STR_LIT>''' <EOL> return len ( [ i for i in self . _open_circuit_dict . values ( ) <EOL> if i . circuit_type == CircuitType . IPv6 ] ) <EOL> def _pendingIPv4Count ( self ) : <EOL> '''<STR_LIT>''' <EOL> return len ( [ i for i in self . _circuit_build_task_dict . values ( ) <EOL> if i . circuit_type == CircuitType . IPv4 ] ) <EOL> def _pendingIPv6Count ( self ) : <EOL> '''<STR_LIT>''' <EOL> return len ( [ i for i in self . _circuit_build_task_dict . values ( ) <EOL> if i . circuit_type == CircuitType . IPv6 ] ) <EOL> def _totalIPv4Count ( self ) : <EOL> '''<STR_LIT>''' <EOL> return self . _openIPv4Count ( ) + self . _pendingIPv4Count ( ) <EOL> def _totalIPv6Count ( self ) : <EOL> '''<STR_LIT>''' <EOL> return self . _openIPv6Count ( ) + self . _pendingIPv6Count ( ) <EOL> def _getOpenCandidates ( self , request ) : <EOL> '''<STR_LIT>''' <EOL> return [ i for i in self . _open_circuit_dict . values ( ) <EOL> if i . canHandleRequest ( request ) ] <EOL> def _getPendingCandidates ( self , request ) : <EOL> '''<STR_LIT>''' <EOL> return [ i for i in self . _circuit_build_task_dict . values ( ) <EOL> if i . canHandleRequest ( request ) ] </s>
