From 6d9942ece06f4f21a74ccb602420bcc3c17d1d9c Mon Sep 17 00:00:00 2001 From: Athanasius Date: Sat, 5 Oct 2019 11:23:41 +0100 Subject: [PATCH] Switch bottle to using an 'app' instance. This fixes the problem I was having (on two separate machines, Debian stretch and Debian buster) with the Gateway not actually sending messages out port 8500 to the Relay and Monitor. Something about the '@thing' syntax, or using bare 'run()' must be interfering with zmq.green. The latter ends up thinking there are no active/matching sockets to send to[0], despite the sockets definitely being there (complete with TCP 3-way handshake visible on tcpdump output). With the problem: * no network traffic was observed on port 8500. * A test sender.send(...) just before the bottle run() call *did* send the message. A similar test at the start of the @post('/upload/') function did not succeed. [0] - I ended up putting debug prints in both python-zmq and the zeromq 'libzmq' libraries, building the Debian packages and installing those versions. I also ended up using 'gdb' on the process. The end result of this was to find that the _matching variable (a count of matching sockets I think) was empty deep in libzmq, when it should be counting sockets to send to. This was specifically in zeromq3-4.3.1/src/dist.cpp, in the void zmq::dist_t::distribute (msg_t *msg_) function. The immediate: if (_matching == 0) { test was true. I didn't manage to track down which bit of libzmq code should have been setting _matching before I 'recursed back up' the call chain to investigate other things. --- src/eddn/Gateway.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/eddn/Gateway.py b/src/eddn/Gateway.py index d5f4b17..1531156 100644 --- a/src/eddn/Gateway.py +++ b/src/eddn/Gateway.py @@ -21,7 +21,8 @@ from eddn.core.Validator import Validator, ValidationSeverity from gevent import monkey monkey.patch_all() -from bottle import run, request, response, get, post +from bottle import Bottle, run, request, response, get, post +app = Bottle() logger = logging.getLogger(__name__) @@ -158,7 +159,7 @@ def parse_and_error_handle(data): return "FAIL: " + str(validationResults.messages) -@post('/upload/') +@app.post('/upload/') def upload(): response.set_header("Access-Control-Allow-Origin", "*") try: @@ -181,7 +182,7 @@ def upload(): return parse_and_error_handle(message_body) -@get('/health_check/') +@app.get('/health_check/') def health_check(): """ This should only be used by the gateway monitoring script. It is used @@ -191,7 +192,7 @@ def health_check(): return Settings.EDDN_VERSION -@get('/stats/') +@app.get('/stats/') def stats(): response.set_header("Access-Control-Allow-Origin", "*") stats = statsCollector.getSummary() @@ -211,7 +212,7 @@ class MalformedUploadError(Exception): def main(): loadConfig() configure() - run( + app.run( host=Settings.GATEWAY_HTTP_BIND_ADDRESS, port=Settings.GATEWAY_HTTP_PORT, server='gevent',