def __init__(self): # Check is class name is properly constructed # like SomethingHandler if (self.__class__.__name__[-7:] != 'Handler'): raise ValueError( "Wrong handler class name : must be [something]Handler") self._handler_name = (self.__class__.__name__)[0:-7].lower() self._config = Config(self._handler_name) logging.debug("Initializing Handler's base for %s" % self._handler_name) setproctitle("griotte-%s" % self._handler_name) self._ws = WebSocket() self._ws.add_listener("%s.command.ping" % self._handler_name, self.ping) logging.debug("Added ping listener for %s" % self._handler_name) # Install signal handlers that child class can override signal.signal(signal.SIGINT, self._signal) signal.signal(signal.SIGTERM, self._signal) signal.signal(signal.SIGUSR1, self._signal) signal.signal(signal.SIGHUP, self._signal)
class Handler: def __init__(self): # Check is class name is properly constructed # like SomethingHandler if (self.__class__.__name__[-7:] != 'Handler'): raise ValueError( "Wrong handler class name : must be [something]Handler") self._handler_name = (self.__class__.__name__)[0:-7].lower() self._config = Config(self._handler_name) logging.debug("Initializing Handler's base for %s" % self._handler_name) setproctitle("griotte-%s" % self._handler_name) self._ws = WebSocket() self._ws.add_listener("%s.command.ping" % self._handler_name, self.ping) logging.debug("Added ping listener for %s" % self._handler_name) # Install signal handlers that child class can override signal.signal(signal.SIGINT, self._signal) signal.signal(signal.SIGTERM, self._signal) signal.signal(signal.SIGUSR1, self._signal) signal.signal(signal.SIGHUP, self._signal) def _signal(self, signum, frame): pass def ping(self, channel, message): self._ws.send("%s.event.pong" % self._handler_name, {"handler": self._handler_name}) logging.debug("%s sending pong" % self._handler_name) def send_event(self, event, data): self._ws.send("%s.event.%s" % (self._handler_name, event), data) def add_listener(self, command, full_path=False, callback=None): if callback is None: callback = getattr(self, "_wscb_%s" % command.split(".")[-1]) if full_path: path = command else: path = "%s.command.%s" % (self._handler_name, command) self._ws.add_listener(path, callback)
class Handler: def __init__(self): # Check is class name is properly constructed # like SomethingHandler if (self.__class__.__name__[-7:] != 'Handler'): raise ValueError("Wrong handler class name : must be [something]Handler") self._handler_name = (self.__class__.__name__)[0:-7].lower() self._config = Config(self._handler_name) logging.debug("Initializing Handler's base for %s" % self._handler_name) setproctitle("griotte-%s" % self._handler_name) self._ws = WebSocket() self._ws.add_listener("%s.command.ping" % self._handler_name, self.ping) logging.debug("Added ping listener for %s" % self._handler_name) # Install signal handlers that child class can override signal.signal(signal.SIGINT, self._signal) signal.signal(signal.SIGTERM, self._signal) signal.signal(signal.SIGUSR1, self._signal) signal.signal(signal.SIGHUP, self._signal) def _signal(self, signum, frame): pass def ping(self, channel, message): self._ws.send("%s.event.pong" % self._handler_name, { "handler": self._handler_name }) logging.debug("%s sending pong" % self._handler_name) def send_event(self, event, data): self._ws.send("%s.event.%s" % (self._handler_name, event), data) def add_listener(self, command, full_path=False, callback=None): if callback is None: callback = getattr(self, "_wscb_%s" % command.split(".")[-1]) if full_path: path = command else: path = "%s.command.%s" % (self._handler_name, command) self._ws.add_listener(path, callback)
def __init__(self): # Check is class name is properly constructed # like SomethingHandler if (self.__class__.__name__[-7:] != 'Handler'): raise ValueError("Wrong handler class name : must be [something]Handler") self._handler_name = (self.__class__.__name__)[0:-7].lower() self._config = Config(self._handler_name) logging.debug("Initializing Handler's base for %s" % self._handler_name) setproctitle("griotte-%s" % self._handler_name) self._ws = WebSocket() self._ws.add_listener("%s.command.ping" % self._handler_name, self.ping) logging.debug("Added ping listener for %s" % self._handler_name) # Install signal handlers that child class can override signal.signal(signal.SIGINT, self._signal) signal.signal(signal.SIGTERM, self._signal) signal.signal(signal.SIGUSR1, self._signal) signal.signal(signal.SIGHUP, self._signal)
import json import sys import logging from tornado.options import define, options from griotte.websocket import WebSocket from griotte.config import Config import tornado.ioloop Config("DEFAULT") define("watchdog", default=0.1, help="Watchdog interval") if __name__ == "__main__": def on_message(channel, message): logging.info(" >>> On channel \"%s\" : %s" % (channel, message)) channels = () channels = options.parse_command_line() if not channels: logging.warning("No channel specified, watching meta.presence") channels.append("meta.presence") ws = WebSocket() for chan in channels: ws.add_listener(chan, on_message) ws.start(detach=False, watchdog_interval=options.watchdog)
def __init__(self, uri=None): self._ws = WebSocket(uri=uri) self._ws.start(watchdog_interval=2) self._subscriptions = {}
class __Expecter: """ Utility class that sends and receives data over websocket for server-side blocks """ def __init__(self, uri=None): self._ws = WebSocket(uri=uri) self._ws.start(watchdog_interval=2) self._subscriptions = {} def send_expect(self, channel_out, channel_in, data='{}', flush=False): """ Sends a message over websocket and waits for a reply A combination of :py:func:`send` and :py:func:`expect` :param channel_out: The channel to write to :type channel: str :param channel_in: The channel to listen to :type channel: str :param data: The data to send :type data: str -- json encoded :param flush: Whether the incoming queue must be flushed before handling message (set to True to prevent receiving past messages ) :type flush: bool """ self._subscribe(channel_in) if flush: self._flush_queue(channel_in) self._ws.send(channel_out, data) return self._subscriptions[channel_in].get() def send(self, channel, data='{}'): """ Sends a message over websocket Utility function that wraps websocket message sending and takes care of opening a websocket if needed :param channel: The channel to write to :type channel: str. :param data: The data to send :type data: str -- json encoded :param flush: Whether the incoming queue must be flushed before handling message (set to True to prevent receiving past messages ) :type flush: bool """ logging.debug("sending message on %s" % channel) self._ws.send(channel, data) def expect(self, channel, flush=False): """ Expects a message on a channel Blocks until the message arrives and returns the 'data' part of the message :param channel: Channel to listen to :type channel: str :param flush: Whether the incoming queue must be flushed before handling message (set to True to prevent receiving past messages ) :type flush: bool :rtype: dict -- the message we got on the wire """ self._subscribe(channel) if flush: self._flush_queue(channel) data = self._subscriptions[channel].get() logging.debug("got message on %s" % channel) #self._unsubscribe(channel) return data def quit(self): self._unsubscribe_all() self._ws.stop() def on_message(self, channel, data): try: self._subscriptions[channel].put(data) except KeyError: # Clients can watch wildcard channels for watched_channel in self._subscriptions: if fnmatch.fnmatch(channel, watched_channel): # We had a match for watched_channel key # We have to iterate over client list for this channel self._subscriptions[watched_channel].put(data) return logging.error( "Received a message for a channel we didn't subscribe to (%s)" % channel) def _flush_queue(self, channel): logging.debug("Flushing queue for channel %s" % channel) try: while not self._subscriptions[channel].empty(): self._subscriptions[channel].get() logging.debug("flushed one message") except Empty: return def _subscribe(self, channel): if channel in self._subscriptions: return False self._subscriptions[channel] = Queue() logging.debug("subscribing to channel %s" % channel) self._ws.add_listener(channel, self.on_message) return True def _unsubscribe(self, channel): if channel not in self._subscriptions: return logging.debug("unsubscribing from channel %s" % channel) self._ws.remove_listener(channel) logging.debug("removing channel %s" % channel) self._subscriptions.pop(channel) def _unsubscribe_all(self): for channel in self._subscriptions.copy().keys(): self._unsubscribe(channel)
class __Expecter: """ Utility class that sends and receives data over websocket for server-side blocks """ def __init__(self, uri=None): self._ws = WebSocket(uri=uri) self._ws.start(watchdog_interval=2) self._subscriptions = {} def send_expect(self, channel_out, channel_in, data='{}', flush=False): """ Sends a message over websocket and waits for a reply A combination of :py:func:`send` and :py:func:`expect` :param channel_out: The channel to write to :type channel: str :param channel_in: The channel to listen to :type channel: str :param data: The data to send :type data: str -- json encoded :param flush: Whether the incoming queue must be flushed before handling message (set to True to prevent receiving past messages ) :type flush: bool """ self._subscribe(channel_in) if flush: self._flush_queue(channel_in) self._ws.send(channel_out, data) return self._subscriptions[channel_in].get() def send(self, channel, data = '{}'): """ Sends a message over websocket Utility function that wraps websocket message sending and takes care of opening a websocket if needed :param channel: The channel to write to :type channel: str. :param data: The data to send :type data: str -- json encoded :param flush: Whether the incoming queue must be flushed before handling message (set to True to prevent receiving past messages ) :type flush: bool """ logging.debug("sending message on %s" % channel) self._ws.send(channel, data) def expect(self, channel, flush=False): """ Expects a message on a channel Blocks until the message arrives and returns the 'data' part of the message :param channel: Channel to listen to :type channel: str :param flush: Whether the incoming queue must be flushed before handling message (set to True to prevent receiving past messages ) :type flush: bool :rtype: dict -- the message we got on the wire """ self._subscribe(channel) if flush: self._flush_queue(channel) data = self._subscriptions[channel].get() logging.debug("got message on %s" % channel) #self._unsubscribe(channel) return data def quit(self): self._unsubscribe_all() self._ws.stop() def on_message(self, channel, data): try: self._subscriptions[channel].put(data) except KeyError: # Clients can watch wildcard channels for watched_channel in self._subscriptions: if fnmatch.fnmatch(channel, watched_channel): # We had a match for watched_channel key # We have to iterate over client list for this channel self._subscriptions[watched_channel].put(data) return logging.error("Received a message for a channel we didn't subscribe to (%s)" % channel) def _flush_queue(self, channel): logging.debug("Flushing queue for channel %s" % channel) try: while not self._subscriptions[channel].empty(): self._subscriptions[channel].get() logging.debug("flushed one message") except Empty: return def _subscribe(self, channel): if channel in self._subscriptions: return False self._subscriptions[channel] = Queue() logging.debug("subscribing to channel %s" % channel) self._ws.add_listener(channel, self.on_message) return True def _unsubscribe(self, channel): if channel not in self._subscriptions: return logging.debug("unsubscribing from channel %s" % channel) self._ws.remove_listener(channel) logging.debug("removing channel %s" % channel) self._subscriptions.pop(channel) def _unsubscribe_all(self): for channel in self._subscriptions.copy().keys(): self._unsubscribe(channel)