asyncplot / asyncplot /

r"""Threaded Socket Server"""

import cPickle
import socket
import threading
import SocketServer

import mmf

class PlotRequestHandler(SocketServer.BaseRequestHandler):
    def handle(self):

class PlotSocketServer(SocketServer.ThreadingMixIn,
    r"""Simple threaded socket server.  Listens on the specified port, and
    launches Socket threads on connection.

    Call :meth:`update` to update the plot data.

    To Do
    * Add timeouts.
    _PORT = 9999
    _HOST = ''

    def __init__(self, host=_HOST, port=_PORT):
        self.lock = threading.Lock()  # RLock()??
        self.have_data = threading.Event() = None
        self.daemon_threads = True       # Don't keep python alive.
        self.allow_reuse_address = True  # Allow port reuse after termination.
        SocketServer.TCPServer.__init__(self, (host, port),

    def get_data(self, block=True):
        r"""The object is pickled here."""
        with self.lock:
            return cPickle.dumps(
    def update(self, *v, **kw):
        with self.lock:
   = (v, kw)
        self.have_data.set()    # This is very slow!

class Server(threading.Thread):
    def __init__(self, host=PlotSocketServer._HOST,
        self.server = PlotSocketServer(host=host, port=port)
        threading.Thread.__init__(self, target=self.server.serve_forever)
        self.daemon = True               # Don't keep python alive.

    def __enter__(self):
        return self.server

    def __exit__(self, type, value, traceback):
        return value is None

def example_server():
    import time
    import numpy as np
    x = np.linspace(0, 2*np.pi, 100)
    t = 0
    dt = 0.01
    tic = time.time()
    with Server() as s:
        for n in xrange(100000):
            if n % 100000 == 0:
                print n, time.time() - tic
                tic = time.time()
            t += dt
            y = np.sin(x + t)
            s.update(x, y)