2015-02-03 4 views
1

С Python 2.7 я расширил BaseHTTPServer.BaseHTTPRequestHandler для поддержки метода do_POST. Я хотел бы предоставить обработчику запросов очередь, чтобы он мог помещать опубликованные данные в очередь для обработки другим потоком.Как разместить очередь в Python 2 BaseHTTPRequestHandler?

Вот урезанная версия моего класса:

import BaseHTTPServer 
import json 

class PostHTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): 

    def do_POST(self): 
     self.send_response(200) 
     self.end_headers() 

     length = int(self.headers['Content-Length']) 
     self.post_data = self.rfile.read(length) 

     try: 
      if self.headers['Content-Type'] == 'application/json': 
       self.post_data = json.loads(self.post_data) 
       self.log_message(json.dumps(self.post_data)) 

       ### WANT TO PUT self.post_data ON A QUEUE HERE ### 

     except KeyError as error: 
      self.log_message('No Content-Type header') 
     except ValueError as error: 
      self.log_message("%s" % error) 

С тех пор обработчик получает созданный BaseHTTPServer, я не думаю, что может изменить INIT метод для передачи в очереди.

Я хотел бы мой основной(), чтобы выглядеть следующим образом:

def main(): 

    import logging 
    import Queue 
    import signal 
    import threading 
    import traceback 


    try: 
     # set stoprequest to accept Ctrl+c 
     stoprequest = threading.Event() 
     signal.signal(signal.SIGINT, lambda signal, frame: stoprequest.set()) 

     args = _get_main_args() 

     ### HERE IS THE QUEUE, HOW TO I GIVE A REFERENCE TO THE HANDLER??? ### 
     data_queue = Queue.Queue() 

     handler = PostHTTPRequestHandler 

     server = BaseHTTPServer.HTTPServer((args.address, args.port), handler) 

     server_thread = threading.Thread(target=server.serve_forever) 
     server_thread.daemon = True 
     server_thread.start() 

     while not stoprequest.is_set(): 

      try: 
       data = data_queue.get(False) 

       ### I WANT TO PROCESS THE DATA HERE ### 

      except Queue.Empty: 
       pass 

     server.shutdown() 

     #logging.debug("Exiting with return code 0") 
     return 0 

    except Exception: 
     sys.stderr.write("%s" % traceback.format_exc()) 
     return 1 

ответ

0

теперь я вижу, что для инициализации BaseRequestHandler выглядит следующим образом:

class BaseRequestHandler: 

    def __init__(self, request, client_address, server): 
     self.request = request 
     self.client_address = client_address 
     self.server = server 
     self.setup() 
     try: 
      self.handle() 
     finally: 
      self.finish() 

Так что продлит BaseHTTPServer, чтобы содержать очередь, тогда он будет доступен для обработчика.

class QueuingHTTPServer(BaseHTTPServer.HTTPServer): 

    def __init__(self, server_address, RequestHandlerClass, bind_and_activate=True): 
     BaseHTTPServer.HTTPServer.__init__(self, server_address, RequestHandlerClass, bind_and_activate) 
     self.data_queue = Queue.Queue() 

Так что теперь обработчик выглядит следующим образом:

class PostHTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): 

    def do_POST(self): 
     self.send_response(200) 
     self.end_headers() 

     length = int(self.headers['Content-Length']) 
     self.post_data = self.rfile.read(length) 

     try: 
      if self.headers['Content-Type'] == 'application/json': 
       self.post_data = json.loads(self.post_data) 
       self.log_message(json.dumps(self.post_data)) 

       try: 
        self.server.data_queue.put(self.post_data) 
       except Queue.Full: 
        pass 

     except KeyError as error: 
      self.log_message('No Content-Type header') 
     except ValueError as error: 
      self.log_message("%s" % error) 
0

Я изменил код, представленный Джош использовать ссылку на общие очереди вместо создания одного во время создания экземпляра.

class QueuingHTTPServer(BaseHTTPServer.HTTPServer): 

    def __init__(self, server_address, RequestHandlerClass, data_queue, bind_and_activate=True): 
     BaseHTTPServer.HTTPServer.__init__(self, server_address, RequestHandlerClass, bind_and_activate) 
     self.data_queue = queue 
Смежные вопросы