def session(): from connection import Connection from session import Session from link import link, Sender, Receiver from protocol import Fragment, Linkage a = Connection(lambda n: Session(n, link)) a.tracing = set(["ops", "err"]) a.id = "A" b = Connection(lambda n: Session(n, link)) b.tracing = set(["err"]) b.id = "B" ssn = Session("test", link) a.add(ssn) ssn.begin() # nss = Session("test", link) # b.add(nss) def pump(): a.tick() b.tick() b.write(a.read()) a.write(b.read()) pump() nss = [s for s in b.incoming.values() if s.name == "test"][0] nss.begin() snd = Sender("L", "S", "T") ssn.add(snd) rcv = Receiver("L", "S", "T") nss.add(rcv) snd.attach() rcv.attach() rcv.flow(10) pump() snd.send(fragments=Fragment(True, True, 0, 0, "m1")) snd.send(fragments=Fragment(True, True, 0, 0, "m2")) dt3 = snd.send(fragments=Fragment(True, True, 0, 0, "m3")) pump() print "PENDING", rcv.pending() pump() snd.send(fragments=Fragment(True, True, 0, 0, "m4")) pump() xfrs = [] while rcv.pending(): x = rcv.get() xfrs.append(x) print "XFR", x rcv.disposition(xfrs[-1].delivery_tag, "ACCEPTED") pump() snd.send(fragments=Fragment(True, True, 0, 0, "m5")) pump() rcv.disposition(xfrs[0].delivery_tag, "ACCEPTED") print "----------" pump() print "----------" print "ssn.outgoing:", ssn.outgoing print "snd.unsettled:", snd.unsettled for xfr in xfrs[1:-1]: rcv.disposition(xfr.delivery_tag, "ACCEPTED") print "rcv.unsettled", rcv.unsettled print "rcv.pending()", rcv.pending() rcv.disposition(rcv.get().delivery_tag) pump() print "----------" print "ssn.outgoing:", ssn.outgoing print "snd.unsettled:", snd.unsettled print "settling:", dt3 snd.settle(dt3) print "ssn.outgoing:", ssn.outgoing print "snd.unsettled:", snd.unsettled for dt in list(snd.unsettled): snd.settle(dt) snd.detach() rcv.detach() pump() print "ssn.outgoing:", ssn.outgoing print "snd.unsettled:", snd.unsettled
def connection(): from connection import Connection from session import Session from link import Sender, Receiver, link from protocol import Fragment, Linkage a = Connection(lambda n: Session(n, link)) b = Connection(lambda n: Session(n, link)) a.id = "A" a.tracing = set(["ops", "err"]) b.id = "B" b.tracing = set(["ops", "err"]) def pump(): while a.pending() or b.pending(): b.write(a.read()) a.write(b.read()) s = Session("test-ssn", link) a.add(s) s2 = Session("test-ssn2", link) a.add(s2) a.open(hostname="asdf") b.open() s.begin() s2.begin() l = Sender("qwer", local=Linkage("S", "T")) s.add(l) l.attach() pump() bssn = [x for x in b.incoming.values() if x.name == "test-ssn"][0] bssn.begin() bl = bssn.links["qwer"] bl.attach() bl.flow(10) pump() l.settle(l.send(fragments=Fragment(True, True, 0, 0, "asdf"))) tag = l.send(delivery_tag="blah", fragments=Fragment(True, True, 0, 0, "asdf")) pump() ln = bssn.links["qwer"] x = ln.get() print "INCOMING XFR:", x ln.disposition(x.delivery_tag, "ACCEPTED") xfr = ln.get() print "INCOMING XFR:", xfr ln.disposition(xfr.delivery_tag, "ASDF") print "--" pump() print "--" print "DISPOSITION", l.get_remote(modified=True) l.settle(tag) l.detach() bl.detach() pump() s.end(True) pump() bssn.end(True) s2.end(True) a.close() b.close() pump()
class Session: def __init__(self, connection): self.proto = ProtoSession(link) self.connection = connection self._lock = self.connection._lock self.timeout = 120 self.txn = None self.proto.begin() def wait(self, predicate, timeout=DEFAULT): if timeout is DEFAULT: self.timeout = timeout self.connection.wait(predicate, timeout) @synchronized def sender(self, target, name=None, unsettled=None): if isinstance(target, basestring): target = Target(address=target) snd = Sender(self.connection, name or str(uuid4()), target) self.proto.add(snd.proto) for k, v in (unsettled or {}).items(): snd.proto.resume(k, v) snd.proto.attach() self.wait(lambda: snd.proto.attached() or snd.proto.detaching()) if snd.proto.remote_target is None: snd.close() raise LinkError("no such target: %s" % target) else: snd.address = getattr(snd.proto.remote_target, "address", None) snd.unsettled = snd.proto.remote_unsettled() return snd @synchronized def receiver(self, source, limit=0, drain=False, name=None, unsettled=None): if isinstance(source, basestring): source = Source(address=source) rcv = Receiver(self.connection, name or str(uuid4()), source) self.proto.add(rcv.proto) if limit: rcv.flow(limit, drain=drain) for k, v in (unsettled or {}).items(): rcv.proto.resume(k, v) rcv.proto.attach() self.wait(lambda: rcv.proto.attached() or rcv.proto.attaching()) if rcv.proto.remote_source is None: rcv.close() raise LinkError("no such source: %s" % source) else: rcv.address = getattr(rcv.proto.remote_source, "address", None) rcv.unsettled = rcv.proto.remote_unsettled() return rcv @synchronized def incoming_window(self): return self.proto.incoming_window(self) @synchronized def set_incoming_window(self, *args, **kwargs): return self.proto.set_incoming_window(*args, **kwargs) def _txn_link(self): if self.txn is None: self.txn = self.sender(Coordinator(), "txn-%s" % uuid4()) @synchronized def declare(self, timeout=None): self._txn_link() self.txn.send(Message(Declare(), delivery_tag="declare")) for t, l, r in self.txn.pending(block=True, timeout=timeout): if t == "declare": self.txn.settle(t) return r.state.txn_id else: raise SessionError("transaction declare failed") @synchronized def discharge(self, txn, fail=False, timeout=None): self._txn_link() self.txn.send(Message(Discharge(txn_id=txn, fail=fail), delivery_tag="discharge")) for t, l, r in self.txn.pending(block=True, timeout=timeout): if t == "discharge": self.txn.settle(t) break else: raise SessionError("transaction discharge failed") @synchronized def close(self): self.proto.end()