【问题标题】:How to put queue in a Python 2 BaseHTTPRequestHandler?如何将队列放入 Python 2 BaseHTTPRequestHandler?
【发布时间】:2015-02-03 20:42:02
【问题描述】:

在 Python 2.7 中,我扩展了 BaseHTTPServer.BaseHTTPRequestHandler 以支持 do_POST 方法。我想给请求处理程序一个队列,以便它可以将发布的数据放在队列中以由另一个线程处理。

这是我班级的精简版:

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 方法以传入队列。

我希望我的 main() 看起来像这样:

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

【问题讨论】:

    标签: python basehttpserver basehttprequesthandler


    【解决方案1】:

    我现在看到 BaseRequestHandler 的 init 如下所示:

    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)
    

    【讨论】:

      【解决方案2】:

      我修改了 Josh 提交的代码以使用共享队列引用,而不是在实例化期间创建一个。

      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
      

      【讨论】:

        猜你喜欢
        • 2017-04-30
        • 1970-01-01
        • 2018-08-12
        • 1970-01-01
        • 1970-01-01
        • 2012-03-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多