0

在 mod_wsgi 中,我通过运行函数 start_response() 发送标题,但所有页面内容都通过 yield/return 传递。有没有办法以类似于 start_response() 的方式传递页面内容?在处理分块数据时,使用 return.yield 语句非常严格。

例如

def Application():

    b = buffer()

    [... page code ...]

    while True:
        out = b.flush()    
        if out:
            yield out

class buffer:

    def __init__(self):        
        b = ['']
        l = 0

    def add(self, s):
        s = str(s)
        l += len(s)
        b.append(s)

    def flush(self):

        if self.l > 1000:
            out = ''.join(b)
            self.__init__()
            return out

我希望缓冲区在页面加载时输出内容,但仅在内容堆积到一定程度后才输出内容(例如,1000 字节)。

4

3 回答 3

2

不; 但我不认为这是限制性的。也许您想粘贴一个示例代码来描述您的限制,我们可以提供帮助。

要使用块数据,您只需yield使用块:

def application(environ, start_response):
    start_response('200 OK', [('Content-type', 'text/plain')]
    yield 'Chunk 1\n'    
    yield 'Chunk 2\n'    
    yield 'Chunk 3\n'
    for chunk in chunk_data_generator():
        yield chunk

def chunk_data_generator()
    yield 'Chunk 4\n'
    yield 'Chunk 5\n'

编辑:根据您给出的评论,在发送前将数据堆积到一定长度的示例:

BUFFER_SIZE = 10 # 10 bytes for testing. Use something bigger
def application(environ, start_response):
    start_response('200 OK', [('Content-type', 'text/plain')]
    buffer = []
    size = 0
    for chunk in chunk_generator():
        buffer.append(chunk)
        size += len(chunk)
        if size > BUFFER_SIZE:
            for buf in buffer:
                yield buf
            buffer = []
            size = 0

def chunk_data_generator()
    yield 'Chunk 1\n'    
    yield 'Chunk 2\n'    
    yield 'Chunk 3\n'
    yield 'Chunk 4\n'
    yield 'Chunk 5\n'
于 2009-06-02T17:31:52.433 回答
1

您的应用程序可以将数据“推送”到 WSGI 服务器:

一些现有的应用程序框架 API 以不同于 WSGI 的方式支持无缓冲输出。具体来说,它们提供“写入”函数或某种方法来写入无缓冲的数据块,或者它们提供缓冲的“写入”函数和“刷新”机制来刷新缓冲区。

不幸的是,除非使用线程或其他特殊机制,否则此类 API 无法根据 WSGI 的“可迭代”应用程序返回值来实现。

因此,为了允许这些框架继续使用命令式 API,WSGI 包含一个特殊write()的可调用对象,由可调用对象返回start_response

如果可以避免的话,新的 WSGI 应用程序和框架不应该使用callable。write()

http://www.python.org/dev/peps/pep-0333/#the-write-callable

但不建议这样做。

一般来说,应用程序将通过缓冲其(中等大小的)输出并一次发送所有输出来实现最佳吞吐量。这是现有框架(如 Zope)中的一种常见方法:输出缓冲在 StringIO 或类似对象中,然后与响应标头一起一次性传输。

WSGI 中的相应方法是让应用程序简单地返回一个包含作为单个字符串的响应主体的单元素可迭代(例如列表)。这是绝大多数应用程序功能的推荐方法,这些功能可以呈现文本很容易放入内存的 HTML 页面。

http://www.python.org/dev/peps/pep-0333/#buffering-and-streaming

于 2009-06-02T18:19:46.990 回答
1

如果您不想将 WSGI 应用程序本身更改为在发送响应数据之前对其进行部分缓冲,那么请实现一个 WSGI 中间件来包装您的 WSGI 应用程序并执行该任务。

于 2009-06-25T00:13:09.477 回答