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アプリケーションとフレームワークは、使用を回避できる場合は、呼び出し可能オブジェクトを使用しないでください。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 に答える