def testOrdering(self): t = Target() p1 = send(t).one(1) p2 = send(t).two(3, k="extra") self.failIf(t.calls) def _check1(res): # we can't check t.calls here: the when() clause is not # guaranteed to fire before the second send. self.failUnlessEqual(res, 2) when(p1).addCallback(_check1) def _check2(res): self.failUnlessEqual(res, None) when(p2).addCallback(_check2) def _check3(res): self.failUnlessEqual(t.calls, [ ("one", 1), ("two", 3, 2, { "k": "extra" }), ]) fireEventually().addCallback(_check3)
def testFire(self): results = [] fireEventually(1).addCallback(results.append) fireEventually(2).addCallback(results.append) self.failIf(results) def _check(res): self.failUnlessEqual(results, [1, 2]) d = flushEventualQueue() d.addCallback(_check) return d
def callRemote(self, methname, *args, **kwargs): def _try(ignored): meth = getattr(self.original, "remote_" + methname) return meth(*args, **kwargs) d = fireEventually() d.addCallback(_try) return d
def startService(self): service.MultiService.startService(self) for d,sturdy in self._pending_getReferences: d1 = eventual.fireEventually(sturdy) d1.addCallback(self.getReference) d1.addBoth(lambda res, d=d: d.callback(res)) del self._pending_getReferences for rc in self.reconnectors: eventual.eventually(rc.startConnecting, self)
def testOrdering(self): t = Target() p1 = send(t).one(1) p2 = send(t).two(3, k="extra") self.failIf(t.calls) def _check1(res): # we can't check t.calls here: the when() clause is not # guaranteed to fire before the second send. self.failUnlessEqual(res, 2) when(p1).addCallback(_check1) def _check2(res): self.failUnlessEqual(res, None) when(p2).addCallback(_check2) def _check3(res): self.failUnlessEqual(t.calls, [("one", 1), ("two", 3, 2, {"k": "extra"}), ]) fireEventually().addCallback(_check3)
def startService(self): service.MultiService.startService(self) for d, sturdy in self._pending_getReferences: d1 = eventual.fireEventually(sturdy) d1.addCallback(self.getReference) d1.addBoth(lambda res, d=d: d.callback(res)) del self._pending_getReferences for rc in self.reconnectors: eventual.eventually(rc.startConnecting, self)
def test_5_overdue_immutable(self): # restrict the ShareFinder to only allow 5 outstanding requests, and # arrange for the first 5 servers to hang. Then trigger the OVERDUE # timers (simulating 10 seconds passed), at which point the # ShareFinder should send additional queries and finish the download # quickly. If we didn't have OVERDUE timers, this test would fail by # timing out. done = [] d = self._set_up(False, "test_5_overdue_immutable") def _reduce_max_outstanding_requests_and_download(ign): self._hang_shares(range(5)) n = self.c0.create_node_from_uri(self.uri) n._cnode._maybe_create_download_node() self._sf = n._cnode._node._sharefinder self._sf.max_outstanding_requests = 5 self._sf.OVERDUE_TIMEOUT = 1000.0 d2 = download_to_data(n) # start download, but don't wait for it to complete yet def _done(res): done.append(res) # we will poll for this later d2.addBoth(_done) d.addCallback(_reduce_max_outstanding_requests_and_download) from foolscap.eventual import fireEventually, flushEventualQueue # wait here a while d.addCallback(lambda res: fireEventually(res)) d.addCallback(lambda res: flushEventualQueue()) d.addCallback(lambda ign: self.failIf(done)) def _check_waiting(ign): # all the share requests should now be stuck waiting self.failUnlessEqual(len(self._sf.pending_requests), 5) # but none should be marked as OVERDUE until the timers expire self.failUnlessEqual(len(self._sf.overdue_requests), 0) d.addCallback(_check_waiting) def _mark_overdue(ign): # declare four requests overdue, allowing new requests to take # their place, and leaving one stuck. The finder will keep # sending requests until there are 5 non-overdue ones # outstanding, at which point we'll have 4 OVERDUE, 1 # stuck-but-not-overdue, and 4 live requests. All 4 live requests # will retire before the download is complete and the ShareFinder # is shut off. That will leave 4 OVERDUE and 1 # stuck-but-not-overdue, for a total of 5 requests in in # _sf.pending_requests for t in self._sf.overdue_timers.values()[:4]: t.reset(-1.0) # the timers ought to fire before the eventual-send does return fireEventually() d.addCallback(_mark_overdue) def _we_are_done(): return bool(done) d.addCallback(lambda ign: self.poll(_we_are_done)) def _check_done(ign): self.failUnlessEqual(done, [immutable_plaintext]) self.failUnlessEqual(len(self._sf.pending_requests), 5) self.failUnlessEqual(len(self._sf.overdue_requests), 4) d.addCallback(_check_done) return d
def _mark_overdue(ign): # declare four requests overdue, allowing new requests to take # their place, and leaving one stuck. The finder will keep # sending requests until there are 5 non-overdue ones # outstanding, at which point we'll have 4 OVERDUE, 1 # stuck-but-not-overdue, and 4 live requests. All 4 live requests # will retire before the download is complete and the ShareFinder # is shut off. That will leave 4 OVERDUE and 1 # stuck-but-not-overdue, for a total of 5 requests in in # _sf.pending_requests for t in self._sf.overdue_timers.values()[:4]: t.reset(-1.0) # the timers ought to fire before the eventual-send does return fireEventually()
def _mark_overdue(ign): # declare four requests overdue, allowing new requests to take # their place, and leaving one stuck. The finder will keep # sending requests until there are 5 non-overdue ones # outstanding, at which point we'll have 4 OVERDUE, 1 # stuck-but-not-overdue, and 4 live requests. All 4 live requests # will retire before the download is complete and the ShareFinder # is shut off. That will leave 4 OVERDUE and 1 # stuck-but-not-overdue, for a total of 5 requests in in # _sf.pending_requests for t in list(self._sf.overdue_timers.values())[:4]: t.reset(-1.0) # the timers ought to fire before the eventual-send does return fireEventually()
def setLocationAutomatically(self, *extra_addresses): """Determine one of this host's publically-visible IP addresses and use it to set our location. This uses whatever source address would be used to get to a well-known public host (A.ROOT-SERVERS.NET), which is effectively the interface on which a default route lives. This is neither very pretty (IP address instead of hostname) nor guaranteed to work (it may very well be a 192.168 'private' address), but for publically-visible hosts this will probably produce a useable FURL. This method returns a Deferred that will fire once the location is actually established. Calls to registerReference() must be put off until the location has been set. And of course, you must call listenOn() before calling setLocationAutomatically().""" # first, make sure the reactor is actually running, by using the # eventual-send queue d = eventual.fireEventually() def _reactor_running(res): assert self.running # we can't use get_local_ip_for until the reactor is running return util.get_local_ip_for() d.addCallback(_reactor_running) def _got_local_ip(local_address): local_addresses = set(extra_addresses) if local_address: local_addresses.add(local_address) local_addresses.add("127.0.0.1") locations = set() for l in self.getListeners(): portnum = l.getPortnum() for addr in local_addresses: locations.add("%s:%d" % (addr, portnum)) locations = list(locations) locations.sort() assert len(locations) >= 1 location = ",".join(locations) self.setLocation(location) d.addCallback(_got_local_ip) return d
def test_simple(self): d1 = eventual.fireEventually(None) a = util.AsyncAND([d1]) self.attach(a) a.addBoth(self.shouldFire) return a
def whenFired(self): if self._fired: return eventual.fireEventually(self._result) d = defer.Deferred() self._watchers.append(d) return d
def insert_turns(self, res, count): d = eventual.fireEventually(res) for i in range(count-1): d.addCallback(eventual.fireEventually) return d
def remote_one(self): d = self.tub.stopService() d.addBoth(lambda r: fireEventually(r)) d.addBoth(self.done_d.callback)
def run(self, options): d = fireEventually(options) d.addCallback(self.start) d.addErrback(self._error) print "starting.." reactor.run()
#!/usr/bin/env python from __future__ import print_function from foolscap import Tub, eventual from twisted.internet import reactor import sys import pprint def oops(f): print("ERROR") print(f) def fetch(furl): t = Tub() t.startService() d = t.getReference(furl) d.addCallback(lambda rref: rref.callRemote("get_averages")) d.addCallback(pprint.pprint) return d d = eventual.fireEventually(sys.argv[1]) d.addCallback(fetch) d.addErrback(oops) d.addBoth(lambda res: reactor.stop()) reactor.run()
def insert_turns(self, res, count): d = eventual.fireEventually(res) for i in range(count - 1): d.addCallback(eventual.fireEventually) return d