[Checkins] SVN: zc.resumelb/trunk/src/zc/resumelb/ When using ZooKeeper, you can request an lb status server. The

jim cvs-admin at zope.org
Mon Mar 26 20:43:38 UTC 2012


Log message for revision 124739:
  When using ZooKeeper, you can request an lb status server.  The
  address gets registered with ZooKeeper. When you connect to it, you
  get back a json string containing the overall lb backlog and
  addresses and backlogs of each worker.
  

Changed:
  U   zc.resumelb/trunk/src/zc/resumelb/README.txt
  U   zc.resumelb/trunk/src/zc/resumelb/zk.py
  U   zc.resumelb/trunk/src/zc/resumelb/zk.test

-=-
Modified: zc.resumelb/trunk/src/zc/resumelb/README.txt
===================================================================
--- zc.resumelb/trunk/src/zc/resumelb/README.txt	2012-03-26 19:47:27 UTC (rev 124738)
+++ zc.resumelb/trunk/src/zc/resumelb/README.txt	2012-03-26 20:43:35 UTC (rev 124739)
@@ -45,6 +45,8 @@
 The current version of the load-balancer should be considered
 experimental.  We're currently testing it in production.
 
+The documentation is a bit thin, but there are extensive doctests.
+
 Request Classification
 ======================
 
@@ -256,6 +258,11 @@
 
     bin/get-worker-resume 192.168.24.60:33161
 
+- When using ZooKeeper, you can request an lb status server.  The
+  address gets registered with ZooKeeper. When you connect to it, you
+  get back a json string containing the overall lb backlog and
+  addresses and backlogs of each worker.
+
 - The update settings methods were changed to revert settings to
   default when not provided.  This is especially important when used
   with ZooKeeper, so you can look at a tree and know what settings are

Modified: zc.resumelb/trunk/src/zc/resumelb/zk.py
===================================================================
--- zc.resumelb/trunk/src/zc/resumelb/zk.py	2012-03-26 19:47:27 UTC (rev 124738)
+++ zc.resumelb/trunk/src/zc/resumelb/zk.py	2012-03-26 20:43:35 UTC (rev 124739)
@@ -15,6 +15,8 @@
 """
 import gevent
 import gevent.pool
+import gevent.server
+import json
 import logging
 import os
 import re
@@ -108,6 +110,10 @@
         '-m', '--max-connections', type='int',
         help="Maximum number of simultanious accepted connections.")
     parser.add_option(
+        '-s', '--status-server',
+        help=("Run a status server for getting pool information. "
+              "The argument is an address to listen on."))
+    parser.add_option(
         '-L', '--logger-configuration',
         help=
         "Read logger configuration from the given configuration file path.\n"
@@ -206,12 +212,38 @@
         bd.start()
         registration_data['backdoor'] = '127.0.0.1:%s' % bd.server_port
 
+    status_server = None
+    if options.status_server:
+        def status(socket, addr):
+            pool = lb.pool
+            writer = socket.makefile('w')
+            writer.write(json.dumps(
+                dict(
+                    backlog = pool.backlog,
+                    mean_backlog = pool.mbacklog,
+                    workers = [
+                        (worker.__name__, worker.backlog, worker.mbacklog)
+                        for worker in sorted(
+                            pool.workers, key=lambda w: w.__name__)
+                        ]
+                    ))+'\n')
+            writer.close()
+            socket.close()
+        status_server_address = zc.parse_addr.parse_addr(options.status_server)
+        status_server = gevent.server.StreamServer(
+            status_server_address, status)
+        status_server.start()
+        registration_data['status'] = "%s:%s" % (
+            status_server_address[0], status_server.server_port)
+
     zk.register_server(path+'/providers', (addr[0], server.server_port),
                        **registration_data)
 
     def shutdown():
         zk.close()
         server.close()
+        if status_server is not None:
+            status_server.close()
         lb.shutdown()
 
     gevent.signal(signal.SIGTERM, shutdown)

Modified: zc.resumelb/trunk/src/zc/resumelb/zk.test
===================================================================
--- zc.resumelb/trunk/src/zc/resumelb/zk.test	2012-03-26 19:47:27 UTC (rev 124738)
+++ zc.resumelb/trunk/src/zc/resumelb/zk.test	2012-03-26 20:43:35 UTC (rev 124739)
@@ -193,6 +193,10 @@
       -m MAX_CONNECTIONS, --max-connections=MAX_CONNECTIONS
                             Maximum number of simultanious accepted
                             connections.
+      -s STATUS_SERVER, --status-server=STATUS_SERVER
+                            Run a status server for getting pool
+                            information. The argument is an address to
+                            listen on.
       -L LOGGER_CONFIGURATION, --logger-configuration=LOGGER_CONFIGURATION
                             Read logger configuration from the given
                             configuration file path.  The configuration
@@ -212,7 +216,7 @@
 
     >>> gevent.signal.reset_mock()
     >>> lb, server, accesslog = zc.resumelb.zk.lbmain(
-    ...     'zookeeper.example.com:2181 /test/lb')
+    ...     'zookeeper.example.com:2181 /test/lb -s :0')
 
     >>> sig, sighandler = gevent.signal.call_args[0]
 
@@ -268,6 +272,37 @@
     >>> len(lb.pool.workers)
     2
 
+LB status server
+----------------
+
+When we started the lb, we told it to create a status server.  The
+server is registered with ZooKeeper:
+
+    >>> status_addr = zc.parse_addr.parse_addr(
+    ...     zk.get_properties(
+    ...         '/test/lb/providers/' +
+    ...         zk.get_children('/test/lb/providers')[0])['status'])
+    >>> status_socket = gevent.socket.create_connection(
+    ...     ('127.0.0.1', status_addr[1]))
+    >>> status_file = status_socket.makefile()
+    >>> import json
+    >>> status = json.loads(status_file.read())
+    >>> pprint(status, width=1) # doctest: +ELLIPSIS
+    {u'backlog': 0,
+     u'mean_backlog': 0.4...,
+     u'workers': [[u'127.0.0.1:...',
+                   0,
+                   ...],
+                  [u'127.0.0.1:...',
+                   0,
+                   ...]]}
+
+    >>> sorted(status['workers'], key=lambda w: w[2]) # doctest: +ELLIPSIS
+    [[u'127.0.0.1:...', 0, 0], [u'127.0.0.1:...', 0, 0.48...]]
+
+    >>> status_file.close()
+    >>> status_socket.close()
+
 Shutdown
 --------
 



More information about the checkins mailing list