0

I am trying to create multi threaded web server in python, but the requests are handled one by one. After searching few hours, I found this link but the approved answer seems to be incorrect as the request over there is also handled one by one. Here is the code:

from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
from SocketServer import ThreadingMixIn
import threading
from time import sleep

class Handler(BaseHTTPRequestHandler):

def do_GET(self):
    self.send_response(200)
    self.end_headers()
    sleep(5)
    message =  threading.currentThread().getName()
    self.wfile.write(message)
    self.wfile.write('\n')
    return

class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
    """Handle requests in a separate thread."""

if __name__ == '__main__':
    server = ThreadedHTTPServer(('localhost', 8080), Handler)
    print 'Starting server, use <Ctrl-C> to stop'
    server.serve_forever()

I added "sleep(5)" for 5 second delay to handle the request. After that I send multiple requests but all the requests are handled one by one and each request took 5 seconds. I am unable to find the reason. Help me.

Aman Sinha
  • 11
  • 1
  • 4
  • 1
    Why are you writing a web server yourself? There are plenty already. Use gunicorn or uwsgi. – Daniel Roseman Aug 20 '17 at 18:13
  • Your observations are incorrect. The code as shown above (when you fix the indentation!) works as intended; it is able to start serving a GET request in a new thread while the other(s) are still being processed. I don't know how you reached the conclusion that it doesn't work. – Irmen de Jong Aug 20 '17 at 21:55
  • @IrmendeJong Sir, there is no issue with indentation. The test I conducted gives me result one after other. You can try the above code. – Aman Sinha Aug 21 '17 at 07:00
  • I did, and it works fine. I suggest you look at https://docs.python.org/3.7/library/socketserver.html#asynchronous-mixins – Irmen de Jong Aug 21 '17 at 11:39
  • and yes, you have an indendtation error in your code: the "def" should be indented to be part of the class – Irmen de Jong Aug 21 '17 at 21:50
  • @Daniel -- Kunal wants a 5-second delay between the `send_response` and the message. That's streaming. gunicorn doesn't do that. See my answer below. – personal_cloud Sep 14 '17 at 06:59

1 Answers1

1

The key requirement here is to be able to have a 5-second delay between the send_response and the data returned. That means you need streaming; you can't use ThreadingMixIn, gunicorn, or any other such hack.

You need something like this:

import time, socket, threading

sock = socket.socket (socket.AF_INET, socket.SOCK_STREAM)
host = socket.gethostname()
port = 8000

sock.bind((host, port))
sock.listen(1)

HTTP = "HTTP/1.1 200 OK\nContent-Type: text/html; charset=UTF-8\n\n"

class Listener(threading.Thread):

    def __init__(self):
        threading.Thread.__init__(self)
        self.daemon = True # stop Python from biting ctrl-C
        self.start()

    def run(self):
        conn, addr = sock.accept()
        conn.send(HTTP)

        # serve up an infinite stream
        i = 0
        while True:
            conn.send("%i " % i)
            time.sleep(0.1)
            i += 1

[Listener() for i in range(100)]
time.sleep(9e9)
personal_cloud
  • 3,943
  • 3
  • 28
  • 38