<s> from twisted . internet import defer <EOL> from twisted . protocols . basic import NetstringReceiver <EOL> from twisted . python import failure , log <EOL> from txjason import protocol , client <EOL> class JSONRPCClientProtocol ( NetstringReceiver ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , factory ) : <EOL> self . factory = factory <EOL> self . deferred = defer . Deferred ( ) <EOL> def stringReceived ( self , string ) : <EOL> try : <EOL> self . factory . client . handleResponse ( string ) <EOL> except client . JSONRPCProtocolError : <EOL> log . err ( ) <EOL> self . transport . loseConnection ( ) <EOL> except : <EOL> log . err ( ) <EOL> def connectionLost ( self , reason ) : <EOL> if self . brokenPeer : <EOL> log . msg ( '<STR_LIT>' ) <EOL> else : <EOL> log . msg ( '<STR_LIT>' ) <EOL> self . deferred . errback ( reason ) <EOL> class JSONRPCServerProtocol ( NetstringReceiver ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , service ) : <EOL> self . service = service <EOL> @ defer . inlineCallbacks <EOL> def stringReceived ( self , string ) : <EOL> result = yield self . service . call ( string ) <EOL> if result is not None : <EOL> self . sendString ( result ) <EOL> class JSONRPCClientFactory ( protocol . BaseClientFactory ) : <EOL> def __init__ ( self , endpoint , timeout = <NUM_LIT:5> , reactor = None ) : <EOL> if reactor is None : <EOL> from twisted . internet import reactor <EOL> self . client = client . JSONRPCClient ( timeout = timeout , reactor = reactor ) <EOL> self . endpoint = endpoint <EOL> self . _proto = None <EOL> self . _waiting = [ ] <EOL> self . _notifyOnDisconnect = [ ] <EOL> self . _connecting = False <EOL> self . _connectionDeferred = None <EOL> self . reactor = reactor <EOL> def buildProtocol ( self , addr ) : <EOL> return JSONRPCClientProtocol ( self ) <EOL> def _cancel ( self , d ) : <EOL> if self . _connectionDeferred is not None : <EOL> self . _connectionDeferred . cancel ( ) <EOL> def _getConnection ( self ) : <EOL> if self . _proto is not None : <EOL> return defer . succeed ( self . _proto ) <EOL> d = defer . Deferred ( self . _cancel ) <EOL> self . _waiting . append ( d ) <EOL> if not self . _connecting : <EOL> self . _connecting = True <EOL> self . _connectionDeferred = ( <EOL> self . endpoint . connect ( self ) <EOL> . addBoth ( self . _gotResult ) <EOL> . addErrback ( log . err , '<STR_LIT>' % ( self , ) ) ) <EOL> return d <EOL> def _gotResult ( self , result ) : <EOL> self . _connecting = False <EOL> if not isinstance ( result , failure . Failure ) : <EOL> self . _proto = result <EOL> self . _proto . deferred . addErrback ( self . _lostProtocol ) <EOL> waiting , self . _waiting = self . _waiting , [ ] <EOL> for d in waiting : <EOL> d . callback ( result ) <EOL> return result <EOL> def _lostProtocol ( self , reason ) : <EOL> log . err ( reason , '<STR_LIT>' % ( self , ) ) <EOL> deferreds , self . _notifyOnDisconnect = self . _notifyOnDisconnect , [ ] <EOL> for d in deferreds : <EOL> d . errback ( reason ) <EOL> self . _proto = None <EOL> self . client . cancelRequests ( ) <EOL> def callRemote ( self , __method , * args , ** kwargs ) : <EOL> connectionDeferred = self . _getConnection ( ) <EOL> def gotConnection ( connection ) : <EOL> payload , requestDeferred = self . client . getRequest ( <EOL> __method , * args , ** kwargs ) <EOL> connection . sendString ( payload ) <EOL> return requestDeferred <EOL> connectionDeferred . addCallback ( gotConnection ) <EOL> return connectionDeferred <EOL> def notifyRemote ( self , __method , * args , ** kwargs ) : <EOL> connectionDeferred = self . _getConnection ( ) <EOL> def gotConnection ( connection ) : <EOL> payload = self . client . getNotification ( __method , * args , ** kwargs ) <EOL> connection . sendString ( payload ) <EOL> connectionDeferred . addCallback ( gotConnection ) <EOL> return connectionDeferred <EOL> def connect ( self ) : <EOL> return self . _getConnection ( ) . addCallback ( lambda ign : None ) <EOL> def disconnect ( self ) : <EOL> if self . _proto : <EOL> self . _proto . transport . abortConnection ( ) <EOL> elif self . _connecting : <EOL> self . _connectionDeferred . cancel ( ) <EOL> def notifyDisconnect ( self ) : <EOL> d = defer . Deferred ( ) <EOL> self . _notifyOnDisconnect . append ( d ) <EOL> return d <EOL> class JSONRPCServerFactory ( protocol . BaseServerFactory ) : <EOL> protocol = JSONRPCServerProtocol </s>
