changeset 26684:ccd020a05464

Adddress nits, use asyncio signal handling, create_task
author Bob McElrath <bob_git@mcelrath.org>
date Thu, 19 Jan 2017 17:06:52 -0500
parents ec51c556d861
children f18919e9e7d9
files contrib/zmq/zmq_sub.py contrib/zmq/zmq_sub3.4.py
diffstat 2 files changed, 50 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/contrib/zmq/zmq_sub.py	Tue Jan 10 10:54:07 2017 -0500
+++ b/contrib/zmq/zmq_sub.py	Thu Jan 19 17:06:52 2017 -0500
@@ -3,12 +3,29 @@
 # Distributed under the MIT software license, see the accompanying
 # file COPYING or http://www.opensource.org/licenses/mit-license.php.
 
-# A blocking example using python 2.7 can be obtained from the git history:
-# https://github.com/bitcoin/bitcoin/blob/37a7fe9e440b83e2364d5498931253937abe9294/contrib/zmq/zmq_sub.py
+"""
+    ZMQ example using python3's asyncio
 
-import array
+    Bitcoin should be started with the command line arguments:
+        bitcoind -testnet -daemon \
+                -zmqpubhashblock=tcp://127.0.0.1:28332 \
+                -zmqpubrawtx=tcp://127.0.0.1:28332 \
+                -zmqpubhashtx=tcp://127.0.0.1:28332 \
+                -zmqpubhashblock=tcp://127.0.0.1:28332
+
+    We use the asyncio library here.  `self.handle()` installs itself as a
+    future at the end of the function.  Since it never returns with the event
+    loop having an empty stack of futures, this creates an infinite loop.  An
+    alternative is to wrap the contents of `handle` inside `while True`.
+
+    A blocking example using python 2.7 can be obtained from the git history:
+    https://github.com/bitcoin/bitcoin/blob/37a7fe9e440b83e2364d5498931253937abe9294/contrib/zmq/zmq_sub.py
+"""
+
 import binascii
-import asyncio, zmq, zmq.asyncio
+import asyncio
+import zmq
+import zmq.asyncio
 import signal
 import struct
 import sys
@@ -55,7 +72,8 @@
         asyncio.ensure_future(self.handle())
 
     def start(self):
-        asyncio.ensure_future(self.handle())
+        self.loop.add_signal_handler(signal.SIGINT, self.stop)
+        self.loop.create_task(self.handle())
         self.loop.run_forever()
 
     def stop(self):
@@ -63,8 +81,4 @@
         self.zmqContext.destroy()
 
 daemon = ZMQHandler()
-def signal_handler(num, frame):
-    daemon.stop()
-    exit(0)
-signal.signal(signal.SIGINT, signal_handler)
 daemon.start()
--- a/contrib/zmq/zmq_sub3.4.py	Tue Jan 10 10:54:07 2017 -0500
+++ b/contrib/zmq/zmq_sub3.4.py	Thu Jan 19 17:06:52 2017 -0500
@@ -3,12 +3,33 @@
 # Distributed under the MIT software license, see the accompanying
 # file COPYING or http://www.opensource.org/licenses/mit-license.php.
 
-# A blocking example using python 2.7 can be obtained from the git history:
-# https://github.com/bitcoin/bitcoin/blob/37a7fe9e440b83e2364d5498931253937abe9294/contrib/zmq/zmq_sub.py
+"""
+    ZMQ example using python3's asyncio
 
-import array
+    Bitcoin should be started with the command line arguments:
+        bitcoind -testnet -daemon \
+                -zmqpubhashblock=tcp://127.0.0.1:28332 \
+                -zmqpubrawtx=tcp://127.0.0.1:28332 \
+                -zmqpubhashtx=tcp://127.0.0.1:28332 \
+                -zmqpubhashblock=tcp://127.0.0.1:28332
+
+    We use the asyncio library here.  `self.handle()` installs itself as a
+    future at the end of the function.  Since it never returns with the event
+    loop having an empty stack of futures, this creates an infinite loop.  An
+    alternative is to wrap the contents of `handle` inside `while True`.
+
+    The `@asyncio.coroutine` decorator and the `yield from` syntax found here
+    was introduced in python 3.4 and has been deprecated in favor of the `async`
+    and `await` keywords respectively.
+
+    A blocking example using python 2.7 can be obtained from the git history:
+    https://github.com/bitcoin/bitcoin/blob/37a7fe9e440b83e2364d5498931253937abe9294/contrib/zmq/zmq_sub.py
+"""
+
 import binascii
-import asyncio, zmq, zmq.asyncio
+import asyncio
+import zmq
+import zmq.asyncio
 import signal
 import struct
 import sys
@@ -56,7 +77,8 @@
         asyncio.ensure_future(self.handle())
 
     def start(self):
-        asyncio.ensure_future(self.handle())
+        self.loop.add_signal_handler(signal.SIGINT, self.stop)
+        self.loop.create_task(self.handle())
         self.loop.run_forever()
 
     def stop(self):
@@ -64,8 +86,4 @@
         self.zmqContext.destroy()
 
 daemon = ZMQHandler()
-def signal_handler(num, frame):
-    daemon.stop()
-    exit(0)
-signal.signal(signal.SIGINT, signal_handler)
 daemon.start()