)]}'
{"horizon-realtime.py":[{"author":{"_account_id":6966,"name":"Jeffrey J. Walls","email":"jeff.walls@hpe.com","username":"ftcjeff"},"change_message_id":"2b20454965b8b405b6800ab005af976f9ee3801c","unresolved":false,"context_lines":[{"line_number":66,"context_line":"                    topic\u003d\u0027notifications.info\u0027,"},{"line_number":67,"context_line":"                    exchange_name\u003dexchange_name,"},{"line_number":68,"context_line":"                )"},{"line_number":69,"context_line":"            except Exception:"},{"line_number":70,"context_line":"                LOG.info(\u0027Could not join consumer pool %s/%s\u0027, topic,"},{"line_number":71,"context_line":"                        exchange_name)"},{"line_number":72,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAATn%2F9Pus%3D","line":69,"updated":"2013-12-13 15:15:21.000000000","message":"I know it\u0027s a POC, but especially for debugging, logging the exception is going to be really helpful I think.","commit_id":"f60064dbe915e63c324881c171c901c444eea7b5"},{"author":{"_account_id":4330,"name":"Tomas Sedovic","email":"tsedovic@redhat.com","username":"tomas-8c8"},"change_message_id":"555a8401b2f4631dbd2300e55e8841572728d4c3","unresolved":false,"context_lines":[{"line_number":66,"context_line":"                    topic\u003d\u0027notifications.info\u0027,"},{"line_number":67,"context_line":"                    exchange_name\u003dexchange_name,"},{"line_number":68,"context_line":"                )"},{"line_number":69,"context_line":"            except Exception:"},{"line_number":70,"context_line":"                LOG.info(\u0027Could not join consumer pool %s/%s\u0027, topic,"},{"line_number":71,"context_line":"                        exchange_name)"},{"line_number":72,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAAUH%2F%2BK4E%3D","line":69,"in_reply_to":"AAAATn%2F9Pus%3D","updated":"2014-01-29 15:24:57.000000000","message":"Done","commit_id":"f60064dbe915e63c324881c171c901c444eea7b5"},{"author":{"_account_id":6966,"name":"Jeffrey J. Walls","email":"jeff.walls@hpe.com","username":"ftcjeff"},"change_message_id":"2b20454965b8b405b6800ab005af976f9ee3801c","unresolved":false,"context_lines":[{"line_number":72,"context_line":""},{"line_number":73,"context_line":"    def process_notification(self, notification):"},{"line_number":74,"context_line":"        \"\"\""},{"line_number":75,"context_line":"        Passes the recenived notifications to the queue shared with socket.io."},{"line_number":76,"context_line":"        \"\"\""},{"line_number":77,"context_line":"        LOG.info(\"Received OpenStack notification: %s\","},{"line_number":78,"context_line":"            notification.get(\u0027event_type\u0027, \u0027unknown\u0027))"}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAATn%2F9PuI%3D","line":75,"updated":"2013-12-13 15:15:21.000000000","message":"Received is misspelled :-)","commit_id":"f60064dbe915e63c324881c171c901c444eea7b5"},{"author":{"_account_id":4330,"name":"Tomas Sedovic","email":"tsedovic@redhat.com","username":"tomas-8c8"},"change_message_id":"555a8401b2f4631dbd2300e55e8841572728d4c3","unresolved":false,"context_lines":[{"line_number":72,"context_line":""},{"line_number":73,"context_line":"    def process_notification(self, notification):"},{"line_number":74,"context_line":"        \"\"\""},{"line_number":75,"context_line":"        Passes the recenived notifications to the queue shared with socket.io."},{"line_number":76,"context_line":"        \"\"\""},{"line_number":77,"context_line":"        LOG.info(\"Received OpenStack notification: %s\","},{"line_number":78,"context_line":"            notification.get(\u0027event_type\u0027, \u0027unknown\u0027))"}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAAUH%2F%2BK34%3D","line":75,"in_reply_to":"AAAATn%2F9PuI%3D","updated":"2014-01-29 15:24:57.000000000","message":"Done","commit_id":"f60064dbe915e63c324881c171c901c444eea7b5"},{"author":{"_account_id":6966,"name":"Jeffrey J. Walls","email":"jeff.walls@hpe.com","username":"ftcjeff"},"change_message_id":"2b20454965b8b405b6800ab005af976f9ee3801c","unresolved":false,"context_lines":[{"line_number":79,"context_line":"        global EVENT_QUEUE"},{"line_number":80,"context_line":"        EVENT_QUEUE.append(notification)"},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"def scrub_event(event, whitelist\u003dNone):"},{"line_number":83,"context_line":"    if not whitelist:"},{"line_number":84,"context_line":"        whitelist \u003d []"},{"line_number":85,"context_line":"    event_type \u003d event.get(\u0027event_type\u0027)"}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAATn%2F9Ptk%3D","line":82,"updated":"2013-12-13 15:15:21.000000000","message":"Why don\u0027t you just default whitelist to \u003d[] ?","commit_id":"f60064dbe915e63c324881c171c901c444eea7b5"},{"author":{"_account_id":4330,"name":"Tomas Sedovic","email":"tsedovic@redhat.com","username":"tomas-8c8"},"change_message_id":"555a8401b2f4631dbd2300e55e8841572728d4c3","unresolved":false,"context_lines":[{"line_number":79,"context_line":"        global EVENT_QUEUE"},{"line_number":80,"context_line":"        EVENT_QUEUE.append(notification)"},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"def scrub_event(event, whitelist\u003dNone):"},{"line_number":83,"context_line":"    if not whitelist:"},{"line_number":84,"context_line":"        whitelist \u003d []"},{"line_number":85,"context_line":"    event_type \u003d event.get(\u0027event_type\u0027)"}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAAUH%2F%2BK1A%3D","line":82,"in_reply_to":"AAAATn%2F9Ptk%3D","updated":"2014-01-29 15:24:57.000000000","message":"That would make the all the whitelists for all the scrub_event calls point to a single shared object.\n\nIt\u0027s a good rule in Python not to the set default arguments to mutable things since it leads to obscure bugs.\n\nDefaulting to an empty tuple would be fine, though.","commit_id":"f60064dbe915e63c324881c171c901c444eea7b5"},{"author":{"_account_id":6966,"name":"Jeffrey J. Walls","email":"jeff.walls@hpe.com","username":"ftcjeff"},"change_message_id":"2b20454965b8b405b6800ab005af976f9ee3801c","unresolved":false,"context_lines":[{"line_number":152,"context_line":"    This needs to be in a separate thread due to the conflicts between"},{"line_number":153,"context_line":"    eventlet and tornado."},{"line_number":154,"context_line":"    \"\"\""},{"line_number":155,"context_line":"    # Create tornadio router"},{"line_number":156,"context_line":"    WebSocketRouter \u003d sockjs.tornado.SockJSRouter(WebSocketConnection)"},{"line_number":157,"context_line":""},{"line_number":158,"context_line":"    # Start the websockets application"}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAATn%2F9Psc%3D","line":155,"updated":"2013-12-13 15:15:21.000000000","message":"tornado misspelled :-)","commit_id":"f60064dbe915e63c324881c171c901c444eea7b5"},{"author":{"_account_id":4330,"name":"Tomas Sedovic","email":"tsedovic@redhat.com","username":"tomas-8c8"},"change_message_id":"555a8401b2f4631dbd2300e55e8841572728d4c3","unresolved":false,"context_lines":[{"line_number":152,"context_line":"    This needs to be in a separate thread due to the conflicts between"},{"line_number":153,"context_line":"    eventlet and tornado."},{"line_number":154,"context_line":"    \"\"\""},{"line_number":155,"context_line":"    # Create tornadio router"},{"line_number":156,"context_line":"    WebSocketRouter \u003d sockjs.tornado.SockJSRouter(WebSocketConnection)"},{"line_number":157,"context_line":""},{"line_number":158,"context_line":"    # Start the websockets application"}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAAUH%2F%2BK0w%3D","line":155,"in_reply_to":"AAAATn%2F9Psc%3D","updated":"2014-01-29 15:24:57.000000000","message":"Done","commit_id":"f60064dbe915e63c324881c171c901c444eea7b5"},{"author":{"_account_id":6966,"name":"Jeffrey J. Walls","email":"jeff.walls@hpe.com","username":"ftcjeff"},"change_message_id":"2b20454965b8b405b6800ab005af976f9ee3801c","unresolved":false,"context_lines":[{"line_number":157,"context_line":""},{"line_number":158,"context_line":"    # Start the websockets application"},{"line_number":159,"context_line":"    websocket_app \u003d tornado.web.Application(WebSocketRouter.urls)"},{"line_number":160,"context_line":"    websocket_app.listen(12327)"},{"line_number":161,"context_line":""},{"line_number":162,"context_line":"    # Start the Django server"},{"line_number":163,"context_line":"    http_server \u003d tornado.httpserver.HTTPServer(django_app)"}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAATn%2F9PsU%3D","line":160,"updated":"2013-12-13 15:15:21.000000000","message":"Can / should this port be set via config?","commit_id":"f60064dbe915e63c324881c171c901c444eea7b5"},{"author":{"_account_id":4330,"name":"Tomas Sedovic","email":"tsedovic@redhat.com","username":"tomas-8c8"},"change_message_id":"555a8401b2f4631dbd2300e55e8841572728d4c3","unresolved":false,"context_lines":[{"line_number":157,"context_line":""},{"line_number":158,"context_line":"    # Start the websockets application"},{"line_number":159,"context_line":"    websocket_app \u003d tornado.web.Application(WebSocketRouter.urls)"},{"line_number":160,"context_line":"    websocket_app.listen(12327)"},{"line_number":161,"context_line":""},{"line_number":162,"context_line":"    # Start the Django server"},{"line_number":163,"context_line":"    http_server \u003d tornado.httpserver.HTTPServer(django_app)"}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAAUH%2F%2BKyU%3D","line":160,"in_reply_to":"AAAATn%2F9PsU%3D","updated":"2014-01-29 15:24:57.000000000","message":"Yeah I think it should. However, the same port value needs to be set on the client side (see horizon/static/horizon/js/horizon.realtime.js).\n\nAny suggestions on how to do that without it being a huge mess?","commit_id":"f60064dbe915e63c324881c171c901c444eea7b5"},{"author":{"_account_id":6966,"name":"Jeffrey J. Walls","email":"jeff.walls@hpe.com","username":"ftcjeff"},"change_message_id":"2b20454965b8b405b6800ab005af976f9ee3801c","unresolved":false,"context_lines":[{"line_number":173,"context_line":"    thread.start_new_thread(websocket_server,"},{"line_number":174,"context_line":"        (cfg.CONF.bind_host, cfg.CONF.bind_port))"},{"line_number":175,"context_line":"    while True:"},{"line_number":176,"context_line":"        eventlet.sleep(0.1)"}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAATn%2F9Pr4%3D","line":176,"updated":"2013-12-13 15:15:21.000000000","message":"Seems like in production you would want some other mechanism to wait instead of a fast, tight spin loop?","commit_id":"f60064dbe915e63c324881c171c901c444eea7b5"},{"author":{"_account_id":4330,"name":"Tomas Sedovic","email":"tsedovic@redhat.com","username":"tomas-8c8"},"change_message_id":"555a8401b2f4631dbd2300e55e8841572728d4c3","unresolved":false,"context_lines":[{"line_number":173,"context_line":"    thread.start_new_thread(websocket_server,"},{"line_number":174,"context_line":"        (cfg.CONF.bind_host, cfg.CONF.bind_port))"},{"line_number":175,"context_line":"    while True:"},{"line_number":176,"context_line":"        eventlet.sleep(0.1)"}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAAUH%2F%2BKwE%3D","line":176,"in_reply_to":"AAAATn%2F9Pr4%3D","updated":"2014-01-29 15:24:57.000000000","message":"Well, this is a bit complicated: we need Tornado for the sockjs stuff (which was the only viable option I could find 6 months back) but we also need Eventlet since that\u0027s the system baked into the OpenStack common RPC code.\n\nBoth are green threading systems that want to control the event loop. And they don\u0027t play nice with each other (hence the separate thread for the tornado/websockets stuff).\n\nSo what happens here is: we run NotificationCollector in the same OS thread as the main program and eventlet takes control over that. And we spawn another OS thread for the tornado server.\n\nThe `while True` loop is there only to keep eventlet happy. If I understand it correctly, the sleep value doesn\u0027t actually do anything for us. If eventlet provided something like eventlet.loop_forever(), I\u0027d call it here but it doesn\u0027t.\n\nI should be able to change the sleep to say 1 hour and it would have no difference on the timing of the events or whatever. We don\u0027t actually care about the green thread in the loop at all -- it should just sleep forever and make sure it doesn\u0027t interupt the RPC notification collector thread.","commit_id":"f60064dbe915e63c324881c171c901c444eea7b5"}]}
