# Path: tapes/reporting/http.py
# class HTTPReporter(Reporter):
#     """Exposes metrics via HTTP.
# 
#     For web applications, you should almost certainly just use your existing framework's capabilities. This is for
#     applications that don't have HTTP easily available.
#     """
#     def __init__(self, port, registry=None):
#         """
#         :param port: Port to listen on
#         :param registry: The registry to report from, defaults to the global one
#         """
#         super(HTTPReporter, self).__init__(registry)
#         self.port = port
#         self.thread = None
#         self.httpd = None
# 
#     def start(self):
#         class _RequestHandler(BaseHTTPRequestHandler):
#             def do_GET(inner_self):
#                 inner_self.send_response(200)
#                 response_string = json.dumps(self.registry.get_stats())
#                 inner_self.send_header('Content-Type', 'application/json')
#                 inner_self.send_header('Content-Length', len(response_string))
#                 inner_self.end_headers()
#                 inner_self.wfile.write(response_string.encode('utf-8'))
# 
#         server_address = '', self.port
# 
#         self.httpd = HTTPServer(server_address, _RequestHandler)
#         self.thread = Thread(target=self.httpd.serve_forever)
#         self.thread.start()
# 
#     def stop(self):
#         self.httpd.shutdown()
#         self.thread.join()
# 
# Path: tapes/distributed/registry.py
# class DistributedRegistry(BaseRegistry):
#     """A registry proxy that pushes metrics data to a ``RegistryAggregator``."""
#     def __init__(self, socket_addr=_DEFAULT_IPC):
#         """
#         :param socket_addr: the 0MQ IPC socket address; has to be the same as corresponding aggregator's
#         """
#         super(DistributedRegistry, self).__init__()
#         self.stats = dict()
#         self.socket_addr = socket_addr
#         self.zmq_context = None
#         self.socket = None
# 
#     def meter(self, name):
#         return self._get_or_add_stat(name, functools.partial(MeterProxy, self.socket, name))
# 
#     def timer(self, name):
#         return self._get_or_add_stat(name, functools.partial(TimerProxy, self.socket, name))
# 
#     def gauge(self, name, producer):
#         raise NotImplementedError('Gauge is unavailable in distributed mode')
# 
#     def counter(self, name):
#         return self._get_or_add_stat(name, functools.partial(CounterProxy, self.socket, name))
# 
#     def histogram(self, name):
#         return self._get_or_add_stat(name, functools.partial(HistogramProxy, self.socket, name))
# 
#     def connect(self):
#         """Connects to the 0MQ socket and starts publishing."""
#         distributed_logger.info('Connecting registry proxy to ZMQ socket %s', self.socket_addr)
#         self.zmq_context = zmq.Context()
#         sock = self.zmq_context.socket(zmq.PUB)
#         sock.set_hwm(0)
#         sock.setsockopt(zmq.LINGER, 0)
#         sock.connect(self.socket_addr)
#         distributed_logger.info('Connected registry proxy to ZMQ socket %s', self.socket_addr)
# 
#         def _reset_socket(values):
#             for value in values:
#                 try:
#                     _reset_socket(value.values())
#                 except AttributeError:
#                     value.socket = sock
# 
#         distributed_logger.debug('Resetting socket on metrics proxies')
#         _reset_socket(self.stats.values())
#         self.socket = sock
#         distributed_logger.debug('Reset socket on metrics proxies')
# 
#     def close(self):
#         distributed_logger.info('Shutting down metrics proxy')
#         self.socket.send_pyobj(Message('shutdown', 'noname', -1))
#         self.socket.disconnect(self.socket_addr)
#         self.socket.close()
#         self.zmq_context.destroy()
#         distributed_logger.info('Metrics proxy shutdown complete')
# 
# class RegistryAggregator(object):
#     """Aggregates multiple registry proxies and reports on the unified metrics."""
#     def __init__(self, reporter, socket_addr=_DEFAULT_IPC):
#         """Constructs a metrics registry aggregator.
# 
#         The ``registry`` field on the ``reporter`` argument will be reset to an implementation instance prior to
#         calling ``start()``. Any previously set registry is not guaranteed to be used.
# 
#         :param reporter: the reporter to use
#         :param socket_addr: the 0MQ socket address; has to be the same as corresponding proxies'
#         """
#         super(RegistryAggregator, self).__init__()
#         self.socket_addr = socket_addr
#         self.reporter = reporter
#         self.process = None
# 
#     def start(self, fork=True):
#         """Starts the registry aggregator.
# 
#         :param fork: whether to fork a process; if ``False``, blocks and stays in the existing process
#         """
#         if not fork:
#             distributed_logger.info('Starting metrics aggregator, not forking')
#             _registry_aggregator(self.reporter, self.socket_addr)
#         else:
#             distributed_logger.info('Starting metrics aggregator, forking')
#             p = Process(target=_registry_aggregator, args=(self.reporter, self.socket_addr, ))
#             p.start()
#             distributed_logger.info('Started metrics aggregator as PID %s', p.pid)
#             self.process = p
# 
#     def stop(self):
#         """Terminates the forked process.
# 
#         Only valid if started as a fork, because... well you wouldn't get here otherwise.
#         :return:
#         """
#         distributed_logger.info('Stopping metrics aggregator')
#         self.process.terminate()
#         self.process.join()
#         distributed_logger.info('Stopped metrics aggregator')


from tornado import ioloop, web, gen
from tapes.reporting.http import HTTPReporter
from tapes.distributed.registry import DistributedRegistry, RegistryAggregator


registry = DistributedRegistry()
registry.connect()
timer = registry.timer('my.timer')


class TimedHandler(web.RequestHandler):
    @gen.coroutine
    def get(self):

