<commit_before>
HOST, PORT = "localhost", 11982

import asyncore
import asynchat
import Queue
import random
import socket
import string

from collections import namedtuple

JoinEvent = namedtuple('JoinEvent', ['id', 'version'])
QuitEvent = namedtuple('QuitEvent', ['id'])

class CompetitionServer(object):
    def __init__(self, event_queue):
        self.event_queue = event_queue
        self.competitors = {}

    def update(self):
        try:
            event = self.event_queue.get_nowait()
            self.handle_event(event)
        except Queue.Empty:
            pass

    def handle_event(self, event):
        if isinstance(event, JoinEvent):
            print "JOIN: %s v%.2f" % (event.id, event.version)

        elif isinstance(event, QuitEvent):
            print "QUIT: %s" % event.id

    def competitor_quit(self, addr):
        pass

class FreecellCompetitor(asynchat.async_chat):
    def __init__(self, sock, addr, event_queue):
        """
        :param socket.socket sock: Socket
        :param (str, int) addr: Address
        :param Queue event_queue: Event queue
        """
        asynchat.async_chat.__init__(self, sock=sock)
        self.set_terminator("\r\n")
        self.addr = addr
        self.event_queue = event_queue
        self.id = ''.join(random.choice(string.ascii_uppercase + string.digits) for x in range(8))
        self.buffer = []
        self.state = "connecting"

    def handle_close(self):
        if self.state != "disconnected":
            self.event_queue.put(QuitEvent(id=self.id))
            self.state = "disconnected"

    def collect_incoming_data(self, data):
        self.buffer.append(data)

    def found_terminator(self):
        self.create_event("".join(self.buffer))
        self.buffer = []

    def create_event(self, data):
        event_type, trash, rest = data.partition(" ")
        print event_type
        if event_type == "connect":
            self.event_queue.put(JoinEvent(id=self.id, version=float(rest)))
            self.state = "connected"

class FreecellServer(asyncore.dispatcher):
    def __init__(self, host, port, event_queue):
        asyncore.dispatcher.__init__(self)
        self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
        self.set_reuse_addr()
        self.bind((host, port))
        self.listen(1)
        self.event_queue = event_queue

    def handle_accept(self):
        pair = self.accept()
        if pair is not None:
            sock, addr = pair
            handler = FreecellCompetitor(sock, addr, self.event_queue)

if __name__ == "__main__":
    event_queue = Queue.Queue()
    network_server = FreecellServer(HOST, PORT, event_queue)
    competition_server = CompetitionServer(event_queue)
    while True:
        asyncore.loop(count=1, timeout=.1)
        # todo: slap that in a thread
        competition_server.update()

<commit_msg>Networking is threaded<commit_after>
HOST, PORT = "localhost", 11982

import asyncore
import asynchat
import json
import Queue
import random
import socket
import string
import threading

from collections import namedtuple


JoinEvent = namedtuple('JoinEvent', ['id', 'version'])
QuitEvent = namedtuple('QuitEvent', ['id'])
StopServerEvent = namedtuple('StopServerEvent', ['reason'])

class CompetitionServer(object):
    def __init__(self, host, port):
        self.event_queue = Queue.Queue()
        self.competitors = {}
        self.run_networking = threading.Event()
        self.networking = FreecellServer(host, port, self.event_queue, self.run_networking)
        threading.Thread(target=self.networking.run).start()
        self.running = True

    def start(self):
        self.run_networking.set()
        self.loop()

    def loop(self):
        while self.running:
            try:
                self.update()
            except KeyboardInterrupt:
                self.quit("Keyboard Interrupt")
                self.running = False
        self.run_networking.clear()

    def update(self):
        try:
            event = self.event_queue.get_nowait()
            self.handle_event(event)
        except Queue.Empty:
            pass

    def handle_event(self, event):
        if isinstance(event, JoinEvent):
            print "JOIN: %s v%.2f" % (event.id, event.version)

        elif isinstance(event, QuitEvent):
            print "QUIT: %s" % event.id

    def competitor_quit(self, addr):
        pass

    def quit(self, reason):
        self.event_queue.put(StopServerEvent(reason=reason))

class FreecellCompetitor(asynchat.async_chat):
    def __init__(self, sock, addr, event_queue):
        """
        :param socket.socket sock: Socket
        :param (str, int) addr: Address
        :param Queue.Queue event_queue: Event queue
        """
        asynchat.async_chat.__init__(self, sock=sock)
        self.set_terminator("\r\n")
        self.addr = addr
        self.event_queue = event_queue
        self.id = ''.join(random.choice(string.ascii_uppercase + string.digits) for x in range(8))
        self.buffer = []
        self.state = "connecting"

    def handle_close(self):
        if self.state != "disconnected":
            self.event_queue.put(QuitEvent(id=self.id))
            self.state = "disconnected"

    def collect_incoming_data(self, data):
        self.buffer.append(data)

    def found_terminator(self):
        message = json.loads("".join(self.buffer))
        if "event" in message:
            self.create_event(message)
        else:
            print "Non-event message received"

        self.buffer = []

    def create_event(self, message):
        if message["event"] == "connect":
            self.event_queue.put(JoinEvent(id=self.id, version=message["event"]))
            self.state = "connected"

class FreecellServer(asyncore.dispatcher):
    def __init__(self, host, port, event_queue, run_signal):
        """
        :param str host: Host
        :param int port: Port
        :param Queue.Queue event_queue: Event Queue
        :param threading.Event run_signal: Run signal
        """
        asyncore.dispatcher.__init__(self)
        self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
        self.set_reuse_addr()
        self.bind((host, port))
        self.listen(1)
        self.event_queue = event_queue
        self.connections = {}
        """:type : dict[(str, int), FreecellCompetitor]"""
        self.running = run_signal

    def run(self):
        self.running.wait()
        while self.running.is_set():
            asyncore.loop(timeout=1, count=1)
            self.update_connections()

        for connection in self.connections.values():
            connection.close_when_done()

    def update_connections(self):
        for addr, connection in self.connections.items():
            if connection.state == "disconnected":
                del self.connections[addr]

    def handle_accept(self):
        pair = self.accept()
        if pair is not None:
            sock, addr = pair
            handler = FreecellCompetitor(sock, addr, self.event_queue)
            self.connections[addr] = handler

if __name__ == "__main__":
    competition_server = CompetitionServer(HOST, PORT)
    competition_server.start()


{'fraction_non_alphanumeric': 0.11046106700097506, 'fraction_numerical': 0.002785903329154478, 'mean_word_length': 2.4905201750121537, 'pattern_counts': {'":': 8, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6915243', 'n_tokens_mistral': 2140, 'n_tokens_neox': 2094, 'n_words': 468}