def fetch(path, url, state):
agent = OnionRoutedAgent(reactor, path=path, state=state)
request = agent.request("GET", url)
reactor.callLater(10, request.cancel)
request.addCallback(readBody)
def parse_ip(body):
exit_ip = path[-1].ip
try:
checked_ip = re.search("<strong>(.*)</strong>", body).group(1)
return exit_ip, checked_ip
except AttributeError:
return exit_ip, None
request.addCallback(parse_ip)
def err(failure):
failure.trap(defer.CancelledError, ResponseNeverReceived,
ResponseFailed, HostUnreachable, TTLExpired)
log.err(failure)
request.addErrback(err)
return request
python类CancelledError()的实例源码
def test_clientConnectionFailed(self):
"""
When a client connection fails, the service removes its reference
to the protocol and tries again after a timeout.
"""
clock = Clock()
cq, service = self.makeReconnector(fireImmediately=False,
clock=clock)
self.assertEqual(len(cq.connectQueue), 1)
cq.connectQueue[0].errback(Failure(Exception()))
whenConnected = service.whenConnected()
self.assertNoResult(whenConnected)
# Don't fail during test tear-down when service shutdown causes all
# waiting connections to fail.
whenConnected.addErrback(lambda ignored: ignored.trap(CancelledError))
clock.advance(AT_LEAST_ONE_ATTEMPT)
self.assertEqual(len(cq.connectQueue), 2)
def test_whenConnectedErrbacksOnStopService(self):
"""
L{ClientService.whenConnected} returns a L{Deferred} that
errbacks with L{CancelledError} if
L{ClientService.stopService} is called between connection
attempts.
"""
clock = Clock()
cq, service = self.makeReconnector(fireImmediately=False,
clock=clock)
beforeErrbackAndStop = service.whenConnected()
# The protocol fails to connect, and the service is waiting to
# reconnect.
cq.connectQueue[0].errback(Exception("no connection"))
service.stopService()
afterErrbackAndStop = service.whenConnected()
self.assertIsInstance(self.failureResultOf(beforeErrbackAndStop).value,
CancelledError)
self.assertIsInstance(self.failureResultOf(afterErrbackAndStop).value,
CancelledError)
def test_execCancelled(self):
"""
If execution of the command is cancelled via the L{Deferred} returned
by L{SSHCommandClientEndpoint.connect}, the connection is closed
immediately.
"""
self.realm.channelLookup[b'session'] = UnsatisfiedExecSession
endpoint = self.create()
factory = Factory()
factory.protocol = Protocol
connected = endpoint.connect(factory)
server, client, pump = self.finishConnection()
connected.cancel()
f = self.failureResultOf(connected)
f.trap(CancelledError)
self.assertClientTransportState(client, True)
def test_cancelGetConnectionCancelsEndpointConnect(self):
"""
Cancelling the C{Deferred} returned from
L{HTTPConnectionPool.getConnection} cancels the C{Deferred} returned
by opening a new connection with the given endpoint.
"""
self.assertEqual(self.pool._connections, {})
connectionResult = Deferred()
class Endpoint:
def connect(self, factory):
return connectionResult
d = self.pool.getConnection(12345, Endpoint())
d.cancel()
self.assertEqual(self.failureResultOf(connectionResult).type,
CancelledError)
def test_deprecatedTransport(self):
"""
Calling L{client.readBody} with a transport that does not implement
L{twisted.internet.interfaces.ITCPTransport} produces a deprecation
warning, but no exception when cancelling.
"""
response = DummyResponse(transportFactory=StringTransport)
response.transport.abortConnection = None
d = self.assertWarns(
DeprecationWarning,
'Using readBody with a transport that does not have an '
'abortConnection method',
__file__,
lambda: client.readBody(response))
d.cancel()
self.failureResultOf(d, defer.CancelledError)
def _cancelConnectTest(self, connect):
"""
Helper for implementing a test to verify that cancellation of the
L{Deferred} returned by one of L{ClientCreator}'s I{connect} methods is
implemented to cancel the underlying connector.
@param connect: A function which will be invoked with a L{ClientCreator}
instance as an argument and which should call one its I{connect}
methods and return the result.
@return: A L{Deferred} which fires when the test is complete or fails if
there is a problem.
"""
reactor = MemoryReactorClock()
cc = ClientCreator(reactor, Protocol)
d = connect(cc)
connector = reactor.connectors.pop()
self.assertFalse(connector._disconnected)
d.cancel()
self.assertTrue(connector._disconnected)
return self.assertFailure(d, CancelledError)
def test_cancelConnectTCPTimeout(self):
"""
L{ClientCreator.connectTCP} inserts a very short delayed call between
the time the connection is established and the time the L{Deferred}
returned from one of its connect methods actually fires. If the
L{Deferred} is cancelled in this interval, the established connection is
closed, the timeout is cancelled, and the L{Deferred} fails with
L{CancelledError}.
"""
def connect(reactor, cc):
d = cc.connectTCP('example.com', 1234)
host, port, factory, timeout, bindAddress = reactor.tcpClients.pop()
protocol = factory.buildProtocol(None)
transport = StringTransport()
protocol.makeConnection(transport)
return d
return self._cancelConnectTimeoutTest(connect)
def test_cancelConnectUNIXTimeout(self):
"""
L{ClientCreator.connectUNIX} inserts a very short delayed call between
the time the connection is established and the time the L{Deferred}
returned from one of its connect methods actually fires. If the
L{Deferred} is cancelled in this interval, the established connection is
closed, the timeout is cancelled, and the L{Deferred} fails with
L{CancelledError}.
"""
def connect(reactor, cc):
d = cc.connectUNIX('/foo/bar')
address, factory, timeout, bindAddress = reactor.unixClients.pop()
protocol = factory.buildProtocol(None)
transport = StringTransport()
protocol.makeConnection(transport)
return d
return self._cancelConnectTimeoutTest(connect)
def test_cancelConnectSSLTimeout(self):
"""
L{ClientCreator.connectSSL} inserts a very short delayed call between
the time the connection is established and the time the L{Deferred}
returned from one of its connect methods actually fires. If the
L{Deferred} is cancelled in this interval, the established connection is
closed, the timeout is cancelled, and the L{Deferred} fails with
L{CancelledError}.
"""
def connect(reactor, cc):
d = cc.connectSSL('example.com', 1234, object())
host, port, factory, contextFactory, timeout, bindADdress = reactor.sslClients.pop()
protocol = factory.buildProtocol(None)
transport = StringTransport()
protocol.makeConnection(transport)
return d
return self._cancelConnectTimeoutTest(connect)
def _cancelConnectFailedTimeoutTest(self, connect):
"""
Like L{_cancelConnectTest}, but for the case where the L{Deferred} is
cancelled after the connection attempt has failed but before it is fired
with the resulting failure.
"""
reactor = MemoryReactorClock()
cc = ClientCreator(reactor, Protocol)
d, factory = connect(reactor, cc)
connector = reactor.connectors.pop()
factory.clientConnectionFailed(
connector, Failure(Exception("Simulated failure")))
# Sanity check - there is an outstanding delayed call to fire the
# Deferred.
self.assertEqual(len(reactor.getDelayedCalls()), 1)
# Cancel the Deferred, cancelling the delayed call.
d.cancel()
self.assertEqual(reactor.getDelayedCalls(), [])
return self.assertFailure(d, CancelledError)
def test_cancel(self):
"""
The L{Deferred} returned by L{task.deferLater} can be
cancelled to prevent the call from actually being performed.
"""
called = []
clock = task.Clock()
d = task.deferLater(clock, 1, called.append, None)
d.cancel()
def cbCancelled(ignored):
# Make sure there are no calls outstanding.
self.assertEqual([], clock.getDelayedCalls())
# And make sure the call didn't somehow happen already.
self.assertFalse(called)
self.assertFailure(d, defer.CancelledError)
d.addCallback(cbCancelled)
return d
def test_cancelDeferredListCallback(self):
"""
When cancelling an unfired L{defer.DeferredList} without the
C{fireOnOneCallback} and C{fireOnOneErrback} flags set, the
L{defer.DeferredList} will be callback with a C{list} of
(success, result) C{tuple}s.
"""
deferredOne = defer.Deferred(fakeCallbackCanceller)
deferredTwo = defer.Deferred()
deferredList = defer.DeferredList([deferredOne, deferredTwo])
deferredList.cancel()
self.failureResultOf(deferredTwo, defer.CancelledError)
result = self.successResultOf(deferredList)
self.assertTrue(result[0][0])
self.assertEqual(result[0][1], "Callback Result")
self.assertFalse(result[1][0])
self.assertTrue(result[1][1].check(defer.CancelledError))
def test_cancelDeferredListWithFireOnOneErrback(self):
"""
When cancelling an unfired L{defer.DeferredList} with the flag
C{fireOnOneErrback} set, cancel every L{defer.Deferred} in the list.
"""
deferredOne = defer.Deferred()
deferredTwo = defer.Deferred()
deferredList = defer.DeferredList([deferredOne, deferredTwo],
fireOnOneErrback=True)
deferredList.cancel()
self.failureResultOf(deferredOne, defer.CancelledError)
self.failureResultOf(deferredTwo, defer.CancelledError)
deferredListFailure = self.failureResultOf(deferredList,
defer.FirstError)
firstError = deferredListFailure.value
self.assertTrue(firstError.subFailure.check(defer.CancelledError))
def test_noCancellerMultipleCancelsAfterCancelAndErrback(self):
"""
A L{defer.Deferred} without a canceller, when cancelled and then
errbacked, ignores multiple cancels thereafter.
"""
d = defer.Deferred()
d.addCallbacks(self._callback, self._errback)
d.cancel()
self.assertEqual(self.errbackResults.type, defer.CancelledError)
currentFailure = self.errbackResults
# One errback will be ignored
d.errback(GenericError())
# I.e., we should still have a CancelledError.
self.assertEqual(self.errbackResults.type, defer.CancelledError)
d.cancel()
self.assertIs(currentFailure, self.errbackResults)
def test_cancellerMultipleCancel(self):
"""
Verify that calling cancel multiple times on a deferred with a
canceller that does not errback results in a
L{defer.CancelledError} and that subsequent calls to cancel do not
cause an error and that after all that, the canceller was only
called once.
"""
def cancel(d):
self.cancellerCallCount += 1
d = defer.Deferred(canceller=cancel)
d.addCallbacks(self._callback, self._errback)
d.cancel()
self.assertEqual(self.errbackResults.type, defer.CancelledError)
currentFailure = self.errbackResults
d.cancel()
self.assertIs(currentFailure, self.errbackResults)
self.assertEqual(self.cancellerCallCount, 1)
def test_cancelNestedDeferred(self):
"""
Verify that a Deferred, a, which is waiting on another Deferred, b,
returned from one of its callbacks, will propagate
L{defer.CancelledError} when a is cancelled.
"""
def innerCancel(d):
self.cancellerCallCount += 1
def cancel(d):
self.assertTrue(False)
b = defer.Deferred(canceller=innerCancel)
a = defer.Deferred(canceller=cancel)
a.callback(None)
a.addCallback(lambda data: b)
a.cancel()
a.addCallbacks(self._callback, self._errback)
# The cancel count should be one (the cancellation done by B)
self.assertEqual(self.cancellerCallCount, 1)
# B's canceller didn't errback, so defer.py will have called errback
# with a CancelledError.
self.assertEqual(self.errbackResults.type, defer.CancelledError)
def test_errbackAddedBeforeTimeout(self):
"""
An errback added before a timeout is added errbacks with a
L{defer.CancelledError} when the timeout fires. If the
errback returns the L{defer.CancelledError}, it is translated
to a L{defer.TimeoutError} by the timeout implementation.
"""
clock = Clock()
d = defer.Deferred()
dErrbacked = [None]
def errback(f):
dErrbacked[0] = f
return f
d.addErrback(errback)
d.addTimeout(10, clock)
clock.advance(15)
self.assertIsInstance(dErrbacked[0], failure.Failure)
self.assertIsInstance(dErrbacked[0].value, defer.CancelledError)
self.failureResultOf(d, defer.TimeoutError)
def test_errbackAddedBeforeTimeoutCustom(self):
"""
An errback added before a timeout is added with a custom
timeout function errbacks with a L{defer.CancelledError} when
the timeout fires. The timeout function runs if the errback
returns the L{defer.CancelledError}.
"""
clock = Clock()
d = defer.Deferred()
dErrbacked = [None]
def errback(f):
dErrbacked[0] = f
return f
d.addErrback(errback)
d.addTimeout(10, clock, _overrideFunc)
clock.advance(15)
self.assertIsInstance(dErrbacked[0], failure.Failure)
self.assertIsInstance(dErrbacked[0].value, defer.CancelledError)
self.assertEqual("OVERRIDDEN", self.successResultOf(d))
def test_errbackAddedBeforeTimeoutSuppressesCancellationCustom(self):
"""
An errback added before a timeout is added with a custom
timeout function errbacks with a L{defer.CancelledError} when
the timeout fires. The timeout function runs if the errback
suppresses the L{defer.CancelledError}.
"""
clock = Clock()
d = defer.Deferred()
dErrbacked = [None]
def errback(f):
dErrbacked[0] = f
d.addErrback(errback)
d.addTimeout(10, clock, _overrideFunc)
clock.advance(15)
self.assertIsInstance(dErrbacked[0], failure.Failure)
self.assertIsInstance(dErrbacked[0].value, defer.CancelledError)
self.assertEqual("OVERRIDDEN", self.successResultOf(d))
def test_routeHandlesRequestFinished(self):
app = self.app
request = requestMock(b"/")
cancelled = []
@app.route("/")
def root(request):
_d = Deferred()
_d.addErrback(cancelled.append)
request.notifyFinish().addCallback(lambda _: _d.cancel())
return _d
d = _render(self.kr, request)
request.finish()
self.assertFired(d)
cancelled[0].trap(CancelledError)
self.assertEqual(request.getWrittenData(), b'')
self.assertEqual(request.writeCount, 1)
self.assertEqual(request.processingFailed.call_count, 0)
def test_cancelsOnConnectionLost(self):
app = self.app
request = requestMock(b"/")
handler_d = Deferred()
@app.route("/")
def root(request):
return handler_d
d = _render(self.kr, request)
self.assertNotFired(d)
request.connectionLost(ConnectionLost())
handler_d.addErrback(lambda f: f.trap(CancelledError))
d.addErrback(lambda f: f.trap(ConnectionLost))
d.addCallback(lambda _: handler_d)
self.assertFired(d)
def close(self, reason=None, within=0):
"""Explicitely close the connection.
@param reason: Optional closing reason. If not given, ConnectionDone
will be used.
@param within: Shutdown the client within this amount of seconds. If
zero (the default), all channels and queues will be closed
immediately. If greater than 0, try to close the AMQP connection
cleanly, by sending a "close" method and waiting for "close-ok". If
no reply is received within the given amount of seconds, the
transport will be forcely shutdown.
"""
if self.closed:
return
if reason is None:
reason = ConnectionDone()
if within > 0:
channel0 = yield self.channel(0)
deferred = channel0.connection_close()
call = self.clock.callLater(within, deferred.cancel)
try:
yield deferred
except defer.CancelledError:
pass
else:
call.cancel()
self.do_close(reason)
def start(self, period):
assert not self.running
self.running = True
self._df = self._worker(period).addErrback(lambda fail: fail.trap(defer.CancelledError))
def watch(self, keys, on_watch, filters=None, start_revision=None, return_previous=None):
"""
Watch one or more keys or key sets and invoke a callback.
Watch watches for events happening or that have happened. The entire event history
can be watched starting from the last compaction revision.
:param keys: Watch these keys / key sets.
:type keys: list of bytes or list of instance of :class:`txaioetcd.KeySet`
:param on_watch: The callback to invoke upon receiving
a watch event.
:type on_watch: callable
:param start_revision: start_revision is an optional
revision to watch from (inclusive). No start_revision is "now".
:type start_revision: int
"""
d = self._start_watching(keys, on_watch, filters, start_revision, return_previous)
def on_err(err):
if err.type == CancelledError:
# swallow canceling!
pass
else:
return err
d.addErrback(on_err)
return d
def start(self, period):
assert not self.running
self.running = True
self._df = self._worker(period).addErrback(lambda fail: fail.trap(defer.CancelledError))
def failed(self, failure, job_id):
if failure.check(CancelledError):
self.job_failed("Response max size exceeded! job id: %s!" % job_id, job_id)
elif failure.check(InvalidResponseRetry):
ex = failure.value
if job_id in self.retry_counter and self.retry_counter[job_id] == self.max_retry:
self.job_failed("Max retry has been reached! job id: %s!" % job_id, job_id)
else:
self.job_failed_retry(ex.message, job_id)
elif failure.check(ResponseNeverReceived):
self.job_failed("No response from the server! job id: %s!" % job_id, job_id)
elif failure.check(ResponseFailed):
# @TODO add retry
self.job_failed("Connection to server failed, retry .... %s!" % job_id, job_id)
elif failure.check(NoResponseContent):
self.job_failed("Response has no content .... %s!" % job_id, job_id)
elif failure.check(TimeoutError):
if job_id in self.retry_counter and self.retry_counter[job_id] == self.max_retry:
self.job_failed("Max retry has been reached! job id: %s!" % job_id, job_id)
else:
self.job_failed_retry("Request timeout .... %s!" % job_id, job_id)
elif failure.check(ConnectionRefusedError):
if job_id in self.retry_counter and self.retry_counter[job_id] == self.max_retry:
self.job_failed("Max retry has been reached! job id: %s!" % job_id, job_id)
else:
self.job_failed_retry("Connection refused .... %s!" % job_id, job_id)
else:
ex = failure.value
self.job_failed("No proper failure found: %s, \n %s!" % (job_id, ex.message), job_id)
failure.printTraceback()
def start(self, period):
assert not self.running
self.running = True
self._df = self._worker(period).addErrback(lambda fail: fail.trap(defer.CancelledError))
def start(self, period):
assert not self.running
self.running = True
self._df = self._worker(period).addErrback(lambda fail: fail.trap(defer.CancelledError))
def start(self, period):
assert not self.running
self.running = True
self._df = self._worker(period).addErrback(lambda fail: fail.trap(defer.CancelledError))