prefix "tcp://" zmq uris with "zmqpickle" (closes #2574114)
authorAurelien Campeas <aurelien.campeas@logilab.fr>
Tue, 22 Jan 2013 18:16:20 +0100
changeset 8670 f02139297beb
parent 8669 62213a34726e
child 8671 150bbb066167
prefix "tcp://" zmq uris with "zmqpickle" (closes #2574114) * it turns "tcp://" into "zmqpickle-tcp://" * will leave room for future non-pickling communications using zmq
dbapi.py
doc/3.16.rst
doc/book/en/devrepo/repo/hooks.rst
server/cwzmq.py
server/serverconfig.py
server/test/unittest_repository.py
zmqclient.py
--- a/dbapi.py	Mon Jan 21 18:01:25 2013 +0100
+++ b/dbapi.py	Tue Jan 22 18:16:20 2013 +0100
@@ -125,7 +125,7 @@
             return ns_get_proxy(nsid, defaultnsgroup=nsgroup, nshost=puri.netloc)
         except Exception, ex:
             raise ConnectionError(str(ex))
-    elif method == 'tcp': # use zmq (see zmq documentation)
+    elif method.startswith('zmqpickle-'):
         from cubicweb.zmqclient import ZMQRepositoryClient
         return ZMQRepositoryClient(uri)
     else:
--- a/doc/3.16.rst	Mon Jan 21 18:01:25 2013 +0100
+++ b/doc/3.16.rst	Tue Jan 22 18:16:20 2013 +0100
@@ -36,6 +36,11 @@
   * Deprecate `in_memory_cnx` which becomes useless, use `_repo_connect` instead
     if necessary.
 
+* the "tcp://" uri scheme used for ZMQ communications (in a way
+  reminiscent of Pyro) is now named "zmqpickle-tcp://", so as to make
+  room for future zmq-based lightweight communications (without python
+  objects pickling).
+
 
 Unintrusive API changes
 -----------------------
--- a/doc/book/en/devrepo/repo/hooks.rst	Mon Jan 21 18:01:25 2013 +0100
+++ b/doc/book/en/devrepo/repo/hooks.rst	Tue Jan 22 18:16:20 2013 +0100
@@ -195,9 +195,9 @@
       self._cw.repo.app_instances_bus.publish(['hello', 'world'])
 
 The `zmq-address-pub` configuration variable contains the address used
-by the instance for sending messages, e.g. `tcp://*:1234`.  The
+by the instance for sending messages, e.g. `zmqpickle-tcp://*:1234`.  The
 `zmq-address-sub` variable contains a comma-separated list of addresses
-to listen on, e.g. `tcp://localhost:1234, tcp://192.168.1.1:2345`.
+to listen on, e.g. `zmqpickle-tcp://localhost:1234, zmqpickle-tcp://192.168.1.1:2345`.
 
 
 Hooks writing tips
--- a/server/cwzmq.py	Mon Jan 21 18:01:25 2013 +0100
+++ b/server/cwzmq.py	Tue Jan 22 18:16:20 2013 +0100
@@ -31,6 +31,13 @@
 
 ctx = zmq.Context()
 
+def cwproto_to_zmqaddr(address):
+    """ converts a cw-zmq address (like zmqpickle-tcp://<ip>:<port>)
+    into a proper zmq address (tcp://<ip>:<port>)
+    """
+    assert address.startswith('zmqpickle-'), 'bad protocol string %s' % address
+    return address.split('-', 1)[1] # chop the `zmqpickle-` prefix
+
 class ZMQComm(object):
     """
     A simple ZMQ-based notification bus.
@@ -140,7 +147,7 @@
         self.events = []
 
     def connect(self, address):
-        self.address = address
+        self.address = cwproto_to_zmqaddr(address)
 
     def run(self):
         """enter the service loop"""
--- a/server/serverconfig.py	Mon Jan 21 18:01:25 2013 +0100
+++ b/server/serverconfig.py	Tue Jan 22 18:16:20 2013 +0100
@@ -229,19 +229,22 @@
         ('zmq-repository-address',
          {'type' : 'string',
           'default': None,
-          'help': 'ZMQ URI on which the repository will be bound to.',
+          'help': ('ZMQ URI on which the repository will be bound '
+                   'to (of the form `zmqpickle-tcp://<ipaddr><port>`).'),
           'group': 'zmq', 'level': 3,
           }),
          ('zmq-address-sub',
           {'type' : 'csv',
            'default' : None,
-           'help': ('List of ZMQ addresses to subscribe to (requires pyzmq)'),
+           'help': ('List of ZMQ addresses to subscribe to (requires pyzmq) '
+                    '(of the form `zmqpickle-tcp://<ipaddr><port>`)'),
            'group': 'zmq', 'level': 1,
            }),
          ('zmq-address-pub',
           {'type' : 'string',
            'default' : None,
-           'help': ('ZMQ address to use for publishing (requires pyzmq)'),
+           'help': ('ZMQ address to use for publishing (requires pyzmq) '
+                    '(of the form `zmqpickle-tcp://<ipaddr><port>`)'),
            'group': 'zmq', 'level': 1,
            }),
         ) + CubicWebConfiguration.options)
--- a/server/test/unittest_repository.py	Mon Jan 21 18:01:25 2013 +0100
+++ b/server/test/unittest_repository.py	Tue Jan 22 18:16:20 2013 +0100
@@ -396,7 +396,7 @@
         t.start()
 
         zmq_server = ZMQRepositoryServer(self.repo)
-        zmq_server.connect('tcp://127.0.0.1:41415')
+        zmq_server.connect('zmqpickle-tcp://127.0.0.1:41415')
 
         t2 = threading.Thread(target=self._zmq_quit, args=(done, zmq_server,))
         t2.start()
@@ -416,7 +416,7 @@
 
     def _zmq_client(self, done):
         try:
-            cnx = connect('tcp://127.0.0.1:41415', u'admin', password=u'gingkow',
+            cnx = connect('zmqpickle-tcp://127.0.0.1:41415', u'admin', password=u'gingkow',
                           initlog=False) # don't reset logging configuration
             try:
                 cnx.load_appobjects(subpath=('entities',))
--- a/zmqclient.py	Mon Jan 21 18:01:25 2013 +0100
+++ b/zmqclient.py	Tue Jan 22 18:16:20 2013 +0100
@@ -23,6 +23,7 @@
 from functools import partial
 import zmq
 
+from cubicweb.server.cwzmq import cwproto_to_zmqaddr
 
 # XXX hack to overpass old zmq limitation that force to have
 # only one context per python process
@@ -33,9 +34,9 @@
 
 class ZMQRepositoryClient(object):
     """
-    This class delegate the overall repository stuff to a remote source.
+    This class delegates the overall repository stuff to a remote source.
 
-    So calling a method of this repository will results on calling the
+    So calling a method of this repository will result on calling the
     corresponding method of the remote source repository.
 
     Any raised exception on the remote source is propagated locally.
@@ -44,8 +45,13 @@
     """
 
     def __init__(self, zmq_address):
+        """A zmq address provided here will be like
+        `zmqpickle-tcp://127.0.0.1:42000`.  W
+
+        We chop the prefix to get a real zmq address.
+        """
         self.socket = ctx.socket(zmq.REQ)
-        self.socket.connect(zmq_address)
+        self.socket.connect(cwproto_to_zmqaddr(zmq_address))
 
     def __zmqcall__(self, name, *args, **kwargs):
          self.socket.send_pyobj([name, args, kwargs])