def __init__(self, url, root): self.url = url self.root = root #NOTE: setting long poll connections to not be persistent #This is to correct stability/memory leak issues self.agent = Agent(reactor, persistent=False) self.polling = False
class LongPoller(object): """Polls a long poll URL, reporting any parsed work results to the callback function. """ def __init__(self, url, root): self.url = url self.root = root self.agent = Agent(reactor, persistent=True) self.polling = False def start(self): """Begin requesting data from the LP server, if we aren't already...""" if self.polling: return self.polling = True self._request() def _request(self): if self.polling: d = self.agent.request( "GET", self.url, Headers({"Authorization": [self.root.auth], "User-Agent": [self.root.version]}) ) d.addBoth(self._requestComplete) def stop(self): """Stop polling. This LongPoller probably shouldn't be reused.""" self.polling = False @defer.inlineCallbacks def _requestComplete(self, response): if not self.polling: return if isinstance(response, failure.Failure): self._request() return d = defer.Deferred() response.deliverBody(BodyLoader(d)) try: data = yield d except ResponseFailed: self._request() return try: result = RPCPoller.parse(data) except ValueError: self._request() return except ServerMessage: exctype, value = sys.exc_info()[:2] self.root.runCallback("msg", str(value)) self._request() return self._request() self.root.handleWork(result, True)
class LongPoller(object): """Polls a long poll URL, reporting any parsed work results to the callback function. """ def __init__(self, url, root): self.url = url self.root = root self.agent = Agent(reactor, persistent=True) self.polling = False def start(self): """Begin requesting data from the LP server, if we aren't already...""" if self.polling: return self.polling = True self._request() def _request(self): if self.polling: d = self.agent.request( 'GET', self.url, Headers({ 'Authorization': [self.root.auth], 'User-Agent': [self.root.version] })) d.addBoth(self._requestComplete) def stop(self): """Stop polling. This LongPoller probably shouldn't be reused.""" self.polling = False @defer.inlineCallbacks def _requestComplete(self, response): if not self.polling: return if isinstance(response, failure.Failure): self._request() return d = defer.Deferred() response.deliverBody(BodyLoader(d)) try: data = yield d except ResponseFailed: self._request() return try: result = RPCPoller.parse(data) except ValueError: self._request() return self._request() self.root.handleWork(result, True)
def __init__(self, root): self.root = root self.agent = Agent(reactor, persistent=True) self.askInterval = None self.askCall = None self.currentlyAsking = False
class RPCPoller(object): """Polls the root's chosen bitcoind or pool RPC server for work.""" def __init__(self, root): self.root = root self.agent = Agent(reactor, persistent=True) self.askInterval = None self.askCall = None self.currentlyAsking = False def setInterval(self, interval): """Change the interval at which to poll the getwork() function.""" self.askInterval = interval self._startCall() def _startCall(self): self._stopCall() if self.askInterval: self.askCall = reactor.callLater(self.askInterval, self.ask) else: self.askCall = None def _stopCall(self): if self.askCall: try: self.askCall.cancel() except (error.AlreadyCancelled, error.AlreadyCalled): pass except: pass self.askCall = None def ask(self): """Run a getwork request immediately.""" if self.currentlyAsking: return self.currentlyAsking = True self._stopCall() d = self.call("getwork") def errback(failure): if not self.currentlyAsking: return self.currentlyAsking = False if failure.check(ServerMessage): self.root.runCallback("msg", failure.getErrorMessage()) self.root._failure() self._startCall() def errback_delay(x): reactor.callLater(0, errback, x) d.addErrback(errback_delay) def callback(x): if not self.currentlyAsking: return self.currentlyAsking = False try: (headers, result) = x except TypeError: return self.root.handleWork(result) self.root.handleHeaders(headers) self._startCall() # Minor bug in the #3420 patch; you can't start new requests during # callbacks from old ones, so this function has the reactor call it a # little bit later (with no artificial delay) def callback_delay(x): reactor.callLater(0, callback, x) d.addCallback(callback_delay) # since i can't fix the damn idle bug this workaround will have to do # this doesn't need to be cancelled, since it will just throw an # alreadycalled error and silently pass def idleFix(x): try: x.errback(failure.Failure()) except: pass reactor.callLater(15, idleFix, d) @defer.inlineCallbacks def call(self, method, params=[]): """Call the specified remote function.""" body = json.dumps({"method": method, "params": params, "id": 1}) response = yield self.agent.request( "POST", self.root.url, Headers( { "Authorization": [self.root.auth], "User-Agent": [self.root.version], "Content-Type": ["application/json"], } ), StringBodyProducer(body), ) d = defer.Deferred() response.deliverBody(BodyLoader(d)) data = yield d result = self.parse(data) defer.returnValue((response.headers, result)) @classmethod def parse(cls, data): """Attempt to load JSON-RPC data.""" response = json.loads(data) try: message = response["error"]["message"] except (KeyError, TypeError): pass else: raise ServerMessage(message) return response.get("result")
def __init__(self, url, root): self.url = url self.root = root self.agent = Agent(reactor, persistent=True) self.polling = False
class RPCPoller(object): """Polls the root's chosen bitcoind or pool RPC server for work.""" def __init__(self, root): self.root = root self.agent = Agent(reactor, persistent=True) self.askInterval = None self.askCall = None self.currentlyAsking = False def setInterval(self, interval): """Change the interval at which to poll the getwork() function.""" self.askInterval = interval self._startCall() def _startCall(self): self._stopCall() if self.askInterval: self.askCall = reactor.callLater(self.askInterval, self.ask) else: self.askCall = None def _stopCall(self): if self.askCall: try: self.askCall.cancel() except (error.AlreadyCancelled, error.AlreadyCalled): pass except: pass self.askCall = None def ask(self): """Run a getwork request immediately.""" if self.currentlyAsking: return self.currentlyAsking = True self._stopCall() d = self.call('getwork') def errback(failure): if not self.currentlyAsking: return self.currentlyAsking = False if failure.check(ServerMessage): self.root.runCallback('msg', failure.getErrorMessage()) self.root._failure() self._startCall() def errback_delay(x): reactor.callLater(0, errback, x) d.addErrback(errback_delay) def callback(x): if not self.currentlyAsking: return self.currentlyAsking = False try: (headers, result) = x except TypeError: return self.root.handleWork(result) self.root.handleHeaders(headers) self._startCall() # Minor bug in the #3420 patch; you can't start new requests during # callbacks from old ones, so this function has the reactor call it a # little bit later (with no artificial delay) def callback_delay(x): reactor.callLater(0, callback, x) d.addCallback(callback_delay) #since i can't fix the damn idle bug this workaround will have to do #this doesn't need to be cancelled, since it will just throw an #alreadycalled error and silently pass def idleFix(x): try: x.errback(failure.Failure()) except: pass reactor.callLater(15, idleFix, d) @defer.inlineCallbacks def call(self, method, params=[]): """Call the specified remote function.""" body = json.dumps({'method': method, 'params': params, 'id': 1}) response = yield self.agent.request( 'POST', self.root.url, Headers({ 'Authorization': [self.root.auth], 'User-Agent': [self.root.version], 'Content-Type': ['application/json'] }), StringBodyProducer(body)) d = defer.Deferred() response.deliverBody(BodyLoader(d)) data = yield d result = self.parse(data) defer.returnValue((response.headers, result)) @classmethod def parse(cls, data): """Attempt to load JSON-RPC data.""" response = json.loads(data) try: message = response['error']['message'] except (KeyError, TypeError): pass else: raise ServerMessage(message) return response.get('result')
class RPCPoller(object): """Polls the root's chosen bitcoind or pool RPC server for work.""" def __init__(self, root): self.root = root self.agent = Agent(reactor, persistent=True) self.askInterval = None self.askCall = None self.currentlyAsking = False def setInterval(self, interval): """Change the interval at which to poll the getwork() function.""" self.askInterval = interval self._startCall() def _startCall(self): self._stopCall() #if self.currentlyAsking: #return # ask() will _startCall when it finishes if self.askInterval: self.askCall = reactor.callLater(self.askInterval, self.ask) else: self.askCall = None def _stopCall(self): if self.askCall: try: self.askCall.cancel() except (error.AlreadyCancelled, error.AlreadyCalled): pass self.askCall = None def ask(self): """Run a getwork request immediately.""" if self.currentlyAsking: return self.currentlyAsking = True self._stopCall() d = self.call('getwork') def errback(failure): if not self.currentlyAsking: return self.currentlyAsking = False if failure.check(ServerMessage): self.root.runCallback('msg', failure.getErrorMessage()) self.root._failure() self._startCall() def errback_delay(x): reactor.callLater(0, errback, x) d.addErrback(errback_delay) def callback(x): if not self.currentlyAsking: return self.currentlyAsking = False try: (headers, result) = x except TypeError: return self.root.handleWork(result) self.root.handleHeaders(headers) self._startCall() # Minor bug in the #3420 patch; you can't start new requests during # callbacks from old ones, so this function has the reactor call it a # little bit later (with no artificial delay) def callback_delay(x): reactor.callLater(0, callback, x) d.addCallback(callback_delay) @defer.inlineCallbacks def call(self, method, params=[]): """Call the specified remote function.""" body = json.dumps({'method': method, 'params': params, 'id': 1}) response = yield self.agent.request('POST', self.root.url, Headers({ 'Authorization': [self.root.auth], 'User-Agent': [self.root.version], 'Content-Type': ['application/json'] }), StringBodyProducer(body)) d = defer.Deferred() response.deliverBody(BodyLoader(d)) data = yield d result = self.parse(data) defer.returnValue((response.headers, result)) @classmethod def parse(cls, data): """Attempt to load JSON-RPC data.""" response = json.loads(data) try: message = response['error']['message'] except (KeyError, TypeError): pass else: raise ServerMessage(message) return response.get('result')
class RPCPoller(object): """Polls the root's chosen bitcoind or pool RPC server for work.""" def __init__(self, root): self.root = root self.agent = Agent(reactor, persistent=True) self.askInterval = None self.askCall = None self.currentAsk = None def setInterval(self, interval): """Change the interval at which to poll the getwork() function.""" self.askInterval = interval self._startCall() def _startCall(self): self._stopCall() if self.root.disconnected: return if self.askInterval: self.askCall = reactor.callLater(self.askInterval, self.ask) else: self.askCall = None def _stopCall(self): if self.askCall: try: self.askCall.cancel() except (error.AlreadyCancelled, error.AlreadyCalled): pass except: pass self.askCall = None def ask(self): """Run a getwork request immediately.""" if self.currentAsk and not self.currentAsk.called: return self._stopCall() startTime = time() self.currentAsk = self.call('getwork', timeout=15.0) def errback(failure): try: if failure.check(ServerMessage): self.root.runCallback('msg', failure.getErrorMessage()) else: self.root.runCallback('debug', failure.getErrorMessage()) self.root._failure() finally: self._startCall() def errback_delay(x): reactor.callLater(0, errback, x) self.currentAsk.addErrback(errback_delay) def callback(x): try: try: headers, result, metaData = x except TypeError: return endTime = time() self.root.recordGetworkTime(startTime, endTime) self.root.handleWork(result, headers, metaData) self.root.handleHeaders(headers) finally: self._startCall() # Minor bug in the #3420 patch; you can't start new requests during # callbacks from old ones, so this function has the reactor call it a # little bit later (with no artificial delay) def callback_delay(x): reactor.callLater(0, callback, x) self.currentAsk.addCallback(callback_delay) @defer.inlineCallbacks def call(self, method, params=[], timeout=None): """Call the specified remote function.""" body = json.dumps({'method': method, 'params': params, 'id': 1}) headers = { 'Authorization': [self.root.auth], 'User-Agent': [self.root.version], 'Content-Type': ['application/json'] } if method == 'getwork': headers['X-Mining-Hashrate'] = [self.root.getMiningHashrate()] miningExtensions = self.root.handler.getMiningExtensions() if miningExtensions is not None and len(miningExtensions) > 0: headers['X-Mining-Extensions'] = [' '.join(miningExtensions)] startTime = time() response = yield self.agent.request('POST', self.root.url, Headers(headers), StringBodyProducer(body)) d = defer.Deferred() if timeout: def cancelDeferred(): try: d.errback(error.TimeoutError()) except defer.AlreadyCalledError: pass reactor.callLater(timeout, cancelDeferred) response.deliverBody(BodyLoader(d)) endTime = time() data = yield d result = self.parse(data) metaData = {} metaData['receivedAt'] = endTime metaData['duration'] = endTime - startTime defer.returnValue((response.headers, result, metaData)) @classmethod def parse(cls, data): """Attempt to load JSON-RPC data.""" response = json.loads(data) try: message = response['error']['message'] except (KeyError, TypeError): pass else: raise ServerMessage(message) return response.get('result')
class LongPoller(object): """Polls a long poll URL, reporting any parsed work results to the callback function. """ def __init__(self, url, root): self.url = url self.root = root #NOTE: setting long poll connections to not be persistent #This is to correct stability/memory leak issues self.agent = Agent(reactor, persistent=False) self.polling = False def start(self): """Begin requesting data from the LP server, if we aren't already...""" if self.polling: return self.polling = True self._request() def _request(self): if self.polling: d = self.agent.request('GET', self.url, Headers({ 'Authorization': [self.root.auth], 'User-Agent': [self.root.version] })) d.addBoth(self._requestComplete) def stop(self): """Stop polling. This LongPoller probably shouldn't be reused.""" self.polling = False @defer.inlineCallbacks def _requestComplete(self, response): try: if not self.polling: return if isinstance(response, failure.Failure): return d = defer.Deferred() response.deliverBody(BodyLoader(d)) try: data = yield d except ResponseFailed: return try: result = RPCPoller.parse(data) headers = response.headers except ValueError: return except ServerMessage: exctype, value = sys.exc_info()[:2] self.root.runCallback('msg', str(value)) return finally: self._request() self.root.handleWork(result, headers, None, pushed=True)