Передача данных в mod_wsgi - PullRequest
       14

Передача данных в mod_wsgi

0 голосов
/ 02 июня 2009

В mod_wsgi я отправляю заголовки, выполняя функцию start_response (), но все содержимое страницы передается по yield / return. Есть ли способ передать содержимое страницы таким же образом, как start_response ()? Использование оператора return.yield очень ограниченно для работы с кусочными данными.

* 1003 Е.Г. *

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 байт).

Ответы [ 3 ]

2 голосов
/ 02 июня 2009

Нет; Но я не думаю, что это ограничительно. Может быть, вы хотите вставить пример кода, где вы описываете свои ограничения, и мы можем помочь.

Для работы с данными чанка вы просто 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'
1 голос
/ 25 июня 2009

Если вы не хотите изменять свое приложение WSGI для частичной буферизации данных ответа перед его отправкой, то внедрите промежуточное программное обеспечение WSGI, которое упаковывает ваше приложение WSGI и которое выполняет эту задачу.

1 голос
/ 02 июня 2009

Для вашего приложения возможно"отправить" данные на сервер 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

...