Skip to content

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
...
  • 1 commit
  • 2 files changed
  • 0 commit comments
  • 1 contributor
Commits on Mar 25, 2012
@grahamking Supporting multiple clients viewing same HTML output. Replaced Proces…
…s with Thread, and Queue with Condition
e0d5b1b
Showing with 62 additions and 29 deletions.
  1. +39 −21 lintswitch/http_server.py
  2. +23 −8 lintswitch/main.py
View
60 lintswitch/http_server.py
@@ -7,7 +7,7 @@
import SocketServer
import SimpleHTTPServer
import logging
-from Queue import Empty
+from threading import Condition
LOG = logging.getLogger(__name__)
IP = 'localhost'
@@ -16,59 +16,75 @@
os.path.sep +
"index.html", "rw").read()
+# Shared memory between threads. HTML of results gets written here
+SHARED_RESULT = None
-def http_server(result_queue, http_port):
+# Condition which tells us when SHARED_RESULT changes
+SHARED_CONDITION = Condition()
+
+
+def http_server(http_port):
"""Start an HTTP server to display emitted HTML files.
"""
- HTTPHandler.queue = result_queue
-
httpd = SockServ((IP, http_port), HTTPHandler)
httpd.serve_forever()
class SockServ(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
- """Threaded TCPServer which set SO_REUSEADDR on socket"""
+ """Threaded TCPServer which sets SO_REUSEADDR on socket"""
allow_reuse_address = True
+ daemon_threads = True
class HTTPHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
"""Pushes files out over HTTP"""
- queue = None
-
def do_GET(self): # pylint: disable=C0103
"""Serve a GET request"""
self.send_response(200)
self.send_header('Cache-Control', 'no-cache')
+ SHARED_CONDITION.acquire()
+
if self.path == '/sse/':
self.send_header('Content-type', 'text/event-stream')
self.end_headers()
- while self._is_connected():
- try:
- html = self.queue.get(timeout=2)
- self.wfile.write('data: %s\n\n' % html.encode('utf8'))
- self.wfile.flush()
- except Empty:
- pass
+ #while self._is_connected():
+
+ while True:
+ if SHARED_RESULT:
+ try:
+ self.wfile.write('data: {}\n\n'\
+ .format(SHARED_RESULT.encode('utf8')))
+ self.wfile.flush()
+ except socket.error:
+ LOG.info("Remote closed socket")
+ break
+
+ LOG.debug("/sse/ HTTPHandler.wait")
+ SHARED_CONDITION.wait(None)
else:
self.send_header('Content-type', 'text/html')
self.end_headers()
- html = self.queue.get()
+ if not SHARED_RESULT:
+ # Wait for someting to display
+ SHARED_CONDITION.wait(None)
container = HTML_PAGE.encode('utf8')
html = container.replace(
'Waiting for results...',
- html.encode('utf8'))
+ SHARED_RESULT.encode('utf8'))
self.wfile.write(html)
self.wfile.close()
+ SHARED_CONDITION.release()
+
def _is_connected(self):
"""Write a comment to the socket to check it's open.
@@ -79,13 +95,15 @@ def _is_connected(self):
try:
self.wfile.write(':PING\n\n')
self.wfile.flush()
+ LOG.debug("Still connected")
return True
except socket.error:
- try:
- self.wfile.close()
- except socket.error:
- pass
- raise socket.timeout()
+ #try:
+ # self.wfile.close()
+ #except socket.error:
+ # pass
+ LOG.debug("Not connected")
+ return False
def log_message(self, logformat, *args):
"""Override default output to use logging module"""
View
31 lintswitch/main.py
@@ -8,7 +8,13 @@
import os
import os.path
import argparse
-from multiprocessing import Queue, Process
+from threading import Thread
+try:
+ # python 3
+ from queue import Queue
+except ImportError:
+ # python 2
+ from Queue import Queue
from lintswitch import checkers, emitters, http_server
@@ -35,14 +41,15 @@ def main():
LOG.debug('lintswitch start')
work_queue = Queue()
- result_queue = Queue()
- check_proc = Process(target=worker,
- args=(work_queue, result_queue, args))
+ check_proc = Thread(target=worker,
+ args=(work_queue, args))
+ check_proc.daemon = True
check_proc.start()
- server = Process(target=http_server.http_server,
- args=(result_queue, args.httpport))
+ server = Thread(target=http_server.http_server,
+ args=(args.httpport,))
+ server.daemon = True
server.start()
# Listen for connections from vim (or other) plugin
@@ -110,7 +117,7 @@ def main_loop(listener, work_queue):
work_queue.put(data)
-def worker(work_queue, result_queue, args):
+def worker(work_queue, args):
"""Takes filename from queue, checks them and displays (emit) result.
"""
@@ -127,7 +134,15 @@ def worker(work_queue, result_queue, args):
errors, warnings, summaries = check_result
html = emitters.emit(filename, errors, warnings, summaries)
- result_queue.put(html)
+ LOG.debug("Acquire")
+ http_server.SHARED_CONDITION.acquire()
+
+ http_server.SHARED_RESULT = html
+
+ LOG.debug("notifyAll")
+ http_server.SHARED_CONDITION.notifyAll()
+ LOG.debug("release")
+ http_server.SHARED_CONDITION.release()
def find(name):

No commit comments for this range

Something went wrong with that request. Please try again.