You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by gs...@apache.org on 2014/08/08 18:50:00 UTC
svn commit: r1616829 [3/3] - in /qpid/proton/branches/examples/tutorial: ./
_build/doctrees/ _build/html/ _build/html/_sources/
Modified: qpid/proton/branches/examples/tutorial/helloworld.py
URL: http://svn.apache.org/viewvc/qpid/proton/branches/examples/tutorial/helloworld.py?rev=1616829&r1=1616828&r2=1616829&view=diff
==============================================================================
--- qpid/proton/branches/examples/tutorial/helloworld.py (original)
+++ qpid/proton/branches/examples/tutorial/helloworld.py Fri Aug 8 16:49:59 2014
@@ -19,18 +19,41 @@
#
from proton import Message
-from proton_utils import ReceiverHandler, Runtime
+from proton_utils import Container, IncomingMessageHandler
-HOST = "localhost:5672"
-ADDRESS = "examples"
+class HelloWorldReceiver(IncomingMessageHandler):
+ def on_message(self, event):
+ print event.message.body
+ event.connection.close()
-class HelloWorld(ReceiverHandler):
- def received(self, receiver, delivery, msg):
- print msg.body
- receiver.connection.close()
-
-conn = Runtime.DEFAULT.connect(HOST)
-receiver = conn.receiver(ADDRESS, handler=HelloWorld())
-conn.sender(ADDRESS).send_msg(Message(body=u"Hello World!"))
-Runtime.DEFAULT.run()
+class HelloWorldSender(object):
+ def on_link_flow(self, event):
+ event.link.send_msg(Message(body=u"Hello World!"))
+ event.link.close()
+
+class HelloWorld(object):
+ def __init__(self, container, url, address):
+ self.container = container
+ self.conn = container.connect(url, handler=self)
+ self.address = address
+
+ def on_connection_remote_open(self, event):
+ self.conn.receiver(self.address, handler=HelloWorldReceiver())
+ self.conn.sender(self.address, handler=HelloWorldSender())
+
+ def on_link_remote_close(self, event):
+ self.closed(event.link.remote_condition)
+
+ def on_connection_remote_close(self, event):
+ self.closed(event.connection.remote_condition)
+
+ def closed(self, error=None):
+ if error:
+ print "Closed due to %s" % error
+ self.conn.close()
+
+ def run(self):
+ self.container.run()
+
+HelloWorld(Container.DEFAULT, "localhost:5672", "examples").run()
Copied: qpid/proton/branches/examples/tutorial/helloworld_alt.py (from r1616454, qpid/proton/branches/examples/tutorial/helloworld_2.py)
URL: http://svn.apache.org/viewvc/qpid/proton/branches/examples/tutorial/helloworld_alt.py?p2=qpid/proton/branches/examples/tutorial/helloworld_alt.py&p1=qpid/proton/branches/examples/tutorial/helloworld_2.py&r1=1616454&r2=1616829&rev=1616829&view=diff
==============================================================================
--- qpid/proton/branches/examples/tutorial/helloworld_2.py (original)
+++ qpid/proton/branches/examples/tutorial/helloworld_alt.py Fri Aug 8 16:49:59 2014
@@ -19,23 +19,39 @@
#
from proton import Message
-from proton_utils import ReceiverHandler, Runtime
+from proton_utils import Container, IncomingMessageHandler
-HOST = "localhost:5672"
-ADDRESS = "examples"
+class HelloWorld(IncomingMessageHandler):
+ def __init__(self, container, url, address):
+ self.container = container
+ self.conn = container.connect(url, handler=self)
+ self.address = address
-class HelloWorld(ReceiverHandler):
- def received(self, receiver, delivery, msg):
- print msg.body
- receiver.connection.close()
+ def on_connection_remote_open(self, event):
+ self.conn.receiver(self.address)
+ self.conn.sender(self.address)
- def closed(self, receiver, error):
+ def on_link_flow(self, event):
+ event.link.send_msg(Message(body=u"Hello World!"))
+ event.link.close()
+
+ def on_message(self, event):
+ print event.message.body
+ event.connection.close()
+
+ def on_link_remote_close(self, event):
+ self.closed(event.link.remote_condition)
+
+ def on_connection_remote_close(self, event):
+ self.closed(event.connection.remote_condition)
+
+ def closed(self, error=None):
if error:
print "Closed due to %s" % error
- receiver.connection.close()
+ self.conn.close()
+
+ def run(self):
+ self.container.run()
-conn = Runtime.DEFAULT.connect(HOST)
-receiver = conn.receiver(ADDRESS, handler=HelloWorld())
-conn.sender(ADDRESS).send_msg(Message(body=u"Hello World!"))
-Runtime.DEFAULT.run()
+HelloWorld(Container.DEFAULT, "localhost:5672", "examples").run()
Copied: qpid/proton/branches/examples/tutorial/helloworld_direct.py (from r1616454, qpid/proton/branches/examples/tutorial/helloworld_4.py)
URL: http://svn.apache.org/viewvc/qpid/proton/branches/examples/tutorial/helloworld_direct.py?p2=qpid/proton/branches/examples/tutorial/helloworld_direct.py&p1=qpid/proton/branches/examples/tutorial/helloworld_4.py&r1=1616454&r2=1616829&rev=1616829&view=diff
==============================================================================
--- qpid/proton/branches/examples/tutorial/helloworld_4.py (original)
+++ qpid/proton/branches/examples/tutorial/helloworld_direct.py Fri Aug 8 16:49:59 2014
@@ -19,26 +19,43 @@
#
from proton import Message
-from proton_utils import ConnectionHandler, FlowController, Handshaker, ReceiverHandler, Runtime
+from proton_utils import Container, FlowController, Handshaker, IncomingMessageHandler
-HOST = "localhost:8888"
-ADDRESS = "examples"
-
-class HelloWorld(ReceiverHandler):
- def received(self, receiver, delivery, msg):
- print msg.body
- receiver.connection.close()
-
-class Stop(ConnectionHandler):
- def __init__(self, acceptor):
- self.acceptor = acceptor
-
- def closed(self, conn, error):
+class HelloWorldReceiver(IncomingMessageHandler):
+ def on_message(self, event):
+ print event.message.body
+ event.connection.close()
+
+class HelloWorldSender(object):
+ def on_link_flow(self, event):
+ event.link.send_msg(Message(body=u"Hello World!"))
+ event.link.close()
+
+class HelloWorld(object):
+ def __init__(self, container, url, address):
+ self.container = container
+ self.acceptor = container.listen(url)
+ self.conn = container.connect(url, handler=self)
+ self.address = address
+
+ def on_connection_remote_open(self, event):
+ self.conn.sender(self.address, handler=HelloWorldSender())
+
+ def on_link_remote_close(self, event):
+ self.closed(event.link.remote_condition)
+
+ def on_connection_remote_close(self, event):
+ self.closed(event.connection.remote_condition)
+
+ def closed(self, error=None):
+ if error:
+ print "Closed due to %s" % error
+ self.conn.close()
self.acceptor.close()
-runtime = Runtime(HelloWorld(), Handshaker(), FlowController(1))
-stopper = Stop(runtime.listen(HOST))
-conn = runtime.connect(HOST, handler=stopper)
-conn.sender(ADDRESS).send_msg(Message(body=u"Hello World!"))
-runtime.run()
+ def run(self):
+ self.container.run()
+
+container = Container(HelloWorldReceiver(), Handshaker(), FlowController(1))
+HelloWorld(container, "localhost:8888", "examples").run()
Copied: qpid/proton/branches/examples/tutorial/helloworld_direct_alt.py (from r1616454, qpid/proton/branches/examples/tutorial/helloworld_3.py)
URL: http://svn.apache.org/viewvc/qpid/proton/branches/examples/tutorial/helloworld_direct_alt.py?p2=qpid/proton/branches/examples/tutorial/helloworld_direct_alt.py&p1=qpid/proton/branches/examples/tutorial/helloworld_3.py&r1=1616454&r2=1616829&rev=1616829&view=diff
==============================================================================
--- qpid/proton/branches/examples/tutorial/helloworld_3.py (original)
+++ qpid/proton/branches/examples/tutorial/helloworld_direct_alt.py Fri Aug 8 16:49:59 2014
@@ -19,19 +19,41 @@
#
from proton import Message
-from proton_utils import FlowController, Handshaker, ReceiverHandler, Runtime
+from proton_utils import Container, FlowController, Handshaker, IncomingMessageHandler
-HOST = "localhost:8888"
-ADDRESS = "examples"
+class HelloWorldReceiver(IncomingMessageHandler):
+ def on_message(self, event):
+ print event.message.body
+ event.connection.close()
-class HelloWorld(ReceiverHandler):
- def received(self, receiver, delivery, msg):
- print msg.body
- receiver.connection.close()
-
-runtime = Runtime(HelloWorld(), Handshaker(), FlowController(1))
-runtime.listen(HOST)
-conn = runtime.connect(HOST)
-conn.sender(ADDRESS).send_msg(Message(body=u"Hello World!"))
-runtime.run()
+class HelloWorld(object):
+ def __init__(self, container, url, address):
+ self.container = container
+ self.acceptor = container.listen(url)
+ self.conn = container.connect(url, handler=self)
+ self.address = address
+ def on_connection_remote_open(self, event):
+ self.conn.sender(self.address)
+
+ def on_link_flow(self, event):
+ event.link.send_msg(Message(body=u"Hello World!"))
+ event.link.close()
+
+ def on_link_remote_close(self, event):
+ self.closed(event.link.remote_condition)
+
+ def on_connection_remote_close(self, event):
+ self.closed(event.connection.remote_condition)
+
+ def closed(self, error=None):
+ if error:
+ print "Closed due to %s" % error
+ self.conn.close()
+ self.acceptor.close()
+
+ def run(self):
+ self.container.run()
+
+container = Container(HelloWorldReceiver(), Handshaker(), FlowController(1))
+HelloWorld(container, "localhost:8888", "examples").run()
Modified: qpid/proton/branches/examples/tutorial/proton_utils.py
URL: http://svn.apache.org/viewvc/qpid/proton/branches/examples/tutorial/proton_utils.py?rev=1616829&r1=1616828&r2=1616829&view=diff
==============================================================================
--- qpid/proton/branches/examples/tutorial/proton_utils.py (original)
+++ qpid/proton/branches/examples/tutorial/proton_utils.py Fri Aug 8 16:49:59 2014
@@ -24,30 +24,30 @@ from select import select
class EventDispatcher(object):
methods = {
- Event.CONNECTION_INIT: "connection_init",
- Event.CONNECTION_OPEN: "connection_open",
- Event.CONNECTION_REMOTE_OPEN: "connection_remote_open",
- Event.CONNECTION_CLOSE: "connection_close",
- Event.CONNECTION_REMOTE_CLOSE: "connection_remote_close",
- Event.CONNECTION_FINAL: "connection_final",
-
- Event.SESSION_INIT: "session_init",
- Event.SESSION_OPEN: "session_open",
- Event.SESSION_REMOTE_OPEN: "session_remote_open",
- Event.SESSION_CLOSE: "session_close",
- Event.SESSION_REMOTE_CLOSE: "session_remote_close",
- Event.SESSION_FINAL: "session_final",
-
- Event.LINK_INIT: "link_init",
- Event.LINK_OPEN: "link_open",
- Event.LINK_REMOTE_OPEN: "link_remote_open",
- Event.LINK_CLOSE: "link_close",
- Event.LINK_REMOTE_CLOSE: "link_remote_close",
- Event.LINK_FLOW: "link_flow",
- Event.LINK_FINAL: "link_final",
+ Event.CONNECTION_INIT: "on_connection_init",
+ Event.CONNECTION_OPEN: "on_connection_open",
+ Event.CONNECTION_REMOTE_OPEN: "on_connection_remote_open",
+ Event.CONNECTION_CLOSE: "on_connection_close",
+ Event.CONNECTION_REMOTE_CLOSE: "on_connection_remote_close",
+ Event.CONNECTION_FINAL: "on_connection_final",
+
+ Event.SESSION_INIT: "on_session_init",
+ Event.SESSION_OPEN: "on_session_open",
+ Event.SESSION_REMOTE_OPEN: "on_session_remote_open",
+ Event.SESSION_CLOSE: "on_session_close",
+ Event.SESSION_REMOTE_CLOSE: "on_session_remote_close",
+ Event.SESSION_FINAL: "on_session_final",
+
+ Event.LINK_INIT: "on_link_init",
+ Event.LINK_OPEN: "on_link_open",
+ Event.LINK_REMOTE_OPEN: "on_link_remote_open",
+ Event.LINK_CLOSE: "on_link_close",
+ Event.LINK_REMOTE_CLOSE: "on_link_remote_close",
+ Event.LINK_FLOW: "on_link_flow",
+ Event.LINK_FINAL: "on_link_final",
- Event.TRANSPORT: "transport",
- Event.DELIVERY: "delivery"
+ Event.TRANSPORT: "on_transport",
+ Event.DELIVERY: "on_delivery"
}
def dispatch(self, event):
@@ -69,6 +69,7 @@ class Selectable(object):
self.read_done = False
def accept(self):
+ #TODO: use SASL if requested by peer
#sasl = self.transport.sasl()
#sasl.mechanisms("ANONYMOUS")
#sasl.server()
@@ -159,8 +160,8 @@ class Selectable(object):
if not self._closed_cleanly(): self.disconnected()
def disconnected(self):
- if hasattr(self.conn, "context") and hasattr(self.conn.context, "disconnected"):
- self.conn.context.disconnected(self.conn)
+ if hasattr(self.conn, "context") and hasattr(self.conn.context, "on_disconnected"):
+ self.conn.context.on_disconnected(self.conn)
else:
print "connection %s disconnected" % self.conn
@@ -198,7 +199,6 @@ class Acceptor:
def readable(self):
sock, addr = self.socket.accept()
- print "Incoming Connection:", addr
if sock:
self.selectables.append(Selectable(self.events.connection(), sock).accept())
@@ -270,34 +270,34 @@ class SelectLoop(object):
class Handshaker(EventDispatcher):
- def connection_remote_open(self, event):
+ def on_connection_remote_open(self, event):
conn = event.connection
if conn.state & Endpoint.LOCAL_UNINIT:
conn.open()
- def session_remote_open(self, event):
+ def on_session_remote_open(self, event):
ssn = event.session
if ssn.state & Endpoint.LOCAL_UNINIT:
ssn.open()
- def link_remote_open(self, event):
+ def on_link_remote_open(self, event):
link = event.link
if link.state & Endpoint.LOCAL_UNINIT:
link.source.copy(link.remote_source)
link.target.copy(link.remote_target)
link.open()
- def connection_remote_close(self, event):
+ def on_connection_remote_close(self, event):
conn = event.connection
if not (conn.state & Endpoint.LOCAL_CLOSED):
conn.close()
- def session_remote_close(self, event):
+ def on_session_remote_close(self, event):
ssn = event.session
if not (ssn.state & Endpoint.LOCAL_CLOSED):
ssn.close()
- def link_remote_close(self, event):
+ def on_link_remote_close(self, event):
link = event.link
if not (link.state & Endpoint.LOCAL_CLOSED):
link.close()
@@ -311,29 +311,29 @@ class FlowController(EventDispatcher):
delta = self.window - link.credit
link.flow(delta)
- def link_open(self, event):
+ def on_link_open(self, event):
if event.link.is_receiver:
self.top_up(event.link)
- def link_remote_open(self, event):
+ def on_link_remote_open(self, event):
if event.link.is_receiver:
self.top_up(event.link)
- def link_flow(self, event):
+ def on_link_flow(self, event):
if event.link.is_receiver:
self.top_up(event.link)
- def delivery(self, event):
+ def on_delivery(self, event):
if event.delivery.link.is_receiver:
self.top_up(event.delivery.link)
class ScopedDispatcher(EventDispatcher):
- targets = {
- Event.CATEGORY_CONNECTION: "connection_context",
- Event.CATEGORY_SESSION: "session_context",
- Event.CATEGORY_LINK: "link_context",
- Event.CATEGORY_DELIVERY: "delivery_context"
+ scopes = {
+ Event.CATEGORY_CONNECTION: ["connection"],
+ Event.CATEGORY_SESSION: ["session", "connection"],
+ Event.CATEGORY_LINK: ["link", "session", "connection"],
+ Event.CATEGORY_DELIVERY: ["delivery", "link", "session", "connection"]
}
def connection_context(self, event):
@@ -371,56 +371,36 @@ class ScopedDispatcher(EventDispatcher):
return None
def dispatch(self, event):
- target = self.target_context(event)
- if target:
- getattr(target, self.methods[event.type], self.unhandled)(event)
-
-class ConnectionHandler(EventDispatcher):
- def __init__(self):
- super(ConnectionHandler, self).__init__()
-
- def connection_remote_open(self, event):
- self.opened(event.connection)
-
- def connection_remote_close(self, event):
- self.closed(event.connection, event.connection.remote_condition)
+ method = self.methods[event.type]
+ objects = [getattr(event, attr) for attr in self.scopes.get(event.category, [])]
+ targets = [getattr(o, "context") for o in objects if hasattr(o, "context")]
+ handlers = [getattr(t, method) for t in targets if hasattr(t, method)]
+ for h in handlers:
+ h(event)
- def opened(self, conn): pass
- def closed(self, conn, condition): pass
- def disconnected(self, conn): pass
-
-class SenderHandler(EventDispatcher):
- def link_remote_open(self, event):
- self.opened(event.link)
-
- def link_remote_close(self, event):
- self.closed(event.link, event.link.remote_condition)
-
- def delivery(self, event):
+class OutgoingMessageHandler(EventDispatcher):
+ def on_delivery(self, event):
dlv = event.delivery
link = dlv.link
if dlv.updated:
if dlv.remote_state == Delivery.ACCEPTED:
- self.accepted(dlv.link, dlv)
+ self.on_accepted(event)
elif dlv.remote_state == Delivery.REJECTED:
- self.accepted(dlv.link, dlv)
+ self.on_rejected(event)
elif dlv.remote_state == Delivery.RELEASED:
- self.accepted(dlv.link, dlv)
+ self.on_released(event)
elif dlv.remote_state == Delivery.MODIFIED:
- self.accepted(dlv.link, dlv)
+ self.on_modified(event)
if dlv.settled:
- self.settled(dlv.link, dlv)
- if self.auto_settle():
+ self.on_settled(event)
+ if self.auto_settle() and not dlv.settled:
dlv.settle()
- def opened(self, sender): pass
- def closed(self, sender, condition): pass
- def link_flow(self, event): pass
- def accepted(self, sender, delivery): pass
- def rejected(self, sender, delivery): pass
- def released(self, sender, delivery): pass
- def modified(self, sender, delivery): pass
- def settled(self, sender, delivery): pass
+ def on_accepted(self, event): pass
+ def on_rejected(self, event): pass
+ def on_released(self, event): pass
+ def on_modified(self, event): pass
+ def on_settled(self, event): pass
def auto_settle(self): return True
def recv_msg(delivery):
@@ -435,24 +415,14 @@ class Reject(ProtonException):
"""
pass
-class ReceiverHandler(EventDispatcher):
- def link_remote_open(self, event):
- self.opened(event.link)
-
- def link_remote_close(self, event):
- self.closed(event.link, event.link.remote_condition)
-
- def link_flow(self, event):
- if event.link.is_receiver and not event.link.draining():
- self.drained(event.link)
-
- def delivery(self, event):
+class IncomingMessageHandler(EventDispatcher):
+ def on_delivery(self, event):
dlv = event.delivery
link = dlv.link
if dlv.readable and not dlv.partial:
- msg = recv_msg(dlv)
+ event.message = recv_msg(dlv)
try:
- self.received(dlv.link, dlv, msg)
+ self.on_message(event)
if self.auto_accept():
dlv.update(Delivery.ACCEPTED)
dlv.settle()
@@ -460,7 +430,7 @@ class ReceiverHandler(EventDispatcher):
dlv.update(Delivery.REJECTED)
dlv.settle()
elif dlv.updated and dlv.settled:
- self.settled(dlv.link, dlv)
+ self.on_settled(event)
def accept(self, delivery):
self.settle(delivery, Delivery.ACCEPTED)
@@ -468,7 +438,7 @@ class ReceiverHandler(EventDispatcher):
def reject(self, delivery):
self.settle(delivery, Delivery.REJECTED)
- def release(self, delivery, delivered=False):
+ def release(self, delivery, delivered=True):
if delivered:
self.settle(delivery, Delivery.MODIFIED)
else:
@@ -479,11 +449,8 @@ class ReceiverHandler(EventDispatcher):
delivery.update(state)
delivery.settle()
- def opened(self, receiver): pass
- def closed(self, receiver, condition): pass
- def drained(self, receiver): pass
- def received(self, receiver, delivery, message): pass
- def settled(self, receiver, delivery): pass
+ def on_message(self, event): pass
+ def on_settled(self, event): pass
def auto_accept(self): return True
def delivery_tags():
@@ -556,12 +523,12 @@ class MessagingContext(object):
ssn.open()
return ssn
- def session_remote_close(self, event):
+ def on_session_remote_close(self, event):
if self.conn:
self.conn.close()
-class Runtime(object):
+class Container(object):
def __init__(self, *handlers):
self.loop = SelectLoop(Events(ScopedDispatcher(), *handlers))
@@ -583,5 +550,5 @@ class Runtime(object):
def run(self):
self.loop.run()
-Runtime.DEFAULT = Runtime(FlowController(10))
+Container.DEFAULT = Container(FlowController(10))
Modified: qpid/proton/branches/examples/tutorial/server.py
URL: http://svn.apache.org/viewvc/qpid/proton/branches/examples/tutorial/server.py?rev=1616829&r1=1616828&r2=1616829&view=diff
==============================================================================
--- qpid/proton/branches/examples/tutorial/server.py (original)
+++ qpid/proton/branches/examples/tutorial/server.py Fri Aug 8 16:49:59 2014
@@ -19,33 +19,31 @@
#
from proton import Message
-from proton_utils import ReceiverHandler, Runtime
+from proton_utils import Container, IncomingMessageHandler
-class Server(ReceiverHandler):
- def __init__(self, host, address):
- self.conn = Runtime.DEFAULT.connect(host)
+class Server(IncomingMessageHandler):
+ def __init__(self, container, host, address):
+ self.container = container
+ self.conn = container.connect(host)
self.receiver = self.conn.receiver(address, handler=self)
self.senders = {}
- def received(self, receiver, handle, msg):
- sender = self.senders.get(msg.reply_to)
+ def on_message(self, event):
+ sender = self.senders.get(event.message.reply_to)
if not sender:
- sender = self.conn.sender(msg.reply_to)
- self.senders[msg.reply_to] = sender
- sender.send_msg(Message(body=msg.body.upper()))
+ sender = self.conn.sender(event.message.reply_to)
+ self.senders[event.message.reply_to] = sender
+ sender.send_msg(Message(body=event.message.body.upper()))
- def closed(self, endpoint, error):
+ def on_connection_remote_close(self, endpoint, error):
if error: print "Closed due to %s" % error
self.conn.close()
def run(self):
- Runtime.DEFAULT.run()
-
-HOST = "localhost:5672"
-ADDRESS = "examples"
+ self.container.run()
try:
- Server(HOST, ADDRESS).run()
+ Server(Container.DEFAULT, "localhost:5672", "examples").run()
except KeyboardInterrupt: pass
Modified: qpid/proton/branches/examples/tutorial/simple_recv.py
URL: http://svn.apache.org/viewvc/qpid/proton/branches/examples/tutorial/simple_recv.py?rev=1616829&r1=1616828&r2=1616829&view=diff
==============================================================================
--- qpid/proton/branches/examples/tutorial/simple_recv.py (original)
+++ qpid/proton/branches/examples/tutorial/simple_recv.py Fri Aug 8 16:49:59 2014
@@ -18,28 +18,36 @@
# under the License.
#
-from proton_utils import ReceiverHandler, Runtime
+from proton_utils import Container, IncomingMessageHandler
-class Recv(ReceiverHandler):
- def __init__(self, host, address):
- self.conn = Runtime.DEFAULT.connect(host)
- self.link = self.conn.receiver(address, handler=self)
+class Recv(IncomingMessageHandler):
+ def __init__(self, container, host, address):
+ self.container = container
+ self.conn = container.connect(host, handler=self)
+ self.address = address
- def received(self, receiver, handle, msg):
- print msg.body
+ def on_message(self, event):
+ print event.message.body
- def closed(self, endpoint, error):
- if error: print "Closed due to %s" % error
+ def on_connection_remote_open(self, event):
+ self.conn.receiver(self.address)
+
+ def on_link_remote_close(self, event):
+ self.closed(event.link.remote_condition)
+
+ def on_connection_remote_close(self, event):
+ self.closed(event.connection.remote_condition)
+
+ def closed(self, error=None):
+ if error:
+ print "Closed due to %s" % error
self.conn.close()
def run(self):
- Runtime.DEFAULT.run()
-
-HOST = "localhost:5672"
-ADDRESS = "examples"
+ self.container.run()
try:
- Recv(HOST, ADDRESS).run()
+ Recv(Container.DEFAULT, "localhost:5672", "examples").run()
except KeyboardInterrupt: pass
Modified: qpid/proton/branches/examples/tutorial/simple_recv_2.py
URL: http://svn.apache.org/viewvc/qpid/proton/branches/examples/tutorial/simple_recv_2.py?rev=1616829&r1=1616828&r2=1616829&view=diff
==============================================================================
--- qpid/proton/branches/examples/tutorial/simple_recv_2.py (original)
+++ qpid/proton/branches/examples/tutorial/simple_recv_2.py Fri Aug 8 16:49:59 2014
@@ -18,37 +18,44 @@
# under the License.
#
-from proton_utils import ConnectionHandler, ReceiverHandler, Runtime
+from proton_utils import IncomingMessageHandler, Container
-class Recv(ConnectionHandler, ReceiverHandler):
- def __init__(self, host, address):
+class Recv(IncomingMessageHandler):
+ def __init__(self, container, host, address):
+ self.container = container
self.host = host
self.address = address
self.connect()
def connect(self):
- self.conn = Runtime.DEFAULT.connect(self.host, handler=self)
- self.link = self.conn.receiver(self.address, handler=self)
+ self.conn = self.container.connect(self.host, handler=self)
- def received(self, receiver, handle, msg):
- print msg.body
+ def on_message(self, event):
+ print event.message.body
- def closed(self, endpoint, error):
- if error: print "Closed due to %s" % error
+ def on_connection_remote_open(self, event):
+ self.conn.receiver(self.address)
+
+ def on_link_remote_close(self, event):
+ self.closed(event.link.remote_condition)
+
+ def on_connection_remote_close(self, event):
+ self.closed(event.connection.remote_condition)
+
+ def closed(self, error=None):
+ if error:
+ print "Closed due to %s" % error
self.conn.close()
- def disconnected(self, conn):
+ def on_disconnected(self, conn):
print "Disconnected, reconnecting..."
self.connect()
def run(self):
- Runtime.DEFAULT.run()
-
-HOST = "localhost:5672"
-ADDRESS = "examples"
+ self.container.run()
try:
- Recv(HOST, ADDRESS).run()
+ Recv(Container.DEFAULT, "localhost:5672", "examples").run()
except KeyboardInterrupt: pass
Modified: qpid/proton/branches/examples/tutorial/simple_send.py
URL: http://svn.apache.org/viewvc/qpid/proton/branches/examples/tutorial/simple_send.py?rev=1616829&r1=1616828&r2=1616829&view=diff
==============================================================================
--- qpid/proton/branches/examples/tutorial/simple_send.py (original)
+++ qpid/proton/branches/examples/tutorial/simple_send.py Fri Aug 8 16:49:59 2014
@@ -19,18 +19,18 @@
#
from proton import Message
-from proton_utils import SenderHandler, Runtime
+from proton_utils import OutgoingMessageHandler, Container
-class Send(ConnectionHandler, SenderHandler):
- def __init__(self, host, address, messages):
- self.conn = Runtime.DEFAULT.connect(host)
- self.sender = self.conn.sender(address, handler=self)
+class Send(OutgoingMessageHandler):
+ def __init__(self, container, host, address, messages):
+ self.container = container
+ self.conn = container.connect(host, handler=self)
self.sent = 0
self.confirmed = 0
self.total = messages
- self.sender.offered(messages)
+ self.address = address
- def link_flow(self, event):
+ def on_link_flow(self, event):
for i in range(self.sender.credit):
if self.sent == self.total:
self.sender.drained()
@@ -39,7 +39,7 @@ class Send(ConnectionHandler, SenderHand
self.sender.send_msg(msg, handler=self)
self.sent += 1
- def accepted(self, sender, delivery):
+ def on_accepted(self, event):
"""
Stop the application once all of the messages are sent and acknowledged,
"""
@@ -48,17 +48,23 @@ class Send(ConnectionHandler, SenderHand
self.sender.close()
self.conn.close()
- def closed(self, endpoint, error):
+ def on_connection_remote_open(self, event):
+ self.sender = self.conn.sender(self.address)
+ self.sender.offered(self.total)
+
+ def on_link_remote_close(self, event):
+ self.closed(event.link.remote_condition)
+
+ def on_connection_remote_close(self, event):
+ self.closed(event.connection.remote_condition)
+
+ def closed(self, error=None):
if error:
print "Closed due to %s" % error
self.conn.close()
def run(self):
- Runtime.DEFAULT.run()
-
-HOST = "localhost:5672"
-ADDRESS = "examples"
-COUNT = 1000
+ self.container.run()
-Send(HOST, ADDRESS, COUNT).run()
+Send(Container.DEFAULT, "localhost:5672", "examples", 1000).run()
Modified: qpid/proton/branches/examples/tutorial/tutorial.rst
URL: http://svn.apache.org/viewvc/qpid/proton/branches/examples/tutorial/tutorial.rst?rev=1616829&r1=1616828&r2=1616829&view=diff
==============================================================================
--- qpid/proton/branches/examples/tutorial/tutorial.rst (original)
+++ qpid/proton/branches/examples/tutorial/tutorial.rst Fri Aug 8 16:49:59 2014
@@ -2,66 +2,71 @@
Hello World!
============
-Let's start, in time honoured tradition, with hello world!:
+Tradition dictates that we start with hello world! However rather than
+simply striving for the shortest program possible, we'll aim for a
+more illustrative example while still restricting the functionality to
+simply sending and receiving a single message.
.. literalinclude:: helloworld.py
:lines: 21-
:linenos:
-You can see the import of ``Runtime`` from ``proton_utils`` on the
+You can see the import of ``Container`` from ``proton_utils`` on the
second line. This is a helper class that makes programming with proton
-a little easier for the common cases.
-
-We use the ``Runtime`` on line 12. Specifically we use a special
-default instance of it. We'll see some examples using other instances
-later. Line 12 uses the runtime to make a connection to the desired
-host and port via the ``connect()`` call. This call returns a
-``MessagingContext`` object through which we can create objects for
-sending and receiving messages to the process it is connected to.
-
-On line 13 we create a receiver through which to receiver messages
-from the specified address. We specify a ``handler`` parameter, with
-an instance of our ``HelloWorld`` class as it's value. The ``handler``
-parameter provides a way of being notified of important events related
-to the receiver being created. The event we care about most is the
-receiving of a message. To be notified of that we define a
-``received`` method on our handler which will be called whenever a
-message for that receiver arrives. As well as the received message,
-this method also gets passed the receiver over which the message
-arrived and a ``delivery`` handle associated with it, which we can
-ignore for now. In our example we simply print the body of the
-message, then close the connection of the receiver it arrived on.
-
-Now we are all ready to receive and print our message. All we need to
-do is send one! To do so we use the ``MessagingContext`` object to
-create a sender for the same address we used when creating the
-receiver, and then we send a message over it.
-
-Finally we allow the runtime to process these instructions and handle
-all the necessary IO by calling ``run()`` on it in line 15.
-
-To run this example as it is, you need to have an AMQP broker running
-locally on port 5672, with a queue (or topic) named ``examples``, or
-configured to create that dynamically. The broker must also allow
-unauthenticated connections.
-
-In fact, if your broker doesn't have the requisite queue, the example
-just hangs. Let's modify the example to handle that a little more
-gracefully.
-
-.. literalinclude:: helloworld_2.py
- :lines: 21-
- :emphasize-lines: 12-15
- :linenos:
-
-All we have added is a new method to our receiver's handler. This
-method is called ``closed()`` and it is called whenever the remote
-process closes our receiver. We'll print any error if specified and
-then close the connection. If you now run it against a broker that
-doesn't have (and will not automatically create) a queue named
-``examples`` then it should exit with a more informative error
-message. This demonstrates a key concept in using proton, namely that
-you often structure your logic to react to particular events.
+a little easier for the common cases. It includes within it an event
+loop, and programs written using this utility are generally structured
+to react to various events. This reactive style is particularly suited
+to messaging applications.
+
+To be notified of a particular event, you define a class with the
+appropriately name method on it. That method is then called by the
+container when the event occurs.
+
+The first class we define, ``HelloWorldReceiver``, handles the event
+where a message is received and so implements a ``on_message()``
+method. Within that we simply print the body of the message (line 6)
+and then close the connection (line 7).
+
+The second class, ``HelloWorldSender``, handles the event where the
+flow of messages is enabled over our sending link by implementing a
+``on_link_flow()`` method and sending the message within that. Doing
+this ensures that we only send when the recipient is ready and able to
+receive the message. This is particularly important when the volume of
+messages might be large. In our case we are just going to send one
+message, which we do on line 11, so we can then just close the sending
+link on line 12.
+
+The ``HelloWorld`` class ties everything together. It's constructor
+takes the instance of the container to use, a url to connect to, and
+an address through which the message will be sent. To run the example
+you will need to have a broker (or similar) accepting connections on
+that url either with a queue (or topic) matching the given address or
+else configured to create such a queue (or topic) dynamically.
+
+On line 17 we request that a connection be made to the process this
+url refers to by calling ``connect()`` on the ``Container``. This call
+returns a ``MessagingContext`` object through which we can create
+objects for sending and receiving messages to the process it is
+connected to. However we will delay doing that until our connection is
+fully established, i.e. until the remote peer 'opens' the connection
+(the open here is the 'handshake' for establishing an operational AMQP
+connection).
+
+To be notified of this we pass a reference to self as the handler in
+``connect()`` and define an ``on_connection_remote_open()`` method
+within which we can create our receiver and sender using the
+connection context we obtained from the earlier ``connect()`` call,
+and passing the handler implementations defined by
+``HelloWorldReceiver`` and ``HelloWorldSender`` respectively.
+
+We'll add definitions to ``HelloWorld`` of ``on_link_remote_close()``
+and ``on_connection_remote_close()`` also, so that we can be notified
+if the broker we are connected to closes either link or the connection
+for any reason.
+
+Finally we actually enter the event loop the container to handle all
+the necessary IO and make all the necessary event callbacks, by
+calling ``run()`` on it.
====================
Hello World, Direct!
@@ -73,52 +78,36 @@ directly if desired.
Let's modify our example to demonstrate this.
-.. literalinclude:: helloworld_3.py
+.. literalinclude:: helloworld_direct.py
:lines: 21-
- :emphasize-lines: 12-14
+ :emphasize-lines: 17,33,38
:linenos:
-The first difference, on line 12, is that we create our own
-``Runtime`` instance rather than just using the default instance. We
-pass in some handler objects. The first of these is our ``HelloWorld``
-handler as used in the original example. We pass it to the runtime,
-because we aren't going to directly create the receiver here
-ourselves. Rather we will accept an incoming connection on which the
-message will be received. As well as our own handler, we specify a
-couple of useful handlers from the ``proton_utils`` toolkit. The
-``Handshaker`` handler will ensure our server follows the basic
-handshaking rules laid down by the protocol. The ``FlowController``
-will issue credit for incoming messages. We won't worry about them in
-more detail than that for now.
-
-On line 13 we then invoke ``listen()`` on our runtime. This starts a
-server socket listening for incoming connections on the specified
-interface and port. Then on line 14 we use ``connect`` as before on
-our runtime instance to establish an outgoing connection back to
-ourselves. As before we create a sender on this connection and send
-our message over it. So now we have our example working without a
-broker involved!
-
-However, the example doesn't exit after the message is printed. This
-is because we are still listenting for incoming connections; the
-runtime is still running. Let's now change it to shutdown cleanly when
-done.
-
-.. literalinclude:: helloworld_4.py
- :lines: 21-
- :emphasize-lines: 12-17,20,21
- :linenos:
-
-On line 21 we pass a handler to the ``connect()`` call on our
-runtime. This is similar to what we did when creating a receiver in
-the original example. Here however the handler is scoped to the
-connection. We are interested in reacting to the closing of the
-connection by the remote peer by closing the server socket we have
-listening for incoming connections. The call to ``listen()`` returns
-an object we can ``close()`` to accomplish this, so we modify line 20
-to create an object to use as our connection scoped handler, passing
-in this reference to the incoming socket acceptor. Now the ``run()``
-call returns when we are finished and the example exits cleanly.
+The first difference, on line 17, is that rather than creating a
+receiver on the same connection as our sender, we listen for incoming
+connections by invoking the ``listen() method on the ``Container``
+instance.
+
+Another difference is that the ``Container`` instance we use is not
+the default instance as was used in the original example, but one we
+construct ourselves on line 38, passing in some event handlers. The
+first of these is ``HelloWorldReceiver``, as used in the original
+example. We pass it to the container, because we aren't going to
+directly create the receiver here ourselves. Rather we will accept an
+incoming connection on which the message will be received. This
+handler would then be notified of any incoming message event on any of
+the connections the container controls. As well as our own handler, we
+specify a couple of useful handlers from the ``proton_utils``
+toolkit. The ``Handshaker`` handler will ensure our server follows the
+basic handshaking rules laid down by the protocol. The
+``FlowController`` will issue credit for incoming messages. We won't
+worry about them in more detail than that for now.
+
+The last difference is that we close the ``acceptor`` returned from
+the ``listen()`` call as part of the handling of the connection close
+event (line 33).
+
+So now we have our example working without a broker involved!
==========
The Basics
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org