# Path: tapes/reporting/http.py
# class HTTPReporter(Reporter):
#     """Exposes metrics via HTTP.
# 
#     For web applications, you should almost certainly just use your existing framework's capabilities. This is for
#     applications that don't have HTTP easily available.
#     """
#     def __init__(self, port, registry=None):
#         """
#         :param port: Port to listen on
#         :param registry: The registry to report from, defaults to the global one
#         """
#         super(HTTPReporter, self).__init__(registry)
#         self.port = port
#         self.thread = None
#         self.httpd = None
# 
#     def start(self):
#         class _RequestHandler(BaseHTTPRequestHandler):
#             def do_GET(inner_self):
#                 inner_self.send_response(200)
#                 response_string = json.dumps(self.registry.get_stats())
#                 inner_self.send_header('Content-Type', 'application/json')
#                 inner_self.send_header('Content-Length', len(response_string))
#                 inner_self.end_headers()
#                 inner_self.wfile.write(response_string.encode('utf-8'))
# 
#         server_address = '', self.port
# 
#         self.httpd = HTTPServer(server_address, _RequestHandler)
#         self.thread = Thread(target=self.httpd.serve_forever)
#         self.thread.start()
# 
#     def stop(self):
#         self.httpd.shutdown()
#         self.thread.join()
# 
# Path: tapes/distributed/registry.py
# class DistributedRegistry(BaseRegistry):
#     """A registry proxy that pushes metrics data to a ``RegistryAggregator``."""
#     def __init__(self, socket_addr=_DEFAULT_IPC):
#         """
#         :param socket_addr: the 0MQ IPC socket address; has to be the same as corresponding aggregator's
#         """
#         super(DistributedRegistry, self).__init__()
#         self.stats = dict()
#         self.socket_addr = socket_addr
#         self.zmq_context = None
#         self.socket = None
# 
#     def meter(self, name):
#         return self._get_or_add_stat(name, functools.partial(MeterProxy, self.socket, name))
# 
#     def timer(self, name):
#         return self._get_or_add_stat(name, functools.partial(TimerProxy, self.socket, name))
# 
#     def gauge(self, name, producer):
#         raise NotImplementedError('Gauge is unavailable in distributed mode')
# 
#     def counter(self, name):
#         return self._get_or_add_stat(name, functools.partial(CounterProxy, self.socket, name))
# 
#     def histogram(self, name):
#         return self._get_or_add_stat(name, functools.partial(HistogramProxy, self.socket, name))
# 
#     def connect(self):
#         """Connects to the 0MQ socket and starts publishing."""
#         distributed_logger.info('Connecting registry proxy to ZMQ socket %s', self.socket_addr)
#         self.zmq_context = zmq.Context()
#         sock = self.zmq_context.socket(zmq.PUB)
#         sock.set_hwm(0)
#         sock.setsockopt(zmq.LINGER, 0)
#         sock.connect(self.socket_addr)
#         distributed_logger.info('Connected registry proxy to ZMQ socket %s', self.socket_addr)
# 
#         def _reset_socket(values):
#             for value in values:
#                 try:
#                     _reset_socket(value.values())
#                 except AttributeError:
#                     value.socket = sock
# 
#         distributed_logger.debug('Resetting socket on metrics proxies')
#         _reset_socket(self.stats.values())
#         self.socket = sock
#         distributed_logger.debug('Reset socket on metrics proxies')
# 
#     def close(self):
#         distributed_logger.info('Shutting down metrics proxy')
#         self.socket.send_pyobj(Message('shutdown', 'noname', -1))
#         self.socket.disconnect(self.socket_addr)
#         self.socket.close()
#         self.zmq_context.destroy()
#         distributed_logger.info('Metrics proxy shutdown complete')
# 
# class RegistryAggregator(object):
#     """Aggregates multiple registry proxies and reports on the unified metrics."""
#     def __init__(self, reporter, socket_addr=_DEFAULT_IPC):
#         """Constructs a metrics registry aggregator.
# 
#         The ``registry`` field on the ``reporter`` argument will be reset to an implementation instance prior to
#         calling ``start()``. Any previously set registry is not guaranteed to be used.
# 
#         :param reporter: the reporter to use
#         :param socket_addr: the 0MQ socket address; has to be the same as corresponding proxies'
#         """
#         super(RegistryAggregator, self).__init__()
#         self.socket_addr = socket_addr
#         self.reporter = reporter
#         self.process = None
# 
#     def start(self, fork=True):
#         """Starts the registry aggregator.
# 
#         :param fork: whether to fork a process; if ``False``, blocks and stays in the existing process
#         """
#         if not fork:
#             distributed_logger.info('Starting metrics aggregator, not forking')
#             _registry_aggregator(self.reporter, self.socket_addr)
#         else:
#             distributed_logger.info('Starting metrics aggregator, forking')
#             p = Process(target=_registry_aggregator, args=(self.reporter, self.socket_addr, ))
#             p.start()
#             distributed_logger.info('Started metrics aggregator as PID %s', p.pid)
#             self.process = p
# 
#     def stop(self):
#         """Terminates the forked process.
# 
#         Only valid if started as a fork, because... well you wouldn't get here otherwise.
#         :return:
#         """
#         distributed_logger.info('Stopping metrics aggregator')
#         self.process.terminate()
#         self.process.join()
#         distributed_logger.info('Stopped metrics aggregator')


# Path: benchmark/tornado/zmq_metrics_single_process.py
from tornado import ioloop, web, gen
from tapes.reporting.http import HTTPReporter
from tapes.distributed.registry import DistributedRegistry, RegistryAggregator



registry = DistributedRegistry()
registry.connect()
timer = registry.timer('my.timer')


class TimedHandler(web.RequestHandler):
    @gen.coroutine
    def get(self):

        with timer.time():