def sub(self, uri, prefix=''): """ subscribe the web client to this socket """ ident = self.ident(uri, prefix) idents = self.recievers.iterkeys() self.log('subscribe:', 'requested', ident) # we don't need to actually create more filtered sockets if we # already have a general one on the books. # the javascript end will handle choosing the most specific # subscriber callback for any message we send over the wire if ident in self.recievers or self.any_has_prefix(ident, idents): # already subscribed self.write_message({'success': 'already subscribed'}) self.log('subscribe:', 'already has', ident) return # create a new reciever and a callback for it self.log('subscribe:', 'subscribing to prefix', repr(prefix), 'at uri', uri) rcvr = AsyncReciever(sub(uri), prefix) self.recievers[ident] = rcvr rcvr.on_recieve(self.write_squidwork) self.write_message({'success': 'subscribed {}'.format(ident)})
def main(): """ run the app! currently very hairy. starts with dummy data """ conf = Config('squidwork.web.monitor') conf.option('cache-size', type=int, help='numer of elements to store') conf.option('display-size', type=int, help='numer of elements to store') conf.retrieve() settings = dict(debug=conf.debug, template_path=os.path.dirname(os.path.realpath(__file__))) port = conf.port # the message buffer stores the last N mesages cache = MessageCache(conf.cache_size) # subscribe to all services! uris = Service.all_uris() recvr = AsyncReciever(sub(*uris)) recvr.on_recieve(cache.add) # generate some dummy data to pre-populate the cache with dummy = [dummy_message() for i in range(0, 20)] cache.add(*dummy) # we include the api_handlers from squidwork.web so we can use the # squidwork web<--WebSocket-->ZeroMq bridge all_handlers = api_handlers(conf.raw_config, debug=conf.debug) + [ # the index page is totally static -- all it does is request javascript (r"/", TemplateRenderer, dict(source='templates/index.html')), # JSON view of whatever is currently in our cache. this is how the # app gets its initial data on page load (r"/data.json", JSONHandler, dict(encoder=MessageEncoder, data=( lambda: {'latest': cache.cache, 'types': cache.by_origin}))), # big coffeescript app written with Mithril.js. All HTML structure on # the page is produced by view functions in app.coffee (r"/app.js", CoffeescriptHandler, dict(source='templates/app.coffee', count=conf.display_size)), # static, plain-jane scss (r"/style.css", ScssHandler, dict(source='templates/style.scss')), ] # spin up the app! app = tornado.web.Application(all_handlers, **settings) try: app.listen(port) tornado.ioloop.IOLoop.instance().start() except KeyboardInterrupt: print ' keyboard interrupt: exiting.'